Laurens Posted July 15, 2010 Share Posted July 15, 2010 Hi, I believe I had already asked this question before but I can't find it again for the life of me. Perhaps it went AWOL when the database rolled back. Anyway! I have a callback set on an entity but instead of calling a global or static function I really need it to call a non-static member function. Is this in any way possible? The reason I need it to call a member function is because I otherwise have to either expose some methods publicly which aren't supposed to be public or make the classes involved friends of each other, something else I would rather not do. Thanks! Quote Link to comment Share on other sites More sharing options...
Rick Posted July 15, 2010 Share Posted July 15, 2010 Here is how you can simulate it. Basically you create pure abstract classes to act kind of like interfaces for the different types of callbacks. Then derive the classes you want to have these from that interface. Then you define one normal C function for each callback type and just cast the first entity to that interface type and if it's not null call the virtual method. This isn't tested code, just doing some stuff from memory, but it gives you the general idea. void _stdcall EntityCollisionCallback( TEntity entity0, TEntity entity1, byte* position, byte* normal, byte* force, flt speed ) { Collider* b = (Collider*)GetEntityUserData(entity0); if(b != NULL) { b->OnCollide(entity1, position, normal, force, speed); } } class Collider { public: virtual void OnCollide(TEntity ent, byte* position, byte* normal, byte* force, flt speed)=0; }; class MyBody : public Collider { private: TEntity body; public: MyBody() { body = CreateBodyBox(); SetEntityUserData(body, (byte*)this); SetEntityCallback(body,(byte*)EntityCollisionCallback,ENTITYCALLBACK_COLLISION); } void OnCollide(TEntity ent, byte* position, byte* normal, byte* force, flt speed) { } }; Quote Link to comment Share on other sites More sharing options...
Laurens Posted July 17, 2010 Author Share Posted July 17, 2010 Hi Rick, That is a pretty elegant solution you have there. It's working like a charm Thanks! Quote Link to comment Share on other sites More sharing options...
Rick Posted July 17, 2010 Share Posted July 17, 2010 Thanks, I thought so too. This is how the C++ wrapper should handle these callbacks I think. Quote Link to comment Share on other sites More sharing options...
Laurens Posted July 17, 2010 Author Share Posted July 17, 2010 I agree, although we would need to come up with a new structure that will hold multiple references in the entity user data. In your example, an entity can only store a Collider and not, for instance, a reference to an object that also implements OnEntityMatrixChanged or something. Hope I made myself clear, lol A structure that stores a vector of byte pointers would probably do it. Quote Link to comment Share on other sites More sharing options...
Rick Posted July 17, 2010 Share Posted July 17, 2010 Sure it could. Make another interface called MatrixChange that has a pure virtual method for the callback. Then derive your class from that class (you can have multiple inheritance). Then make the C function callback for the matrix changed and do the same thing. That should work for every callback that LE has. One thing you can do is also pass the first entity to the member methods in case you have multiple LE entities inside your class, you can then check which one was collided with or matrix chagned or whatever. With multiple inheritance you can cast the entity to any of the "interfaces" you derived your object from. class MatrixUpdate { public: virtual void OnUpdateMatrix(TEntity ent)=0; }; void _sdtcall MatrixCallback(TEntity ent) { MatrixUpdate* b = (MatrixUpdate*)GetEntityUserData(ent); if(b != NULL) { b->OnUpdateMatrix(ent); } } class MyBody : public Collider, public MatrixUpdate { private: TEntity body; public: MyBody() { body = CreateBodyBox(); SetEntityUserData(body, (byte*)this); SetEntityCallback(body,(byte*)EntityCollisionCallback,ENTITYCALLBACK_COLLISION); SetEntityCallback(body,(byte*)EntityCollisionCallback,ENTITYCALLBACK_UPDATEMATRIX); } virtual void OnCollide(TEntity ent, byte* position, byte* normal, byte* force, flt speed) { } virtual void OnUpdateMatrix(TEntity ent) { } }; Quote Link to comment Share on other sites More sharing options...
Laurens Posted July 17, 2010 Author Share Posted July 17, 2010 Ah of course, multiple inheritance, been in my C# head for the past few days and it shows Quote Link to comment Share on other sites More sharing options...
Rick Posted July 18, 2010 Share Posted July 18, 2010 Well, really we would do the same thing in C#, but just with interfaces since you can have multiple interfaces inherited. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.