luabind::resume_function, lua_newthread, lua class derived from c++ class, creating/calling this lua class from c++

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

luabind::resume_function, lua_newthread, lua class derived from c++ class, creating/calling this lua class from c++

subatomic

Does anyone have a code example of instantiating (from the c++-side) a lua class derived from a c++ class,
then starting a coroutine using one of the lua class's methods?

I'm trying to do this (see code below), and for the most part it is working, but when I refer to self.counter in one of the lua-side class methods, I am getting an error:
   Assertion failed: lua_gettop(L) == top - m_params + 1, file call_function.hpp, line 264
where top is 2, and lua_gettop is 1...
(crash happens in luabind::resume_function)

The docs seem to be sparse for specific examples of the case I listed in the opening line of this email...
I'd love to see an example in the examples dir (or in the docs)  for this specific case. :-)

I suspect that my code is missing some subtle detail to get the class onto the stack for the script to see self inside of members...  or maybe is pushing too many things onto the stack...

To explain my implementation:

Below, you'll see on the lua-side, MyClass:__init (where referring to self works correctly)
and MyClass: __call, (where referring to self does not work)...
In short, I am doing luabind::call_function to instantiate a new instance of the lua-class-derived-from-c++-class, which also happens to call MyClass:__init on the lua-side...
Then, I'm getting __call from the new class object (as returned by luabind::call_function) and running luabind::resume_function on __call.


here's my c++ class, and bindings:

class Actor
{
public:
      private:
      /// ScriptSystem needs private access to Entity to manipulate the script
      /// state.
      friend class ScriptSystem;

      /// Entities are noncopyable. Don't copy them.
      Actor( const Actor& actor );
      Actor& operator=( const Actor& actor );

   public:
      Actor()
      {
         counter = 1;
         std::cout << "[C++Actor] constructor" << std::endl;
      }
      ~Actor()
      {
         counter = 2;
         std::cout << "[C++Actor] destructor" << std::endl;
      }
      virtual void __call()
      {
         counter = 3;
         std::cout << "[C++Actor] call" << std::endl;
      }    

      char counter;
};
struct Actor_wrap : Actor, luabind::wrap_base
{
   virtual void __call()
   {
      std::cout << "[C++Wrapper] __call" << std::endl;
      call<void>("__call");
   }
   static void default_call( Actor* ptr )
   {
      std::cout << "[C++Wrapper] default_call" << std::endl;
      return ptr->Actor::__call();
   }
};
static void bind_actor(lua_State* L)
{
   using namespace luabind;
   module(L)
   [
      class_<Actor, Actor_wrap >("Actor")
         .def(constructor<>())
         .def_readwrite("counter", &Actor::counter)
         .def("__call", &Actor::__call, &Actor_wrap::default_call)
   ];
}






///// Here's my lua class:////////



class 'MyClass' (Actor)

io.write("[luaMyClass] outside of the class, global scope\n")

function MyClass:__init( args )
    super()
    io.write("[luaMyClass] init is called from ",_VERSION,"!\n")
    io.write("[luaMyClass] counter:", self.counter ," !\n")
end

function MyClass:__call()
    io.write("[luaMyClass] starting main... starting while loop:\n")   

    -- only works if commented out, doesn't work otherwise...
    -- io.write("[luaMyClass] counter:", self.counter ," !\n")

    local x = 0
    while x < 5 do
        io.write("[luaMyClass] in while #", x, "! yielding...\n")
        x = x + 1
        coroutine.yield()
    end
    io.write("[luaMyClass] one more time for the yield, whee...\n")
    coroutine.yield( 1 )
   
    io.write("[luaMyClass] exiting, returning 0 \n")
    return 0
end




////   c++ side to create and then call the new lua class:

         std::cout << "[C++] running script: " << filename << " class:" << classname << std::endl;
         dofile( L, filename );

         // start a new coroutine
         std::cout << "[C++] new thread..." << std::endl;
         t = lua_newthread( L );
         thread_reference = luaL_ref( L, LUA_REGISTRYINDEX );

         luabind::object class_type = luabind::globals(L)[classname];
         if (luabind::type( class_type ) != LUA_TUSERDATA)
         {
            assert(false && "Expected name of a Lua class symbol.");
            return;
         }

         std::cout << "[C++] calling __init on " << classname << "..." << std::endl;
         luabind::object argsTable = luabind::newtable( t );
         Actor* actor = luabind::call_function<Actor*>(class_type, argsTable);
        
         std::cout << "[C++] calling __call on " << classname << "..." << std::endl;
         luabind::object actor_obj( t, actor );
         luabind::resume_function<void>( actor_obj["__call"] );




