Creating properties in Lua-only classes

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

Creating properties in Lua-only classes

Kitten, Nicholas
Does anyone know how I would go about creating a property within a Lua-created class (using Lua functions for getters and setters)?  I'm guessing there's support in the metatables for doing it, but I've never seen an implementation.

Thanks,
-Nick

------------------------------------------------------------------------------
The ultimate all-in-one performance toolkit: Intel(R) Parallel Studio XE:
Pinpoint memory and threading errors before they happen.
Find and fix more than 250 security defects in the development cycle.
Locate bottlenecks in serial and parallel code that limit performance.
http://p.sf.net/sfu/intel-dev2devfeb
_______________________________________________
luabind-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/luabind-user
Reply | Threaded
Open this post in threaded view
|

Re: Creating properties in Lua-only classes

Kitten, Nicholas
I'll rephrase my question, with code this time:

I have a C++ class, bound to Lua along these lines:

luabind::class_<Window>( "Window" )
.def( luabind::constructor<>( ) )
.property( "height", &Window::GetHeight, &Window::SetHeight )
.property( "width", &Window::GetWidth, &Window::SetWidth );

/** wrap_base forwarding class omitted **/

Of course, in Lua this means I can do the following:

win = Window()
win.width = 320        -- calls setter
print( win.width )       -- calls getter

Now, I would like to allow a client to subclass Window from within Lua, overriding the setters and/or getters with Lua functions, something like this:

class 'SubWindow' (Window)

function SubWindow:SetHeight( newHeight )
Window.SetHeight( self, newHeight )
--  other stuff
end

function SubWindow:SetWidth( newWidth )
Window.SetWidth( self, newWidth )
--  other stuff
end

function SubWindow:__init( )
Window.__init(self)
--[[
    magically bind derived SetHeight( ) and SetWidth( ) to __newindex metamethod
--]]
end

win = SubWindow()
win.width = 320        -- calls SubWindow's setter
print( win.width )       -- calls Window's getter

As you can see, the only way I can think to do this would be by overriding the __index and __newindex metamethods on the derived class, but because Luabind classes are userdata, this seems impossible at the moment.  I know the last comment I read from this list on the subject said it might possibly be implemented with version .9 (even though firm plans were only for 1.0) - has that happened?

If not, is there a distinct mechanism within Luabind to override properties in derived classes?  I remember seeing a comment in the source saying that properties should "always be overridden, not overloaded", but I couldn't discern how the overriding would happen in the first place.

Thanks,
-Nick



On Tue, Feb 8, 2011 at 12:06 PM, Kitten, Nicholas <[hidden email]> wrote:
Does anyone know how I would go about creating a property within a Lua-created class (using Lua functions for getters and setters)?  I'm guessing there's support in the metatables for doing it, but I've never seen an implementation.

Thanks,
-Nick


------------------------------------------------------------------------------
Index, Search & Analyze Logs and other IT data in Real-Time with Splunk
Collect, index and harness all the fast moving IT data generated by your
applications, servers and devices whether physical, virtual or in the cloud.
Deliver compliance at lower cost and gain new business insights.
Free Software Download: http://p.sf.net/sfu/splunk-dev2dev
_______________________________________________
luabind-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/luabind-user
Reply | Threaded
Open this post in threaded view
|

Re: Creating properties in Lua-only classes

Kitten, Nicholas
Wow, I just realized I was overthinking this way too much.  If I have the following forwarding class using wrap_base:

struct WindowWrapper : Window, luabind::wrap_base
{
    WindowWrapper()
: base() {} virtual void SetHeight(int h) { call<void>("SetHeight", h); } static void BaseSetHeight(Window* ptr, int h) { return ptr->Window::SetHeight(h); } };

Then simply overriding SetHeight( ) in Lua will automatically work, because

win.height = 3
-- calls Window::SetHeight( )
-- which calls Lua's version of SetHeight( ), in this case SubWindow:SetHeight( )

So as long as I maintain a consistent naming convention (property "height" corresponds to "GetHeight" and "SetHeight"), then clients are free to override the getters and setters in Lua.

 

On Mon, Feb 21, 2011 at 3:33 PM, Kitten, Nicholas <[hidden email]> wrote:
I'll rephrase my question, with code this time:

I have a C++ class, bound to Lua along these lines:

luabind::class_<Window>( "Window" )
.def( luabind::constructor<>( ) )
.property( "height", &Window::GetHeight, &Window::SetHeight )
.property( "width", &Window::GetWidth, &Window::SetWidth );

/** wrap_base forwarding class omitted **/

Of course, in Lua this means I can do the following:

win = Window()
win.width = 320        -- calls setter
print( win.width )       -- calls getter

Now, I would like to allow a client to subclass Window from within Lua, overriding the setters and/or getters with Lua functions, something like this:

class 'SubWindow' (Window)

function SubWindow:SetHeight( newHeight )
Window.SetHeight( self, newHeight )
--  other stuff
end

function SubWindow:SetWidth( newWidth )
Window.SetWidth( self, newWidth )
--  other stuff
end

function SubWindow:__init( )
Window.__init(self)
--[[
    magically bind derived SetHeight( ) and SetWidth( ) to __newindex metamethod
--]]
end

win = SubWindow()
win.width = 320        -- calls SubWindow's setter
print( win.width )       -- calls Window's getter

As you can see, the only way I can think to do this would be by overriding the __index and __newindex metamethods on the derived class, but because Luabind classes are userdata, this seems impossible at the moment.  I know the last comment I read from this list on the subject said it might possibly be implemented with version .9 (even though firm plans were only for 1.0) - has that happened?

