Jump to content

Member function callback


Laurens
 Share

Recommended Posts

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!

Link to comment
Share on other sites

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)
{
}
};

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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)
       {
       }
};

Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...