///  program output (with self.counter being read from __call):

[C++] init lua:
[C++] sys.init(MyClass.lua) 
[C++] running script: MyClass.lua class:MyClass
[luaMyClass] outside of the class, global scope
[C++] new thread...
[C++] calling __init on MyClass...
[C++Actor] constructor
[luaMyClass] init is called from Lua 5.0.3!
[luaMyClass] counter:1 !
[C++] calling __call on
MyClass...
Assertion failed: lua_gettop(L) == top - m_params + 1, file c:\documents and settings\kevin meinert\desktop\projects\luatesting\luatest\external\include\luabind\detail\call_function.hpp, line 264



///  program output (without  self.counter inside __call):
[C++] init lua:
[C++] sys.init(MyClass.lua) 
[C++] running script: MyClass.lua class:MyClass
[luaMyClass] outside of the class, global scope
[C++] new thread...
[C++] calling __init on
MyClass ...
[C++Actor] constructor
[luaMyClass] init is called from Lua 5.0.3!
[luaMyClass] counter:1 !
[C++] calling __call on
MyClass ...
[luaMyClass] starting main... starting while loop:
[luaMyClass] in while #0! yielding...
[C++] sys.init(a.lua) 
[C++] running script[X].update() loop:........
[luaMyClass] in while #1! yielding...
[C++] recieved yield from lua, processing C++ side now...
[luaMyClass] in while #2! yielding...
[C++] recieved yield from lua, processing C++ side now...
[luaMyClass] in while #3! yielding...
[C++] recieved yield from lua, processing C++ side now...
[luaMyClass] in while #4! yielding...
[C++] recieved yield from lua, processing C++ side now...
[luaMyClass] one more time for the yield, whee...
[C++] recieved yield from lua, processing C++ side now...
[luaMyClass] exiting, returning 0
[C++] dead script...
[c++] removing dead script #0 - 0 script(s) left
[C++Actor] destructor


thanks...
kevin

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
luabind-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/luabind-user
Reply | Threaded
Open this post in threaded view
|

Re: luabind::resume_function, lua_newthread, lua class derived from c++ class, creating/calling this lua class from c++

Arvid Norberg-2
Hi. I've skimmed through your code, and you're not passing in a this-
pointer to the application operator (__call operator).

All member functions on an object expects the first parameter to be a  
this-pointer.

--
Arvid Norberg

On Oct 8, 2006, at 23:27, subatomic wrote:

> Does anyone have a code example of instantiating (from the c++-
> side) a lua class derived from a c++ class,
> then starting a coroutine using one of the lua class's methods?
>
> I'm trying to do this (see code below), and for the most part it is  
> working, but when I refer to self.counter in one of the lua-side  
> class methods, I am getting an error:
>    Assertion failed: lua_gettop(L) == top - m_params + 1, file  
> call_function.hpp, line 264
> where top is 2, and lua_gettop is 1...
> (crash happens in luabind::resume_function)
>
> The docs seem to be sparse for specific examples of the case I  
> listed in the opening line of this email...
> I'd love to see an example in the examples dir (or in the docs)  
> for this specific case. :-)
>
> I suspect that my code is missing some subtle detail to get the  
> class onto the stack for the script to see self inside of  
> members...  or maybe is pushing too many things onto the stack...
>
> To explain my implementation:
>
> Below, you'll see on the lua-side, MyClass:__init (where referring  
> to self works correctly)
> and MyClass: __call, (where referring to self does not work)...
> In short, I am doing luabind::call_function to instantiate a new  
> instance of the lua-class-derived-from-c++-class, which also  
> happens to call MyClass:__init on the lua-side...
> Then, I'm getting __call from the new class object (as returned by  
> luabind::call_function) and running luabind::resume_function on  
> __call.
>
>
> here's my c++ class, and bindings:
>
> class Actor
> {
> public:
>       private:
>       /// ScriptSystem needs private access to Entity to manipulate  
> the script
>       /// state.
>       friend class ScriptSystem;
>
>       /// Entities are noncopyable. Don't copy them.
>       Actor( const Actor& actor );
>       Actor& operator=( const Actor& actor );
>
>    public:
>       Actor()
>       {
>          counter = 1;
>          std::cout << "[C++Actor] constructor" << std::endl;
>       }
>       ~Actor()
>       {
>          counter = 2;
>          std::cout << "[C++Actor] destructor" << std::endl;
>       }
>       virtual void __call()
>       {
>          counter = 3;
>          std::cout << "[C++Actor] call" << std::endl;
>       }
>
>       char counter;
> };
> struct Actor_wrap : Actor, luabind::wrap_base
> {
>    virtual void __call()
>    {
>       std::cout << "[C++Wrapper] __call" << std::endl;
>       call<void>("__call");
>    }
>    static void default_call( Actor* ptr )
>    {
>       std::cout << "[C++Wrapper] default_call" << std::endl;
>       return ptr->Actor::__call();
>    }
> };
> static void bind_actor(lua_State* L)
> {
>    using namespace luabind;
>    module(L)
>    [
>       class_<Actor, Actor_wrap >("Actor")
>          .def(constructor<>())
>          .def_readwrite("counter", &Actor::counter)
>          .def("__call", &Actor::__call, &Actor_wrap::default_call)
>    ];
> }
>
>
>
>
>
> ///// Here's my lua class:////////
>
>
>
> class 'MyClass' (Actor)
>
> io.write("[luaMyClass] outside of the class, global scope\n")
>
> function MyClass:__init( args )
>     super()
>     io.write("[luaMyClass] init is called from ",_VERSION,"!\n")
>     io.write("[luaMyClass] counter:", self.counter ," !\n")
> end
>
> function MyClass:__call()
>     io.write("[luaMyClass] starting main... starting while loop:\n")
>
>     -- only works if commented out, doesn't work otherwise...
>     -- io.write("[luaMyClass] counter:", self.counter ," !\n")
>
>     local x = 0
>     while x < 5 do
>         io.write("[luaMyClass] in while #", x, "! yielding...\n")
>         x = x + 1
>         coroutine.yield()
>     end
>     io.write("[luaMyClass] one more time for the yield, whee...\n")
>     coroutine.yield( 1 )
>
>     io.write("[luaMyClass] exiting, returning 0 \n")
>     return 0
> end
>
>
>
>
> ////   c++ side to create and then call the new lua class:
>
>          std::cout << "[C++] running script: " << filename << "  
> class:" << classname << std::endl;
>          dofile( L, filename );
>
>          // start a new coroutine
>          std::cout << "[C++] new thread..." << std::endl;
>          t = lua_newthread( L );
>          thread_reference = luaL_ref( L, LUA_REGISTRYINDEX );
>
>          luabind::object class_type = luabind::globals(L)[classname];
>          if (luabind::type( class_type ) != LUA_TUSERDATA)
>          {
>             assert(false && "Expected name of a Lua class symbol.");
>             return;
>          }
>
>          std::cout << "[C++] calling __init on " << classname <<  
> "..." << std::endl;
>          luabind::object argsTable = luabind::newtable( t );
>          Actor* actor = luabind::call_function<Actor*>(class_type,  
> argsTable);
>
>          std::cout << "[C++] calling __call on " << classname <<  
> "..." << std::endl;
>          luabind::object actor_obj( t, actor );
>          luabind::resume_function<void>( actor_obj["__call"] );
>
>
>
> ///  program output (with self.counter being read from __call):
>
> [C++] init lua:
> [C++] sys.init(MyClass.lua)
> [C++] running script: MyClass.lua class:MyClass
> [luaMyClass] outside of the class, global scope
> [C++] new thread...
> [C++] calling __init on MyClass...
> [C++Actor] constructor
> [luaMyClass] init is called from Lua 5.0.3!
> [luaMyClass] counter:1 !
> [C++] calling __call on MyClass...
> Assertion failed: lua_gettop(L) == top - m_params + 1, file c:
> \documents and settings\kevin meinert\desktop\projects\luatesting
> \luatest\external\include\luabind\detail\call_function.hpp, line 264
>
>
> ///  program output (without  self.counter inside __call):
> [C++] init lua:
> [C++] sys.init(MyClass.lua)
> [C++] running script: MyClass.lua class:MyClass
> [luaMyClass] outside of the class, global scope
> [C++] new thread...
> [C++] calling __init on MyClass ...
> [C++Actor] constructor
> [luaMyClass] init is called from Lua 5.0.3!
> [luaMyClass] counter:1 !
> [C++] calling __call on MyClass ...
> [luaMyClass] starting main... starting while loop:
> [luaMyClass] in while #0! yielding...
> [C++] sys.init(a.lua)
> [C++] running script[X].update() loop:........
> [luaMyClass] in while #1! yielding...
> [C++] recieved yield from lua, processing C++ side now...
> [luaMyClass] in while #2! yielding...
> [C++] recieved yield from lua, processing C++ side now...
> [luaMyClass] in while #3! yielding...
> [C++] recieved yield from lua, processing C++ side now...
> [luaMyClass] in while #4! yielding...
> [C++] recieved yield from lua, processing C++ side now...
> [luaMyClass] one more time for the yield, whee...
> [C++] recieved yield from lua, processing C++ side now...
> [luaMyClass] exiting, returning 0
> [C++] dead script...
> [c++] removing dead script #0 - 0 script(s) left
> [C++Actor] destructor
>
>
> thanks...
> kevin
> ----------------------------------------------------------------------
> ---
> Take Surveys. Earn Cash. Influence the Future of IT
> Join SourceForge.net's Techsay panel and you'll get the chance to  
> share your
> opinions on IT & business topics through brief surveys -- and earn  
> cash
> http://www.techsay.com/default.php?
> page=join.php&p=sourceforge&CID=DEVDEV________________________________
> _______________
> luabind-user mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/luabind-user

