0

I have exported from C++ into lua such base class:

class IState
{
    public:
        virtual ~IState() { }

        virtual void Init() = 0;
        virtual void Update(float dSeconds) = 0;
        virtual void Shutdown() = 0;
        virtual string Type() const = 0;
};

// Wraper of state base class for lua
struct IStateWrapper : IState, luabind::wrap_base
{
    virtual void Init() { call<void>("Init"); }
    virtual void Update(float dSeconds) { call<void>("Update", dSeconds); }
    virtual void Shutdown() { call<void>("Shutdown"); }
    virtual string Type() const { return call<string>("Type"); }
};

Export code:

        class_<IState, IStateWrapper>("IState")
            .def("Init", &IState::Init)
            .def("Update", &IState::Update)
            .def("Shutdown", &IState::Shutdown)

The next part: I have StateManager with function: void StateManager::Push(IState*) and it's export:

        class_<StateManager>("StateManager")
            .def("Push", &StateManager::Push)

Now, I want to create object of type IState in Lua and push it into StateManager:

-- Create a table for storing object of IState cpp class
MainState = {}

-- Implementatio of IState::Init pure virtual function
function MainState:Init()
    print 'This is Init function'
end

function MainState:Update()
    print 'this is update'
end

function MainState:Shutdown()
    print 'This is shutdown'
end

state = StateManager
state.Push(MainState)

Of course, this won't work. I don't know how to say that MainState if the object of type IState:

error: No matching overload found, candidates: void Push(StateManager&,IState*)

UPD

    module(state, "Scene") [
        class_<StateManager>("StateManager")
            .def("Push", &StateManager::Push),

        class_<IState, IStateWrapper>("IState")
            .def("Init", &IState::Init)
            .def("Update", &IState::Update)
            .def("Shutdown", &IState::Shutdown)
    ];

    globals(state)["StateManager"] = Root::Get().GetState(); // GetState() returns pointer to obj

After example:

class 'MainState' (Scene.IState)
function MainState:__init()
    Scene.IState.__init(self, 'MainState')
end
...
state = StateManager
state:Push(MainState())

error: no static '__init' in class 'IState'

And should state = StateManager has brackets? With them there is error that no such operator.

Max Frai
  • 61,946
  • 78
  • 197
  • 306
  • "And should state = StateManager has brackets?" I don't know; what do you want it to do? Do you want to *create* a `StateManager` object, or do you want to use an already existing one? I can't read your mind; you need to be more clear on what it is you're trying to achieve. – Nicol Bolas Jul 14 '12 at 18:58
  • @NicolBolas `globals(state)["StateManager"] = Root::Get().GetState();` Here I set `StateManager` to some pointer, that's why, I think, I wrote it without brackets – Max Frai Jul 14 '12 at 19:38

1 Answers1

2

You can't just throw a table at Luabind. If you intend to derive from a Luabind-defined class, you have to follow the rules of Luabind. You have to create a Lua class with Luabind's tools, derived from your IState class. That would look like this:

class 'MainState' (IState) --Assuming that you registered IState in the global table and not a Luabind module.

function MainState:__init()
    IState.__init(self, 'MainState')
end

function MainState:Init()
    print 'This is Init function'
end

function MainState:Update()
    print 'this is update'
end

function MainState:Shutdown()
    print 'This is shutdown'
end

state = StateManager()
state:Push(MainState())

Also, take note of the changes to the last two lines. Specifically, how StateManager is called, not simply set into state). Also, how you use state: and not state.. I have no idea how this code even functioned in your example.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982