SkittlesAreFalling Posted July 9, 2014 Share Posted July 9, 2014 Title says everything. I don't understand why I cannot pass my function through the triggerEvent parameters: addEvent("TestEvent"); CreateTest = function() local Public = {}; local Private = {}; Private.String = "Hello world!"; Public.Test = function() outputDebugString(Private.String); end HandleTest(Public); triggerEvent("TestEvent", resourceRoot, Public); return Public; end HandleTest = function(Public) Public.Test(); -- Works. end addEventHandler( "TestEvent", root, function(Public) Public.Test(); -- This gives error that the field is nil. end ); Test = CreateTest(); Test.Test(); -- Works. I'd like to utilize Lua's class system with MTA's event system but the event system is preventing me from doing so. Link to comment
xXMADEXx Posted July 9, 2014 Share Posted July 9, 2014 This is just a thought, but I'm not really 100% sure. I think the reason it won't work is because when you're using the event, it's sending the Public class, but when you try to run Public.Test it's calling Private.String which would never be defined. Again, I'm not 100% sure on this. Link to comment
SkittlesAreFalling Posted July 9, 2014 Author Share Posted July 9, 2014 When I call triggerEvent, I am sending the Public table containing the function(s) through the parameters, above that I made a quick function showing that tables with functions are passable through parameters, but I'm wondering why the event system didn't pass the functions in the table. Link to comment
xXMADEXx Posted July 9, 2014 Share Posted July 9, 2014 Ah yes, that I ran the code I see what you mean. This is something really weird, I tried using a variable as an index in the Public array, and that works just fine. My thought would be maybe MTA removes functions so that you can't try to get server functions on the client side, or client functions on the server side. Weird. In the following code, it outputs everything for .var1 but nothing for .Test ._. addEvent("TestEvent"); CreateTest = function() local Public = {}; local Private = {}; Private.String = "Hello world!"; Public.Test = function() outputDebugString(Private.String); end Public.var1 = "Hello" HandleTest(Public); triggerEvent("TestEvent", root, Public ); return Public; end HandleTest = function(Public) Public.Test(); -- Works. end addEventHandler( "TestEvent", root, function(Public) for i, v in pairs ( Public ) do outputChatBox ( tostring ( i ) .. " -> "..tostring ( v ) .. " -> ".. type ( v ) ) end end ); Test = CreateTest(); Test.Test(); -- Works. Link to comment
arezu Posted July 9, 2014 Share Posted July 9, 2014 triggerEvent creates a copy of provided tables since triggerEvent is meant to be used to trigger remote resources, or mta team has chosen this behavior when triggering inside the same resource to make behavior consistent. Since a copy of table is used, and triggerEvent is mostly used for remote resource, function pointers would no longer be valid as they point to a function that doesn't exist in the other resource; and therefore they are set to nil (removed from the table). There is an undocumented mta function to get an unique number that represents tables which you could pass along in triggerEvent, but I think it only works for global tables. A better solution is to have a table where you add each instance of your classes and store them under the tostring value of the table, like: instances[tostring(Public)] = public and you can then pass that string with the triggerEvent, and in the event you could have a function that loops instances table to get the class instance from string (you can override triggerEvent and addEventHandler to do it automatically). Btw, your class system will create new functions for each instance of the class you create with the system like that, you should look up "metatables" on some lua tutorial on how to make a "proper" class system. Link to comment
MTA Team botder Posted July 9, 2014 MTA Team Share Posted July 9, 2014 You could also try to go trough the table and dump each function: string.dump(function) In the event handler simply use loadstring(dumpString) to get the function. I am not sure if this will work, but try something like this: local myDump = string.dump(function () return Public end) Link to comment
SkittlesAreFalling Posted July 10, 2014 Author Share Posted July 10, 2014 Thanks Necktrox <3 and thank you arezu for explaining why functions don't get passed the event system. Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now