--
Arvid Norberg



-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
luabind-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/luabind-user
Reply | Threaded
Open this post in threaded view
|

Re: luabind::resume_function, lua_newthread, lua class derived from c++ class, creating/calling this lua class from c++

subatomic

it's possible i don't know how to properly pass in the "this" pointer...
this is what i did...
I changed
         luabind::resume_function<void>( actor_obj["__call"] );
to
         luabind::resume_function<void>( actor_obj["__call"]( actor ) );

where actor is a c++ class pointer to a "class Actor"  (i've also tried using the actor_obj object as well with same result.)


now I get:

[C++] init lua:
[C++] sys.init(MyClass.lua) 
[C++] running script: MyClass.lua class:MyClass
[luaMyClass] outside of the class, global scope
[C++] new thread...
[C++] calling __init on MyClass...
[C++Actor] constructor
[luaMyClass] init is called from Lua 5.0.3!
[luaMyClass] counter:1 !
[C++] calling __call on MyClass...
[luaMyClass] starting main... starting while loop:
[luaMyClass] counter:1 !
[luaMyClass] in while #0! yielding...
lua error: attempt to yield across metamethod/C-call boundary

any ideas why I get the error?
I get no breakpoint in any of my Actor or wrapper C++ code.

callstack is this, there's a few luabind things in the stack, and it calls pcall...  which causes the assert in yield...:

>    luatest.exe!lua_yield(lua_State * L=0x00542a70, int nresults=0)  Line 392    C
     luatest.exe!luaB_yield(lua_State * L=0x00542a70)  Line 617 + 0x16    C
     luatest.exe!luaD_precall(lua_State * L=0x00542a70, lua_TObject * func=0x005400b8)  Line 260 + 0x12    C
     luatest.exe!luaV_execute(lua_State * L=0x00542a70)  Line 627 + 0xd    C
     luatest.exe!luaD_call(lua_State * L=0x00542a70, lua_TObject * func=0x00540088, int nResults=1)  Line 313 + 0x9    C
     luatest.exe!f_call (lua_State * L=0x00542a70, void * ud=0x0012f7a8)  Line 672 + 0x16    C
     luatest.exe!luaD_rawrunprotected(lua_State * L=0x00542a70, void (lua_State *, void *)* f=0x0047cc90, void * ud=0x0012f7a8)  Line 88 + 0xd    C
     luatest.exe!luaD_pcall(lua_State * L=0x00542a70, void (lua_State *, void *)* func=0x0047cc90, void * u=0x0012f7a8, int old_top=32, int ef=0)  Line 417 + 0x11    C
     luatest.exe!lua_pcall(lua_State * L=0x00542a70, int nargs=1, int nresults=1, int errfunc=0)  Line 685 + 0x20    C
     luatest.exe!luabind::detail::pcall(lua_State * L=0x00542a70, int nargs=1, int nresults=1)  Line 40 + 0x15    C++
     luatest.exe!luabind::adl::call_proxy<luabind::adl::index_proxy<luabind::adl::object>,boost::tuples::tuple<luabind::adl::object const *,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type> >::call<luabind::detail::null_type>(luabind::detail::null_type * __formal=0x00000000)  Line 1040 + 0xd    C++
     luatest.exe!luabind::adl::call_proxy<luabind::adl::index_proxy<luabind::adl::object>,boost::tuples::tuple<luabind::adl::object const *,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type,boost::tuples::null_type> >::operator luabind::adl::object()  Line 1015 + 0xe    C++
     luatest.exe!ScriptSystem::LuaScript::spawn(lua_State * ls=0x00321278, const char * filename=0x0032152c, const char * classname=0x0051f4dc)  Line 149 + 0x68    C++


thanks.


On 10/8/06, Arvid Norberg <[hidden email]> wrote:
Hi. I've skimmed through your code, and you're not passing in a this-
pointer to the application operator (__call operator).

All member functions on an object expects the first parameter to be a
this-pointer.

--
Arvid Norberg

On Oct 8, 2006, at 23:27, subatomic wrote:

> Does anyone have a code example of instantiating (from the c++-
> side) a lua class derived from a c++ class,
> then starting a coroutine using one of the lua class's methods?
>
> I'm trying to do this (see code below), and for the most part it is
> working, but when I refer to self.counter in one of the lua-side
> class methods, I am getting an error:
>    Assertion failed: lua_gettop(L) == top - m_params + 1, file
> call_function.hpp, line 264
> where top is 2, and lua_gettop is 1...
> (crash happens in luabind::resume_function)
>
> The docs seem to be sparse for specific examples of the case I
> listed in the opening line of this email...
> I'd love to see an example in the examples dir (or in the docs)
> for this specific case. :-)
>
> I suspect that my code is missing some subtle detail to get the
> class onto the stack for the script to see self inside of
> members...  or maybe is pushing too many things onto the stack...
>
> To explain my implementation:
>
> Below, you'll see on the lua-side, MyClass:__init (where referring
> to self works correctly)
> and MyClass: __call, (where referring to self does not work)...
> In short, I am doing luabind::call_function to instantiate a new
> instance of the lua-class-derived-from-c++-class, which also
> happens to call MyClass:__init on the lua-side...
> Then, I'm getting __call from the new class object (as returned by
> luabind::call_function) and running luabind::resume_function on
> __call.
>
>
> here's my c++ class, and bindings:
>
> class Actor
> {
> public:
>       private:
>       /// ScriptSystem needs private access to Entity to manipulate
> the script
>       /// state.
>       friend class ScriptSystem;
>
>       /// Entities are noncopyable. Don't copy them.
>       Actor( const Actor& actor );
>       Actor& operator=( const Actor& actor );
>
>    public:
>       Actor()
>       {
>          counter = 1;
>          std::cout << "[C++Actor] constructor" << std::endl;
>       }
>       ~Actor()
>       {
>          counter = 2;
>          std::cout << "[C++Actor] destructor" << std::endl;
>       }
>       virtual void __call()
>       {
>          counter = 3;
>          std::cout << "[C++Actor] call" << std::endl;
>       }
>
>       char counter;
> };
> struct Actor_wrap : Actor, luabind::wrap_base
> {
>    virtual void __call()
>    {
>       std::cout << "[C++Wrapper] __call" << std::endl;
>       call<void>("__call");
>    }
>    static void default_call( Actor* ptr )
>    {
>       std::cout << "[C++Wrapper] default_call" << std::endl;
>       return ptr->Actor::__call();

>    }
> };
> static void bind_actor(lua_State* L)
> {
>    using namespace luabind;
>    module(L)
>    [
>       class_<Actor, Actor_wrap >("Actor")
>          .def(constructor<>())
>          .def_readwrite("counter", &Actor::counter)
>          .def("__call", &Actor::__call, &Actor_wrap::default_call)
>    ];
> }
>
>
>
>
>
> ///// Here's my lua class:////////
>
>
>
> class 'MyClass' (Actor)
>
> io.write("[luaMyClass] outside of the class, global scope\n")
>
> function MyClass:__init( args )
>     super()
>     io.write("[luaMyClass] init is called from ",_VERSION,"!\n")
>     io.write("[luaMyClass] counter:", self.counter ," !\n")
> end
>
> function MyClass:__call()
>     io.write("[luaMyClass] starting main... starting while loop:\n")
>
>     -- only works if commented out, doesn't work otherwise...
>     -- io.write("[luaMyClass] counter:", self.counter ," !\n")
>
>     local x = 0
>     while x < 5 do
>         io.write("[luaMyClass] in while #", x, "! yielding...\n")
>         x = x + 1
>         coroutine.yield()
>     end
>     io.write("[luaMyClass] one more time for the yield, whee...\n")
>     coroutine.yield( 1 )
>
>     io.write ("[luaMyClass] exiting, returning 0 \n")
>     return 0
> end
>
>
>
>
> ////   c++ side to create and then call the new lua class:
>
>          std::cout << "[C++] running script: " << filename << "
> class:" << classname << std::endl;
>          dofile( L, filename );
>
>          // start a new coroutine
>          std::cout << "[C++] new thread..." << std::endl;
>          t = lua_newthread( L );
>          thread_reference = luaL_ref( L, LUA_REGISTRYINDEX );
>
>          luabind::object class_type = luabind::globals(L)[classname];
>          if (luabind::type( class_type ) != LUA_TUSERDATA)
>          {
>             assert(false && "Expected name of a Lua class symbol.");
>             return;
>          }
>
>          std::cout << "[C++] calling __init on " << classname <<
> "..." << std::endl;
>          luabind::object argsTable = luabind::newtable( t );
>          Actor* actor = luabind::call_function<Actor*>(class_type,
> argsTable);
>
>          std::cout << "[C++] calling __call on " << classname <<
> "..." << std::endl;
>          luabind::object actor_obj( t, actor );
>          luabind::resume_function<void>( actor_obj["__call"] );
>
>
>
> ///  program output (with self.counter being read from __call):
>
> [C++] init lua:
> [C++] sys.init(MyClass.lua)
> [C++] running script: MyClass.lua class:MyClass
> [luaMyClass] outside of the class, global scope

