Original Post
Hi there! I´ve been developing a simple engine for quite a time now and now I am at the point where it comes inevitable to either hardcode a game or implement a LUA API for the engine, so that I can do most of the game stuff in LUA. So I´ve went along read quite a big part of the LUA documentation, and finally came to the conclusion that using SWIG to build my LUA API would be a good move. However I´ve come to a dead point somehow: I´ve coded 2 simple classes that wrap my base entity class and the class for movables: Entity wrapper: L_Entity.h Movable wrapper: L_Movable.h Additionally I have a simple function that returns a pointer to the Entity with a specific name, which is wrapped in this function: L_StaticFunctions.h Now I´ve created a simple SWIG file like this: So far, so good... after adding some #include's and a using namespace into the create PUKE_wrap.cxx everything compiled fine. Now using L_Entity, L_Movable and the static GetEntity should work. Have a look at the simple LUA-function I created:
class L_Entity
{
public:
L_Entity(){this->m_pEntity = NULL;}
L_Entity(PUKE::Logic::Entity *e){this->m_pEntity = e;}
~L_Entity(){this->m_pEntity = NULL;}
virtual void SetName(char* n)
{
if(this->m_pEntity)
{
this->m_pEntity->SetName(LPCTSTR(n));
}
}
virtual char* GetName()
{
if(this->m_pEntity)
{
return (char*)this->m_pEntity->GetName();
}
return "";
}
virtual void SetPosition(float x, float y, float z)
{
if(this->m_pEntity)
{
this->m_pEntity->SetPosition(x,y,z);
}
}
virtual float GetPositionX()
{
if(this->m_pEntity)
{
return this->m_pEntity->GetPosition().x;
}
return 0.f;
}
virtual float GetPositionY()
{
if(this->m_pEntity)
{
return this->m_pEntity->GetPosition().y;
}
return 0.f;
}
virtual float GetPositionZ()
{
if(this->m_pEntity)
{
return this->m_pEntity->GetPosition().z;
}
return 0.f;
}
virtual void SetState(int newState)
{
if(this->m_pEntity)
{
this->m_pEntity->SetState(newState);
}
}
virtual int GetState()
{
if(this->m_pEntity)
{
return this->m_pEntity->GetState();
}
return -1;
}
virtual void PerformAction(int action)
{
if(this->m_pEntity)
{
this->m_pEntity->GetController()->PerformAction(action);
}
}
protected:
PUKE::Logic::Entity *m_pEntity;
};
class L_Movable : public L_Entity
{
public:
L_Movable() : L_Entity(){}
L_Movable(PUKE::Logic::Movable* m) : L_Entity(m){}
void MoveTo(float x, float y, float z, float speed)
{
if(this->m_pEntity)
{
((PUKE::Logic::Movable*)this->m_pEntity)->MoveTo(x,y,z,speed);
}
}
void MoveToTimed(float x, float y, float z, float time)
{
if(this->m_pEntity)
{
((PUKE::Logic::Movable*)this->m_pEntity)->MoveToTimed(x,y,z,time);
}
}
};
static L_Entity GetEntity(LPCTSTR name)
{
if(PUKE::pCurrentScene)
{
PUKE::Logic::Entity* e = PUKE::pCurrentScene->GetEntityByName(name);
switch(e->GetType())
{
case MOVABLE:
return L_Movable((PUKE::Logic::Movable*)e);
default:
return L_Entity(e);
}
}
return L_Entity();
}
%module PUKE
%include <windows.i>
%include "L_StaticFunctions.h"
%include "L_Entity.h"
%include "L_Movable.h"
function Button1OnPush()
t = PUKE.L_Movable()
t:PerformAction(123)
test = PUKE.L_Entity()
test:PerformAction(8)
door = PUKE.GetEntity("Door01")
door:PerformAction(8)
door = GetEntity("Door02")
door:PerformAction(8)
end
This function works until the line door:PerformAction(8). Notice that t = PUKE.L_Movable() and t:PerformAction(123) works as expected. PUKE.GetEntity(...) seems to work, too. At least the C++-function returns a valid Entity. However door:PerformAction(8) results in the following error: map.lua:17: attempt to index global 'door' (a userdata value) So, all in all my questions are: a) Does anybody have a clue why that error occurs, although L_Movable seems to be available in LUA? b) As the PUKE_wrap.cxx is unreadable, as the comment at its top also states, I would love to read a tutorial on wrapping C++ classes for LUA myself, perhaps that will produce more readable code, although more work, so I´d appreciate using SWIG if I get it to work correctly. Thx for reading and for help and sry for posting that much source, but I think I´ve got everything necessary. If not, feel free to ask.