Using metatables and metamethods on system tables

Announcements, support questions, and discussion for the Dialogue System.
User avatar
liisi.laasik
Posts: 13
Joined: Tue Oct 03, 2017 9:15 am
Location: Tallinn, Estonia

Using metatables and metamethods on system tables

Post by liisi.laasik »

I am trying to use metatables to have callback functionality on some Lua table modifications (through __index and __newindex metamethods).

Everything is working nicely, but some changes will not invoke the metamethods. I suspect the data update, on some occasions, is being done through the rawset metamethod.

Mostly I am interested in DialogueEntry.userScript expressions:
Are they executed through the rawset method?
Could there be any other reason, why when DebugLevel is set to Info, the console displays "Dialogue System: Lua(Variable["XXX"] = true)" but no callback is executed. However when the same is called from project code through DialogueLua.SetVariable(), callback works.

I am using the NLua interpreter.
User avatar
Tony Li
Posts: 22104
Joined: Thu Jul 18, 2013 1:27 pm

Re: Using metatables and metamethods on system tables

Post by Tony Li »

Hi,

When working with NLua, the Dialogue System maintains an instance of a Lua VM (LuaInterface.Lua class). The public property for this VM is NLua_Lua.VM.

It runs all Lua through LuaInterface.Lua.DoString(). Nothing uses rawset. The full signature of Lua.Run is:

Lua.Run(string code, bool debug=false, bool reportExceptions=false)

When Debug Level is set to Info, userScript passes debug=true.

If it's any help, the source code is in Scripts/SourceCode.unitypackage. (Import it into a separate project, not your main project, and delete the DLLS so they don't conflict.) There's a subpackage to import for the NLua code.

Can you share the code you're using for callbacks? I can try to reproduce the same thing here and suggest a solution.
User avatar
liisi.laasik
Posts: 13
Joined: Tue Oct 03, 2017 9:15 am
Location: Tallinn, Estonia

Re: Using metatables and metamethods on system tables

Post by liisi.laasik »

I updated Dialogue System (DialogueSystem_1_7_6_Unity56plus).

Just for testing I added https://www.lua.org/pil/13.4.4.html in Dialogue Database startup script for Variable table (and emptied the Variable table for testing).

Still, some calls invoke the callback and some do not. For example DialogueLua.SetParticipants invokes them and now DialogueLua.SetVariable does not. Or at least that is how it looks from my end.

I imported both dialogue system and nlua sources to a separate project and looked through some of the code, but honestly I don't know enough about Lua to understand the specifics.

If you have any suggestions, it would be nice. However, developing the callback is more of a nice-to-have functionality. We can use some combination of LuaWatchItem and some manual queries - that would just be somewhat less efficient and foolproof.
User avatar
Tony Li
Posts: 22104
Joined: Thu Jul 18, 2013 1:27 pm

Re: Using metatables and metamethods on system tables

Post by Tony Li »

LuaWatchItems are rather inefficient. Today is the last day of Unite Austin. When I get back from it, I'll dig into this and post an answer here, but it will probably not be until tomorrow.
User avatar
liisi.laasik
Posts: 13
Joined: Tue Oct 03, 2017 9:15 am
Location: Tallinn, Estonia

Re: Using metatables and metamethods on system tables

Post by liisi.laasik »

Next week is perfectly fine too. Thank you!
User avatar
Tony Li
Posts: 22104
Joined: Thu Jul 18, 2013 1:27 pm

Re: Using metatables and metamethods on system tables

Post by Tony Li »

I'm afraid I wasn't able to reproduce this one, either. Here's a test scene that I used: TestNLua_2017-10-08.unitypackage. (Exported in Unity 5.3.0.)

It uses this Lua script, which I tested in the dialogue database's Global User Script as well as in a separate script included in the package above.

Code: Select all

    -- keep a private access to original table
    _t = Variable
    
    -- create proxy
    Variable = {}
    
    -- create metatable
    mt = {
      __index = function (t,k)
        printstr("*access to element " .. tostring(k))
        return _t[k]   -- access the original table
      end,
    
      __newindex = function (t,k,v)
        printstr("*update of element " .. tostring(k) ..
                             " to " .. tostring(v))
        _t[k] = v   -- update original table
      end
    }
    setmetatable(Variable, mt)
(The printstr function is added by a test script. It simply prints to the Unity console in yellow text.)

I will include the minor optimizations to GetTableField and SetTableField in the next release of the Dialogue System. If you can point me to a way to reproduce the issue you're seeing, I'll also include any necessary fixes in the next release. (Let me know what I can do to help.)
User avatar
Tony Li
Posts: 22104
Joined: Thu Jul 18, 2013 1:27 pm

Re: Using metatables and metamethods on system tables

Post by Tony Li »

Maybe a clue: If you're using the default Lua, DialogueLua.SetVariable() does use a raw set, so it won't generate an __index callback.

However, if you've switched to NLua, DialogueLua.SetVariable() does a regular set.

Are you sure you're using NLua? (The compiler define "USE_NLUA" should be set.)
User avatar
liisi.laasik
Posts: 13
Joined: Tue Oct 03, 2017 9:15 am
Location: Tallinn, Estonia

Re: Using metatables and metamethods on system tables

Post by liisi.laasik »

To switch to NLua, I followed the instructions here: http://www.pixelcrushers.com/dialogue_s ... n_lua.html
1) imported import Third Party Support/NLua Support.unitypackage
2) deleted DLLs/LuaInterpreter.dll

I am not building dialogue system from source, so I didn't set any compiler defines. Should I?
User avatar
Tony Li
Posts: 22104
Joined: Thu Jul 18, 2013 1:27 pm

Re: Using metatables and metamethods on system tables

Post by Tony Li »

You did the right steps. You don't need to do anything else. (I mentioned the compiler directive in case you were building from source, which I don't recommend because it's a needless hassle.)

Did the example scene in my previous post work for you?
User avatar
liisi.laasik
Posts: 13
Joined: Tue Oct 03, 2017 9:15 am
Location: Tallinn, Estonia

Re: Using metatables and metamethods on system tables

Post by liisi.laasik »

Your scene has a missing prefab.

I am trying to make an example scene of my own, but it might take a day or two.
Post Reply