> [C++] new thread...
> [C++] calling __init on MyClass...
> [C++Actor] constructor
> [luaMyClass] init is called from Lua 5.0.3!
> [luaMyClass] counter:1 !
> [C++] calling __call on MyClass...
> Assertion failed: lua_gettop(L) == top - m_params + 1, file c:
> \documents and settings\kevin meinert\desktop\projects\luatesting
> \luatest\external\include\luabind\detail\call_function.hpp, line 264
>
>
> ///  program output (without  self.counter inside __call):
> [C++] init lua:
> [C++] sys.init(MyClass.lua)
> [C++] running script: MyClass.lua class:MyClass
> [luaMyClass] outside of the class, global scope
> [C++] new thread...
> [C++] calling __init on MyClass ...
> [C++Actor] constructor
> [luaMyClass] init is called from Lua 5.0.3!
> [luaMyClass] counter:1 !
> [C++] calling __call on MyClass ...
> [luaMyClass] starting main... starting while loop:
> [luaMyClass] in while #0! yielding...
> [C++] sys.init(a.lua)
> [C++] running script[X].update() loop:........
> [luaMyClass] in while #1! yielding...
> [C++] recieved yield from lua, processing C++ side now...
> [luaMyClass] in while #2! yielding...
> [C++] recieved yield from lua, processing C++ side now...
> [luaMyClass] in while #3! yielding...
> [C++] recieved yield from lua, processing C++ side now...
> [luaMyClass] in while #4! yielding...
> [C++] recieved yield from lua, processing C++ side now...
> [luaMyClass] one more time for the yield, whee...
> [C++] recieved yield from lua, processing C++ side now...
> [luaMyClass] exiting, returning 0
> [C++] dead script...
> [c++] removing dead script #0 - 0 script(s) left
> [C++Actor] destructor
>
>
> thanks...
> kevin
> ----------------------------------------------------------------------
> ---
> Take Surveys. Earn Cash. Influence the Future of IT
> Join SourceForge.net 's Techsay panel and you'll get the chance to
> share your
> opinions on IT & business topics through brief surveys -- and earn
> cash
> http://www.techsay.com/default.php ?
> page=join.php&p=sourceforge&CID=DEVDEV________________________________
> _______________
> luabind-user mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/luabind-user

