This is for a small game project with SDL on MinGW/Windows.
I am working on a physics engine, and my idea was to have a Physics::Object, which all physical objects should derive from and it registers itself with a global Physics::System class (it's a monostate pattern) so that the user doesn't need to track which objects are included in physics calculations and just needs to call a function like Physics::System::PerformTimestepCalculation(double dt).
This works fine, and I even implemented it using a single derived class Physics::Circle, which is a 2d circle. I was pretty happy with the predictive collision detection, even though I still need to optimise it.
Anyway, I ran into trouble when I started adding other primitives to include in the calculation, e.g. line. The Physics::System::PerformTimestepCalculation(double dt) became littered with calls to Object::GetID() or similar functions (may way to avoid dynamic_cast<>), but I feel dirty.
I did a bit of reading and realised that my the elements of my hierarchy are not substitutable (i.e. the collision between two circles is very different between the collision of two lines).
I like the way my Physics::Objects "self register" with the System class so they automatically get included in the calculations, and I don't really want to lose this.
There must be some other sensible design paths. How can I better redesign things so non-substitutable objects do not get in the way?
Edit FYI:
In the end I have broken away entity and shape properties, similar to how it was described in the accepted answer, and similar to an entity-component-system model. It means I still have the yuk logic of "is this a circle or a line, and is that a line or a circle?", but I'm no longer pretending that polymorphism helps me here. It also means I use some sort of factory and can have multiple calculation worlds happening at once!
The most successful publically available physics engines are not very heavy on the 'patterns' or 'object oriented design'.
Here's a rundown to back up my, admittedly bold, assertion:
Chipmunk - written in C, enough said.
Box2d - Written in C++, and there is some polymorphism here. there's a hierarchy of shapes (base class b2Shape) with a few virtual function. That abstraction leaks like a sieve, though, and you'll find lots of casts to leaf classes throughout the source code. There's also a hierarchy of 'contacts', which proves more successful, although with a single virtual function it would be trivial to rewrite this without polymorphism (chipmunk uses a function pointer, I believe). b2Body is the class used to represent rigid bodies, and it is non-virtual.
Bullet - Written in C++, used in a ton of games. Tons of features, tons of code (relative to the other two). There's actually a base class that the rigid body and soft body representations extend, but only a small part of the code can make any use of it. Most of the base class's virtual function relate to serialization (save/load of the engine state), of the two remaining virtual functions soft body fails to implement one with a TODO informing us that some hack needs to be cleaned up. Not exactly a ringing endorsement of polymorphism in physics engines.
That's a lot of words, and I haven't even really started answering your question. All I want to hammer home is that polymorphism is not something that is applied effectively in existing physics engines. And that's probably not because the authors didn't "get" OO.
So anyway, my advice: ditch polymorphism for your entity class. You're not going to end up with 100 different types that you can't possibly refactor at a later date, your physics engine's shape data will be fairly homogeneous (convex polys, boxes, spheres, etc) and your entity data will likely be even more homogeneous (probably just rigid bodies to start with).
Another mistake that I feel you're making is only supporting one Physics::System. There is utility in being able to simulate bodies independently of eachother (for instance, for a two player game), and the easiest way to do this is to support multiple Physics::Systems.
With that in mind, the cleanest 'pattern' to follow would be a factory pattern. When users want to create a rigid body, they need to tell the Physics::System (acting as a factory) to do it for them, so in your Physics::System:
// returning a smart pointer would not be unreasonable, but I'm returning a raw pointer for simplicity:
rigid_body_t* AddBody( body_params_t const& body_params );
And in the client code:
circle_params_t circle(1.f /*radius*/);
body_params_t b( 1.f /*mass*/, &circle /*shape params*/, xform /*system transform*/ );
rigid_body_t* body = physics_system.AddBody( b );
Anyhoo, kind of a rant. Hope this is helpful. At the very least I want to point you towards box2d. It's written in a pretty simple dialect of C++ and the patterns applied therein will be relevant to your engine, whether it's 3D or 2D.
The problem of hierarchies is that they don't always make sense, and trying to cram everything into a hierarchy just results in awkward decisions and frustrating work down the line.
The other solution that can be used is the tagged union one, best embodied by boost::variant.
The idea is to create an object that can hold one instance of a given type (among a preselected list) at any given time:
typedef boost::variant<Ellipsis, Polygon, Blob> Shape;
And then you can provide the functionality by switching over the type list:
struct AreaComputer: boost::static_visitor<double> {
template <typename T>
double operator()(T const& e) { return area(a); }
};
void area(Shape const& s) {
AreaComputer ac;
return boost::apply_visitor(s, ac);
}
The performance is the same as a virtual dispatch (so not too much, normally), but you get greater flexibility:
void func(boost::variant<Ellipsis, Blob> const& eb);
void bar(boost::variant<Ellipsis, Polygon> const& ep);
// ...
You can provide functions only when relevant.
And on the subject of binary visitation:
struct CollisionComputer: boost::static_visitor<CollisionResult> {
CollisionResult operator()(Circle const& left, Circle const& right);
CollisionResult operator()(Line const& left, Line const& right);
CollisionResult operator()(Circle const& left, Line const& right);
CollisionResult operator()(Line const& left, Circle const& right);
};
CollisionResult collide(Shape const& left, Shape const& right) {
return boost::apply_visitor(CollisionComputer(), left, right);
}
Related
In code I have been writing recently I have been forced to directly access a member of an object to call its functions, however, it feels wrong to do this because it would seem to violate encapsulation and the Law of Demeter. Yet the only good alternative I can come up with is to write my own function in the class for every single function of that member I may want to call, which would be very tedious and redundant. Example:
class Object
{
public:
void setNum(int x)
{
num = x;
}
private:
int num;
};
class Object2
{
public:
Object obj;
};
int main()
{
Object2 obj2;
obj2.obj.setNum(5);
}
vs
class Object
{
public:
void setNum(int x)
{
num = x;
}
private:
int num;
};
class Object2
{
public:
void setNum(int x)
{
obj.setNum(x);
}
private:
Object obj;
};
int main()
{
Object2 obj2;
obj2.setNum(5);
}
The call to setNum in Object2 is forwarded to the same function in Object. Is such a design considered bad practice? Is accessing obj directly be any better?
I could also have Object2 inherit from Object, but in this case the class I would be inheriting from is not designed to be a base class, would expose protected members to Object2, and seems unfitting to begin with because it is not an is-a relationship and composition would be preferred.
My specific situation: I am making a game using SFML, there is a class Ship that of course needs a sprite to represent it in the world. Anytime I want to set or get the ship's position, rotation, etc. I have to either directly access its sprite or write a redundant forwarding function in Ship. The issue is that doing either one of those things seems like a code smell: either violate encapsulation and the Law of Demeter, or write redundant code.
What would be considered best practice here? Am I being overly picky about writing simple forwarding functions? Or is there really nothing wrong with directly accessing the sprite of Ship in this case?
This question: C++ Forward method calls to embed object without inheritance in fact is exactly what I'm asking, however, neither answer gives a good solution. One not being condoned and apparently having very poor encapsulation, the other simply using a getter which seems to be a placebo if anything, and no one addresses the main question I have, which is what is the most elegant and acceptable solution?
What solution is the best highly depends on underlying semantics of encapsulation. You need to decouple your code as much as possible. I'll describe that on examples:
You have a Ship class and it has a Sprite. You may want to separate game logic and rendering. So all that Ships knows about the rendering is that it has a Sprite object which handles it. So in this case you are separating responsibilities and that's good. So simple getter is a good solution.
But if absolute coordinates and rotation must be stored in a sprite, then things change: game logic usually needs them two, so they must be set consistently both inside a Ship and a Sprite. The best way to achieve that is to make Ship's setPosition and setRotation methods to set Sprites position and rotation too. That way you simplify the code which works with the Ship at expense of Ship complexity. Given that Ship is manipulated from several places, that's worth it. NOTE: You still may want to expose Sprite through a getter for rendering purposes. And you may want to prevent anybody except a Ship to set Sprite position and rotation, if that does not bloat your code too much.
Let's imagine that Ship class is mostly devoted to rendering. In such situation you may want to hide from outer classes that you use sprites for graphics (because if you change rendering engine it will be good if you won't need to rewrite anything except rendering code). And in such situation you will want to proxy all setPosition and setRotation calls to a Sprite through Ship just to hide existence of the Sprite.
In none of this cases inheritance is used because inheritance means that child is a variation of it's ancestor. You can say that BattleShip is a variant of a Ship. But Ship is not a variant of a Sprite, they are too different and mean different things.
So: if encapsulated class is too specific and should not be visible outside or if it must be operated consistently with a master object, then writing a bunch of proxy methods is a good solution. Otherwise these methods will just bloat your code and it's better to provide a way to get nested object. But in that case I vote for a getter method instead of a public property.
Despite of how the classic javanese oop school can think, never forgot that also DRY (Don't Repeat Yourself) is ALSO considered a good practice.
And while OOP is just one of many programming paradigm C++ can support, DRY is the very essence of all programming since the first very assembler got macros, and this is true long before oop inventors was even far away from their own parent's thoughts and wishes.
For all what my unfair experience is... if respecting a good oop practice force you in writing useless boilerplates of repeating code it means either
The language you are using is fundamentally broken for the purpose you want to achieve, not supporting the paradigm correctly or...
OOP is broken for the purpose you are try to reach. And in C++ chances are that OOP is really the broken paradigm.
To come to your specific problem, delegation (that's how that pattern is commonly named) makes sense if:
the way it is delegating can be changed or
the delegation is to hide part of the member interface.
In you case, you have a function that calls a fixed method reachable from fixed member.
Is that only specific to this particular sample or in your implementation will be always that way by design?
If so, delegation adds no semantic value, if not just reducing a.b.m() to a.m(). If you are writing more than ... let's say three "do nothing just forward" functions you are wasting your time.
If b has 50 methods and you are making it private to delegate only 5 of them, than it makes perfectly sense.
I'm developing a base for a 2D game. My general design is something like this:
class Entity:
Every object class (like a wall, an enemy, floor etc.) derives
from this class. Most of the functions are pure virtual. There is
a hitbox as well.
class Scene:
Contains pointers to Entity-objects. When an Entity-pointer is added,
it will be given a Scene-pointer to its parent so it may access that.
Scene also has a collision-detecting function:
getIntersections<T> (Entity *)
getIntersections<T...> (Entity *)
(both return a std::vector<Entity *>)
This basically gets all Entity *s intersecting the parameter-Entity * (by checking the hitbox) and then tries to dynamic_cast<T *> them. All matching Entity *s (not the casted ones) are then returned. The variadic template is used for checking for more then one intersecting class.
My basic idea behind that was, if I had a Player-class (which represents the player obviously), and some other classes like Enemy, Wall, etc., it would be an easy task to check if a Player-object was colliding with one(or more) of these:
// (inside Player::tick(); quick and dirty)
{
if ( (this->parentScene->getIntersections<Wall>(this)).empty() )
// player does not collide with a wall, just move.
else
// player does collide with a wall, do whatever.
}
However, I have got two questions on that:
Does my (general) design show up flaws for the need of dynamic_cast<T *> as replacement for instanceof (like there is in Java for example)
Is it a performant solution on the task? Since for every collision check, Scene basically loops through every Entity * it contains, checks if it collides with the given Entity * and finally casts it to check if it derives from another given class. If that is not performant, what changes were to make in my design to make it performant?
On the performance part it would be better to separate entities in separate vectors by primitive type. Not only you can specifically test a plane vs a sphere for example it eliminates the need to have dynamic_cast entirely ( -> extra speedup ). Also since you already separated the types in vectors you can just ignore the virtual functions and go for non virtual call providing additional performance improvement;
So your scene would look something like this:
class scene
{
std::vector<PlaneEntity> m_planes;
std::vector<CircleEntity> m_circles;
};
And regarding the design of this it is much easier to select the right algorithm when intersecting primities:
This is an example on how a basic collision checking would look based on this design:
void colide(const PlaneEntity & e)
{
for each plane
call plane vs plane collision
for each circle
call plane vs circle collision;
};
void colide(const CircleEntity & e)
{
for each plane
call plane vs circle collision;
for each circle
call circle vs circle collision;
};
So to answer your question:
1: it is not a rule weather to use or not dynamic_cast, it is known that not using it is better for performance.
2: The design described above is not performant at all. Also your design with dynamic cast is even slower. To improve this you need to look into accelerations structures (this is huge topic so i can't explaing everything here) to speed up collision detection. They basically reduce the number of collision check for each primitive giving a massive improvement in performance. Basic structures are KD-Tree, Quad-Trees, Spacial-Hash , Grid, etc. You can find lots of code for each just by googleing them.
Hope this helps,
Raxvan.
Basically I have a base class called Geometry, and some derivative such as Point, Polygon, etc...
Geometry implements a method intersection like this :
Geometry* intersection(Geometry* other)
{
Geometry* inter = compute_intersection(this, other);
if (inter is a polygon)
return new Polygon(inter);
if (inter is a point)
return new Point(inter);
}
When I compute the intersection of two geometries in my program, I obtain a Geometry* and I can dynamic_cast it to whatever it really is.
Is it a good design ? What, I think, might be wrong is that I have to check real type each time I compute an intersection and dynamic_cast the result (which can be slow). But what I think is the main problem is that with this design, Geometry must know its derivative (Point, Polyline? etc...).
What could be a good solution to avoid these problems ?
Why do you need to construct a new object of the returned object, can't you jsut return it straight away? If you can not, just implement one additional method in each derivative class that wraps the result from compute_intersection in a new object and call this new method instead of compute_intersection in Geometry.
In my answer I assume the only possible situation: compute_intersection is abstract and each deriving class implements it.
If you find yourself needing to new according to inherited type to copy objects, then you can use virtual copy constructors, by implementing a clone() function that returns a copy of the object:
virtual Obj* Obj::clone() const { return new Obj(*this); }
This can be called from your intersection() function.
There are two issues here as far as I'm concerned.
Firstly, I don't care much for functions which get/set things. I'm more interested in telling objects to do something for me.
Secondly, you are trying to implement multiple dispatch (in this case double dispatch). This is where the behaviour you want depends upon the types of multiple objects.
My normal mantra of encapsulate, encapsulate, encapsulate guides me towards the following ideas:
Encapsulate what you want to do with the intersection e.g.
Put its area into a spreadsheet cell
Add geometry points to a display list
Encapsulate the dispatch of one type given another type
Look into the visitor pattern
Encapsulate applying the behaviour to an intersection
Perhaps you can use boost::variant:
typedef boost::variant<Point, Polygon/*, and other...*/> Geometry_Variants;
Geometry_Variants intersection(Geometry_Variants const& other)
{
// compute the intersection and return Point or Polygon
}
Your problem is known under the name: multiple dispatch or multi methods. There is no real good answer to this problem in C++ as far as I know. A good discussion of this problem by Andrei Alexandrescu is here:
http://books.google.fr/books?id=aJ1av7UFBPwC&pg=PA263&lpg=PA295&dq=modern+c%2B%2B+design+multiple+dispatch&source=bl&ots=YRdIZrWiaV&sig=2Vj0Blst_jmhMCAZIJ8gUiG_pl4&hl=fr&sa=X&ei=082XT86RHNS18QPW7f3mBQ&ved=0CCYQ6AEwAA#v=onepage&q&f=false
I recommend you to buy the book it's worth its price.
I have a chess variants engine that plays suicide chess and losers chess along with normal chess. I might, over time, add more variants to my engine. The engine is implemented completely in C++ with proper usage of OOP. My question is related to design of such a variant engine.
Initially the project started as a suicide-only engine while over time I added other flavors. For adding new variants, I experimented using polymorphism in C++ first. For instance, a MoveGenerator abstract class had two subclasses SuicideMoveGenerator and NormalMoveGenerator and depending on the type of game chosen by user, a factory would instantiate the right subclass. But I found this to be much slower - obviously because instantiating classes containing virtual functions and calling virtual functions in tight loops are both quite inefficient.
But then it occurred to me to use C++ templates with template specialization for separating logic for different variants with maximum reuse of code. This also seemed very logical because dynamic linking is not really necessary in the context as once you choose the type of game, you basically stick with it until the end of the game. C++ template specialization provides exactly this - static polymorphism. The template parameter is either SUICIDE or LOSERS or NORMAL.
enum GameType { LOSERS, NORMAL, SUICIDE };
So once user selects a game type, appropriate game object is instantiated and everything called from there will be appropriately templatized. For instance if user selects suicide chess, lets say:
ComputerPlayer<SUICIDE>
object is instantiated and that instantiation basically is linked to the whole control flow statically. Functions in ComputerPlayer<SUICIDE> would work with MoveGenerator<SUICIDE>, Board<SUICIDE> and so on while corresponding NORMAL one will appropriately work.
On a whole, this lets me instantiate the right templatize specialized class at the beginning and without any other if conditions anywhere, the whole thing works perfectly. The best thing is there is no performance penalty at all!
The main downside with this approach however is that using templates makes your code a bit harder to read. Also template specialization if not appropriately handled can lead to major bugs.
I wonder what do other variant engine authors normally do for separation of logic (with good reuse of code)?? I found C++ template programming quite suitable but if there's anything better out there, I would be glad to embrace. In particular, I checked Fairymax engine by Dr. H G Muller but that uses config files for defining game rules. I don't want to do that because many of my variants have different extensions and by making it generic to the level of config-files the engine might not grow strong. Another popular engine Sjeng is littered with if conditions everywhere and I personally feel thats not a good design.
Any new design insights would be very useful.
"Calling virtual functions in tight loops are inefficient"
I would be pretty surprised actually if this caused any real bloat, if all the variables of the loop have the same dynamic type, then I would expect the compiler to fetch the corresponding instruction from its L1 cache and thus not suffer much.
However there is one part that worries me:
"obviously because instantiating classes containing virtual functions [is] quite inefficient"
Now... I am really surprised.
The cost of instantiating a class with virtual functions is near undistinguishable from the cost of instantiating a class without any virtual functions: it's one more pointer, and that's all (on popular compilers, which corresponds to the _vptr).
I surmise that your problem lies elsewhere. So I am going to take a wild guess:
do you, by any chance, have a lot of dynamic instantiation going on ? (calling new)
If that is the case, you would gain much by removing them.
There is a Design Pattern called Strategy which would be eminently suitable for your precise situation. The idea of this pattern is akin, in fact, to the use of virtual functions, but it actually externalize those functions.
Here is a simple example:
class StrategyInterface
{
public:
Move GenerateMove(Player const& player) const;
private:
virtual Move GenerateMoveImpl(Player const& player) const = 0;
};
class SuicideChessStrategy: public StrategyInterface
{
virtual Move GenerateMoveImpl(Player const& player) const = 0;
};
// Others
Once implemented, you need a function to get the right strategy:
StrategyInterface& GetStrategy(GameType gt)
{
static std::array<StrategyInterface*,3> strategies
= { new SuicideChessStrategy(), .... };
return *(strategies[gt]);
}
And finally, you can delegate the work without using inheritance for the other structures:
class Player
{
public:
Move GenerateMove() const { return GetStrategy(gt).GenerateMove(*this); }
private:
GameType gt;
};
The cost is pretty much similar to using virtual functions, however you do not need dynamically allocated memory for the basic objects of your game any longer, and stack allocation is a LOT faster.
I'm not quite sure if this is a fit but you may be able to achieve static polymorphism via the CRTP with some slight modifications to your original design.
I've got a game engine where I'm splitting off the physics simulation from the game object functionality. So I've got a pure virtual class for a physical body
class Body
from which I'll be deriving various implementations of a physics simulation. My game object class then looks like
class GameObject {
public:
// ...
private:
Body *m_pBody;
};
and I can plug in whatever implementation I need for that particular game. But I may need access to all of the Body functions when I've only got a GameObject. So I've found myself writing tons of things like
Vector GameObject::GetPosition() const { return m_pBody->GetPosition(); }
I'm tempted to scratch all of them and just do stuff like
pObject->GetBody()->GetPosition();
but this seems wrong (i.e. violates the Law of Demeter). Plus, it simply pushes the verbosity from the implementation to the usage. So I'm looking for a different way of doing this.
The idea of the law of Demeter is that your GameObject isn't supposed to have functions like GetPosition(). Instead it's supposed to have MoveForward(int) or TurnLeft() functions that may call GetPosition() (along with other functions) internally. Essentially they translate one interface into another.
If your logic requires a GetPosition() function, then it makes sense turn that into an interface a la Ates Goral. Otherwise you'll need to rethink why you're grabbing so deeply into an object to call methods on its subobjects.
One approach you could take is to split the Body interface into multiple interfaces, each with a different purpose and give GameObject ownership of only the interfaces that it would have to expose.
class Positionable;
class Movable;
class Collidable;
//etc.
The concrete Body implementations would probably implement all interfaces but a GameObject that only needs to expose its position would only reference (through dependency injection) a Positionable interface:
class BodyA : public Positionable, Movable, Collidable {
// ...
};
class GameObjectA {
private:
Positionable *m_p;
public:
GameObjectA(Positionable *p) { m_p = p; }
Positionable *getPosition() { return m_p; }
};
BodyA bodyA;
GameObjectA objA(&bodyA);
objA->getPosition()->getX();
Game hierarchies should not involve a lot of inheritance. I can't point you to any web pages, but that is the feeling I've gather from the several sources, most notably the game gem series.
You can have hierarchies like ship->tie_fighter, ship->x_wing. But not PlaysSound->tie_fighter. Your tie_fighter class should be composed of the objects it needs to represent itself. A physics part, a graphics part, etc. You should provide a minimal interface for interacting with your game objects. Implement as much physics logic in the engine or in the physic piece.
With this approach your game objects become collections of more basic game components.
All that said, you will want to be able to set a game objects physical state during game events. So you'll end up with problem you described for setting the various pieces of state. It's just icky but that is best solution I've found so far.
I've recently tried to make higher level state functions, using ideas from Box2D. Have a function SetXForm for setting positions etc. Another for SetDXForm for velocities and angular velocity. These functions take proxy objects as parameters that represent the various parts of the physical state. Using methods like these you could reduce the number of methods you'd need to set state but in the end you'd probably still end up implementing the finer grained ones, and the proxy objects would be more work than you would save by skipping out on a few methods.
So, I didn't help that much. This was more a rebuttal of the previous answer.
In summary, I would recommend you stick with the many method approach. There may not always be a simple one to 1 relationship between game objects and physic objects. We ran into that where it was much simpler to have one game object represent all of the particles from an explosion. If we had given in and just exposed a body pointer, we would not have been able to simplify the problem.
Do I understand correctly that you're separating the physics of something from it's game representation?
i.e, would you see something like this:
class CompanionCube
{
private:
Body* m_pPhysicsBody;
};
?
If so, that smells wrong to me. Technically your 'GameObject' is a physics object, so it should derive from Body.
It sounds like you're planning on swapping physics models around and that's why you're attempting to do it via aggregation, and if that's the case, I'd ask: "Do you plan on swapping physics types at runtime, or compile time?".
If compile time is your answer, I'd derive your game objects from Body, and make Body a typedef to whichever physics body you want to have be the default.
If it's runtime, you'd have to write a 'Body' class that does that switching internally, which might not be a bad idea if your goal is to play around with different physics.
Alternatively, you'll probably find you'll have different 'parent' classes for Body depending on the type of game object (water, rigid body, etc), so you could just make that explicit in your derivation.
Anyhow, I'll stop rambling since this answer is based on a lot of guesswork. ;) Let me know if I'm off base, and I'll delete my answer.