lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


I know my use case very easy to grok but I think it is a pretty common pattern (Lua sub-classes of C++ classes) and it would really be nice to have some feedback before I start updating lots of C++ and Lua code..

;-)

Gaspard

On Wed, Jun 29, 2011 at 10:55 PM, Gaspard Bucher <gaspard@teti.ch> wrote:
I am considering some changes to the way I handle "self" with regards to userdata. Currently, whenever I need "self" (a Lua table) and a user data, I fake some inheritance mechanism and I use upvalues to call original functions. From the other side, every callback (like "paint") is a lua thread stored in the C++ object.

-- == create a new instance
function SpecialWidget()
  local self = {
    super = mimas.Widget() -- userdata
  }

  -- wrap calls from C
  function super.paint(p, w, h)
    self:paint(p, w, h)
  end

  return self
end

--- === etc, you get the idea

I have a new idea that would use the "uservalue" from Lua 5.2


-- ============ Create new class (code with colors: https://gist.github.com/1054915)
SpecialEdit = {}
setmetatable(SpecialEdit, mimas.LineEdit_mt)

-- calling SpecialEdit() should do the following things
-- 1. create userdata
-- 2. set new table as uservale                 ---> self
-- 3. create new lua thread and install "self" on the stack
-- 4. set access to userdata from self          ---> self.super = userdata
-- 5. set "SpecialEdit" as metatable for "self" ---> setmetatable(self, SpecialEdit)
-- 6. return "self"


-- This is a callback called from the C side. The call goes as follows
-- 1. the object's lua_thread's stack contains "self", ready to be used.
-- 2. call self.textChanged(self, text)
function SpecialEdit:textChanged(text)
  -- just to show that self is accessed by the callback with custom values ("owner").
  self.owner:doSomething()

  -- call a native method
  -- "hide" is found in mimas.LineEdit_mt       ---> LineEdit_mt.hide(self)
  -- the userdata is found in self              ---> LineEdit *c_obj = self.super    // C pseudo-code
  -- call the class method                      ---> c_obj->hide()
  self:hide(nil)
end

In order to handle the callbacks, I would create a single lua thread (which could keep "self" in it's stack).

What do you think ?

Gaspard



--

                                                               Gaspard