--
Arvid Norberg



-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
luabind-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/luabind-user



--
Kevin Meinert
http://www.subatomicglue.com
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
luabind-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/luabind-user
Reply | Threaded
Open this post in threaded view
|

Re: luabind::resume_function, lua_newthread, lua class derived from c++ class, creating/calling this lua class from c++

subatomic
In reply to this post by Arvid Norberg-2

Thanks for the tip.
I changed
   luabind::resume_function<void>( actor_obj["__call"] );
to
   luabind::resume_function<void>( actor_obj["__call"], actor );
and it works now....
thanks

On 10/8/06, Arvid Norberg <[hidden email]> wrote:
Hi. I've skimmed through your code, and you're not passing in a this-
pointer to the application operator (__call operator).

All member functions on an object expects the first parameter to be a
this-pointer.

--
Arvid Norberg

On Oct 8, 2006, at 23:27, subatomic wrote:

> Does anyone have a code example of instantiating (from the c++-
> side) a lua class derived from a c++ class,
> then starting a coroutine using one of the lua class's methods?
>
> I'm trying to do this (see code below), and for the most part it is
> working, but when I refer to self.counter in one of the lua-side
> class methods, I am getting an error:
>    Assertion failed: lua_gettop(L) == top - m_params + 1, file
> call_function.hpp, line 264
> where top is 2, and lua_gettop is 1...
> (crash happens in luabind::resume_function)
>
> The docs seem to be sparse for specific examples of the case I
> listed in the opening line of this email...
> I'd love to see an example in the examples dir (or in the docs)
> for this specific case. :-)
>
> I suspect that my code is missing some subtle detail to get the
> class onto the stack for the script to see self inside of
> members...  or maybe is pushing too many things onto the stack...
>
> To explain my implementation:
>
> Below, you'll see on the lua-side, MyClass:__init (where referring
> to self works correctly)
> and MyClass: __call, (where referring to self does not work)...
> In short, I am doing luabind::call_function to instantiate a new
> instance of the lua-class-derived-from-c++-class, which also
> happens to call MyClass:__init on the lua-side...
> Then, I'm getting __call from the new class object (as returned by
> luabind::call_function) and running luabind::resume_function on
> __call.
>
>
> here's my c++ class, and bindings:
>
> class Actor
> {
> public:
>       private:
>       /// ScriptSystem needs private access to Entity to manipulate
> the script
>       /// state.
>       friend class ScriptSystem;
>
>       /// Entities are noncopyable. Don't copy them.
>       Actor( const Actor& actor );
>       Actor& operator=( const Actor& actor );
>
>    public:
>       Actor()
>       {
>          counter = 1;
>          std::cout << "[C++Actor] constructor" << std::endl;
>       }
>       ~Actor()
>       {
>          counter = 2;
>          std::cout << "[C++Actor] destructor" << std::endl;
>       }
>       virtual void __call()
>       {
>          counter = 3;
>          std::cout << "[C++Actor] call" << std::endl;
>       }
>
>       char counter;
> };
> struct Actor_wrap : Actor, luabind::wrap_base
> {
>    virtual void __call()
>    {
>       std::cout << "[C++Wrapper] __call" << std::endl;
>       call<void>("__call");
>    }
>    static void default_call( Actor* ptr )
>    {
>       std::cout << "[C++Wrapper] default_call" << std::endl;
>       return ptr->Actor::__call();

>    }
> };
> static void bind_actor(lua_State* L)
> {
>    using namespace luabind;
>    module(L)
>    [
>       class_<Actor, Actor_wrap >("Actor")
>          .def(constructor<>())
>          .def_readwrite("counter", &Actor::counter)
>          .def("__call", &Actor::__call, &Actor_wrap::default_call)
>    ];
> }
>
>
>
>
>
> ///// Here's my lua class:////////
>
>
>
> class 'MyClass' (Actor)
>
> io.write("[luaMyClass] outside of the class, global scope\n")
>
> function MyClass:__init( args )
>     super()
>     io.write("[luaMyClass] init is called from ",_VERSION,"!\n")
>     io.write("[luaMyClass] counter:", self.counter ," !\n")
> end
>
> function MyClass:__call()
>     io.write("[luaMyClass] starting main... starting while loop:\n")
>
>     -- only works if commented out, doesn't work otherwise...
>     -- io.write("[luaMyClass] counter:", self.counter ," !\n")
>
>     local x = 0
>     while x < 5 do
>         io.write("[luaMyClass] in while #", x, "! yielding...\n")
>         x = x + 1
>         coroutine.yield()
>     end
>     io.write("[luaMyClass] one more time for the yield, whee...\n")
>     coroutine.yield( 1 )
>
>     io.write ("[luaMyClass] exiting, returning 0 \n")
>     return 0
> end
>
>
>
>
> ////   c++ side to create and then call the new lua class:
>
>          std::cout << "[C++] running script: " << filename << "
> class:" << classname << std::endl;
>          dofile( L, filename );
>
>          // start a new coroutine
>          std::cout << "[C++] new thread..." << std::endl;
>          t = lua_newthread( L );
>          thread_reference = luaL_ref( L, LUA_REGISTRYINDEX );
>
>          luabind::object class_type = luabind::globals(L)[classname];
>          if (luabind::type( class_type ) != LUA_TUSERDATA)
>          {
>             assert(false && "Expected name of a Lua class symbol.");
>             return;
>          }
>
>          std::cout << "[C++] calling __init on " << classname <<
> "..." << std::endl;
>          luabind::object argsTable = luabind::newtable( t );
>          Actor* actor = luabind::call_function<Actor*>(class_type,
> argsTable);
>
>          std::cout << "[C++] calling __call on " << classname <<
> "..." << std::endl;
>          luabind::object actor_obj( t, actor );
>          luabind::resume_function<void>( actor_obj["__call"] );
>
>
>
> ///  program output (with self.counter being read from __call):
>
> [C++] init lua:
> [C++] sys.init(MyClass.lua)
> [C++] running script: MyClass.lua class:MyClass
> [luaMyClass] outside of the class, global scope

