1

I have a library functions defined like that in my C code :

static const struct luaL_reg SelSurfaceLib [] = {
    {"CapabilityConst", CapabilityConst},
    {"create", createsurface},
    {NULL, NULL}
};

static const struct luaL_reg SelSurfaceM [] = {
    {"Release", SurfaceRelease},
    {"GetPosition", SurfaceGetPosition},
    {"clone", SurfaceClone},
    {"restore", SurfaceRestore},
    {NULL, NULL}
};

void _include_SelSurface( lua_State *L ){
    luaL_newmetatable(L, "SelSurface");
    lua_pushstring(L, "__index");
    lua_pushvalue(L, -2);
    lua_settable(L, -3);    /* metatable.__index = metatable */
    luaL_register(L, NULL, SelSurfaceM);
    luaL_register(L,"SelSurface", SelSurfaceLib);
}

And I can use it with this Lua code :

local sub = SelSurface.create()
local x,y = sub:GetPosition()
...

Now, my difficult issue : I'm using follwing code

function HLSubSurface(parent_surface, x,y,sx,sy )
    local self = {}

    -- fields
    local srf = parent_surface:SubSurface( x,y, sx,sy )

    -- methods
    local meta = {
        __index = function (t,k)
            local tbl = getmetatable(srf)
            return tbl[k]
        end
    }
    setmetatable( self, meta )

    return self
end

and my main code is :

sub = HLSubSurface( parent, 0,0, 160,320 )
x,y = sub.GetPosition()

but it's failing

./HDB/80_LeftBar.lua:19: bad argument #1 to 'SetFont' (SelSurface expected, got userdata)

It's because I need to provide srf as 1st argument to GetPosition() function ... but I strictly duno how to do that :(

I don't want to do it when calling GetPosition(), x,y = sub.GetPosition() but I'm looking for a way to do it transparently by setting it in meta's function.

In other words, I would like to have HLSubSurface object to inherit methods from SubSurface.

Any idea ?

Thanks.

Laurent

  • 1
    To be clear, you want the call `sub.somemethod(..)` to turn into `srf:somemethod(...)` behind the scenes where, with `srf` being whatever it was set to when it was created with `HLSubSurface`? – greatwolf Jan 27 '17 at 00:53
  • Exactly :) My goal is to avoid to duplicate all calls. – destroyedlolo Jan 27 '17 at 14:27

1 Answers1

1
function HLSubSurface(parent_surface, x, y, sx, sy)
   local srf = parent_surface:SubSurface(x, y, sx, sy)

   local self = {
      -- fields
      ....
   }

   setmetatable(self, {__index = 
      function (obj, key)
         local parent_field
         local parent_fields = getmetatable(srf).__index
         if type(parent_fields) == "function" then
            parent_field = parent_fields(key)
         elseif parent_fields then 
            parent_field = parent_fields[key]
         end
         if type(parent_field) == "function" then
            return 
               function(o, ...)
                  if o == obj then
                     return parent_field(srf, ...)
                  else
                     return parent_field(o, ...)
                  end
               end
         else
            return parent_field
         end
      end
   })

   return self
end

And your main code would be:

sub = HLSubSurface( parent, 0,0, 160,320 )
x,y = sub:GetPosition()
Egor Skriptunoff
  • 906
  • 1
  • 8
  • 23