Cant help but feel this method needs optimization

Started by
1 comment, last by Zouflain 16 years, 8 months ago
Basically I have a class called gameobj, and an array that stores pointers to each gameobj as it's created (it automatically resizes [well, grows, it doesn't shrink even when large numbers of gameobj's are destroyed], and automatically resorts when a new one is added or an old one is destroyed). That part was easy. I then made a function void GameEvent(int event), which runs a set of events, namely (and in this order) EV_BEGIN_STEP//update x,y,z (based on speed or whatever else) EV_STEP//process inputs, run script EV_DRAW//called during the draw step of the program *note: there are others, but they are unimportant So essentially, GameEvent(EV_BEGIN_STEP) is called, which goes through a switch statement (event) that leads to a for loop which calls each and every gameobj's (listed in the aforementioned array) EventBeginStep() function, which again has a switch for the variable ObjectType. That leads it to perform it's given script ("if W is pressed, increase speed by 2," for instance). To make sense out of this, imagine a bullet and a spaceship. Both are gameobj's, but the bullet has ObjectType OBJBULLET and the ship has the ObjectType OBJSHIP. The function call is the same, but they behave differently whenever. GameEvent(EV_BEGIN_STEP)//the bullet and ship both reposition GameEvent(EV_STEP) //the bullet does nothing; it's speed is constant and thus it needs no script. //the ship, however, checks if w is pressed, and if it is, increases it's speed GameEvent(EV_DRAW)//draws the object This process feels inefficient and logically incorrect, but I don't know of a better one. I'm much too used to Mark Overmar's GML, and this was modeled after that. Is this a useful method, or is it too slow? If it is too slow, how can I improve it, or better yet, what should I replace it with?
Advertisement
  1. A first inefficiency in your system would be your usage of a dynamic array, as opposed to using an industry-grade fully optimized one. Look up std::vector or boost::ptr_vector for faster solutions.
  2. Don't use integers to represent alternatives. Use enumerations, they're type-safe, better documented, and get their values automatically.
  3. Don't use enumerations to represent action alternatives in an object-oriented context. Write one member function per action, call them directly, and use your choice of the visitor pattern or member function pointers if you one day happen to actually represent events.
  4. Don't use enumerations to represent object types. These take up memory, are slower than the compiler-enforced alternative. If the behaviour varies based on the type of the object, you should be using dynamic binding (implemented in C++ as virtual function). If the behaviour depends based on the type of several objects, use the visitor pattern to sort it out. Either way, a compiler-friendly will in almost all conceivable situations be faster than a compiler-unfriendly, wheel-reinventing solution such as enumeration-and-switch dynamic behaviour.
  5. Drawing is not a game event. Ideally, you should never draw the objects. Instead, objects should have the possibility to register renderable entities with a rendering system at creation time, improving performance by not traversing the entire list of (potentially not rendered) objects and instead having a tight loop which works on objects which are known to be renderable.
Brutal, but logical, Toohr - you diced my program, exactly what I was looking for. Thanks!
Quote:Original post by ToohrVyk
  1. A first inefficiency in your system would be your usage of a dynamic array, as opposed to using an industry-grade fully optimized one. Look up std::vector or boost::ptr_vector for faster solutions.

Ah. I always thought that a simple dynamic array would be best. I'd heard (and even seen a few implementations) of boost::ptr_vector, but always focused more on what I was doing and less on how they work. I'm going to go back and study, thanks for the advice.
Quote:
  • Don't use integers to represent alternatives.

  • This I had no clue about. I honestly thought integers were the best way.
    Quote:
  • Don't use enumerations to represent action alternatives in an object-oriented context. Write one member function per action, call them directly, and use your choice of the visitor pattern or member function pointers if you one day happen to actually represent events.

  • This makes more sense than I was willing to believe when I built this method. I wanted to cleanly group each function, so as to minimize the ammount and types of calls I would have to make (ie one GameEvent(int event) function as apposed to GameStep(); GameBeginStep();, but I can see easily how this would shave off a bit of computing time.
    Quote:
  • Don't use enumerations to represent object types. These take up memory, are slower than the compiler-enforced alternative. If the behaviour varies based on the type of the object, you should be using dynamic binding (implemented in C++ as virtual function).

  • I was avoiding virtual functions for simplicity, but they aren't that complex. More things to study (just to make sure I get it absolutely right).
    Quote:
  • Drawing is not a game event. Ideally, you should never draw the objects. Instead, objects should have the possibility to register renderable entities with a rendering system at creation time

  • Another slap in the face. This makes so much sense that I can't see why I ignored it before. Sadly this sacrifices the sheer simplicity of just drawing everything, but in game design simplicity camps in the trunk and speed rides shotgun. Still, I'm going to really have to work out a good (fast) method for doing this. I'm sure there are a lot, but before I ask for one I want to at least have something.

    Thank you for dicing my program, I couldn't have asked for a better reply.

    This topic is closed to new replies.

    Advertisement