> [C++] new thread...
> [C++] calling __init on MyClass...
> [C++Actor] constructor
> [luaMyClass] init is called from Lua 5.0.3!
> [luaMyClass] counter:1 !
> [C++] calling __call on MyClass...
> Assertion failed: lua_gettop(L) == top - m_params + 1, file c:
> \documents and settings\kevin meinert\desktop\projects\luatesting
> \luatest\external\include\luabind\detail\call_function.hpp, line 264
>
>
> ///  program output (without  self.counter inside __call):
> [C++] init lua:
> [C++] sys.init(MyClass.lua)
> [C++] running script: MyClass.lua class:MyClass
> [luaMyClass] outside of the class, global scope
> [C++] new thread...
> [C++] calling __init on MyClass ...
> [C++Actor] constructor
> [luaMyClass] init is called from Lua 5.0.3!
> [luaMyClass] counter:1 !
> [C++] calling __call on MyClass ...
> [luaMyClass] starting main... starting while loop:
> [luaMyClass] in while #0! yielding...
> [C++] sys.init(a.lua)
> [C++] running script[X].update() loop:........
> [luaMyClass] in while #1! yielding...
> [C++] recieved yield from lua, processing C++ side now...
> [luaMyClass] in while #2! yielding...
> [C++] recieved yield from lua, processing C++ side now...
> [luaMyClass] in while #3! yielding...
> [C++] recieved yield from lua, processing C++ side now...
> [luaMyClass] in while #4! yielding...
> [C++] recieved yield from lua, processing C++ side now...
> [luaMyClass] one more time for the yield, whee...
> [C++] recieved yield from lua, processing C++ side now...
> [luaMyClass] exiting, returning 0
> [C++] dead script...
> [c++] removing dead script #0 - 0 script(s) left
> [C++Actor] destructor
>
>
> thanks...
> kevin
> ----------------------------------------------------------------------
> ---
> Take Surveys. Earn Cash. Influence the Future of IT
> Join SourceForge.net 's Techsay panel and you'll get the chance to
> share your
> opinions on IT & business topics through brief surveys -- and earn
> cash
> http://www.techsay.com/default.php ?
> page=join.php&p=sourceforge&CID=DEVDEV________________________________
> _______________
> luabind-user mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/luabind-user

--
Arvid Norberg



-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
luabind-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/luabind-user



--
Kevin Meinert
http://www.subatomicglue.com
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
luabind-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/luabind-user