If not, is there a distinct mechanism within Luabind to override properties in derived classes?  I remember seeing a comment in the source saying that properties should "always be overridden, not overloaded", but I couldn't discern how the overriding would happen in the first place.

Thanks,
-Nick



On Tue, Feb 8, 2011 at 12:06 PM, Kitten, Nicholas <[hidden email]> wrote:
Does anyone know how I would go about creating a property within a Lua-created class (using Lua functions for getters and setters)?  I'm guessing there's support in the metatables for doing it, but I've never seen an implementation.

Thanks,
-Nick



------------------------------------------------------------------------------
Index, Search & Analyze Logs and other IT data in Real-Time with Splunk
Collect, index and harness all the fast moving IT data generated by your
applications, servers and devices whether physical, virtual or in the cloud.
Deliver compliance at lower cost and gain new business insights.
Free Software Download: http://p.sf.net/sfu/splunk-dev2dev
_______________________________________________
luabind-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/luabind-user
Reply | Threaded
Open this post in threaded view
|

Re: Creating properties in Lua-only classes

Kitten, Nicholas
Now, once more on the subject of creating/modifying properties in Lua: overriding functions will work for modifying existing properties, but it won't allow you to create new ones.  After some more digging and finding mysterious references in the changelog to the "Lua property() function", I eventually found some undocumented functionality; here is an example of creating a brand new property in a Lua-only class: 

class 'Window'

function Window:getAspectRatio()
    return self.width / self.height
end

function Window:setAspectRatio(aspect)
    self.height = self.width / aspect
end

function Window:__init(width, height)
    self.width = width
    self.height = height
    -- first parameter is getter, second parameter is (optional) setter
    self.aspectRatio = property( Window.getAspectRatio, Window.setAspectRatio )
end

-- normal property usage
win = Window(640, 480)
print( win.aspectRatio ) -- prints 1.3333333333333
win.aspectRatio = 1.25
print( win.height ) -- prints 512


Note that getters seem to be restricted to a single return value.



On Mon, Feb 21, 2011 at 3:59 PM, Kitten, Nicholas <[hidden email]> wrote:
Wow, I just realized I was overthinking this way too much.  If I have the following forwarding class using wrap_base:

struct WindowWrapper : Window, luabind::wrap_base
{
    WindowWrapper()
: base() {} virtual void SetHeight(int h) { call<void>("SetHeight", h); } static void BaseSetHeight(Window* ptr, int h) { return ptr->Window::SetHeight(h); } };

Then simply overriding SetHeight( ) in Lua will automatically work, because

win.height = 3
-- calls Window::SetHeight( )
-- which calls Lua's version of SetHeight( ), in this case SubWindow:SetHeight( )

So as long as I maintain a consistent naming convention (property "height" corresponds to "GetHeight" and "SetHeight"), then clients are free to override the getters and setters in Lua.

 

On Mon, Feb 21, 2011 at 3:33 PM, Kitten, Nicholas <[hidden email]> wrote:
I'll rephrase my question, with code this time:

I have a C++ class, bound to Lua along these lines:

luabind::class_<Window>( "Window" )
.def( luabind::constructor<>( ) )
.property( "height", &Window::GetHeight, &Window::SetHeight )
.property( "width", &Window::GetWidth, &Window::SetWidth );

/** wrap_base forwarding class omitted **/

Of course, in Lua this means I can do the following:

win = Window()
win.width = 320        -- calls setter
print( win.width )       -- calls getter

Now, I would like to allow a client to subclass Window from within Lua, overriding the setters and/or getters with Lua functions, something like this:

class 'SubWindow' (Window)

function SubWindow:SetHeight( newHeight )
Window.SetHeight( self, newHeight )
--  other stuff
end

function SubWindow:SetWidth( newWidth )
Window.SetWidth( self, newWidth )
--  other stuff
end

function SubWindow:__init( )
Window.__init(self)
--[[
    magically bind derived SetHeight( ) and SetWidth( ) to __newindex metamethod
--]]
end

win = SubWindow()
win.width = 320        -- calls SubWindow's setter
print( win.width )       -- calls Window's getter

As you can see, the only way I can think to do this would be by overriding the __index and __newindex metamethods on the derived class, but because Luabind classes are userdata, this seems impossible at the moment.  I know the last comment I read from this list on the subject said it might possibly be implemented with version .9 (even though firm plans were only for 1.0) - has that happened?

If not, is there a distinct mechanism within Luabind to override properties in derived classes?  I remember seeing a comment in the source saying that properties should "always be overridden, not overloaded", but I couldn't discern how the overriding would happen in the first place.

Thanks,
-Nick



On Tue, Feb 8, 2011 at 12:06 PM, Kitten, Nicholas <[hidden email]> wrote:
Does anyone know how I would go about creating a property within a Lua-created class (using Lua functions for getters and setters)?  I'm guessing there's support in the metatables for doing it, but I've never seen an implementation.

Thanks,
-Nick




------------------------------------------------------------------------------
Free Software Download: Index, Search & Analyze Logs and other IT data in
Real-Time with Splunk. Collect, index and harness all the fast moving IT data
generated by your applications, servers and devices whether physical, virtual
or in the cloud. Deliver compliance at lower cost and gain new business
insights. http://p.sf.net/sfu/splunk-dev2dev 
_______________________________________________
luabind-user mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/luabind-user