vicisdev Posted January 5, 2020 Share Posted January 5, 2020 (edited) I have a shared script that stores a parameter provided function into a table: -- shared_script.Lua local my_table = {} function addFunctionality(key, handler) my_table[key] = handler end The point is that it's stored two different tables - client and server side. When addFunctionality is called from a client script the handler is stored only inside the respective side table. What I need is a way to communicate between both client and server to store the handler in both tables independently of who is calling addFunctionality. The tables need to be synced and have the same data. I know there are functions server/client only, but forget that for now. For the purpose of this help bear in mind I'm trying to store this function: function() return true end But from the point of view of addFunctionality you never know how handler's implementation looks like. I've already tried to: - Use events, but they do not accept functions as arguments - Store the table in the root element, but it's not possible at all - Use loadstring, but 1) I don't know how handler's implementation looks like and 2) it doesn't return values Thanks Edited January 5, 2020 by vicisdev Link to comment
Scripting Moderators ds1-e Posted January 5, 2020 Scripting Moderators Share Posted January 5, 2020 11 minutes ago, vicisdev said: I have a shared script that stores a parameter provided function into a table: -- shared_script.Lua local my_table = {} function addFunctionality(key, handler) my_table[key] = handler end The point is that it's stored two different tables - client and server side. When addFunctionality is called from a client script the handler is stored only inside the respective side table. What I need is a way to communicate between both client and server to store the handler in both tables independently of who is calling addFunctionality. The tables need to be synced and have the same data. I know there are functions server/client only, but forget that for now. For the purpose of this help bear in mind I'm trying to store this function: function() return true end But from the point of view of addFunctionality you never know how handler's implementation looks like. I've already tried to: - Use events, but they do not accept functions as arguments - Store the table in the root element, but it's not possible at all - Use loadstring, but 1) I don't know how handler's implementation looks like and 2) it doesn't return values Thanks You can pass tables in triggerClientEvent/triggerServerEvent as argument. 1 Link to comment
vicisdev Posted January 5, 2020 Author Share Posted January 5, 2020 Just now, majqq said: You can pass tables in triggerClientEvent/triggerServerEvent as argument. I'll try it. But I have almost sure the entries are going to be nil ... let me see and I'll give feedback Link to comment
Scripting Moderators ds1-e Posted January 5, 2020 Scripting Moderators Share Posted January 5, 2020 1 minute ago, vicisdev said: I'll try it. But I have almost sure the entries are going to be nil ... let me see and I'll give feedback Why? I'm using tables n triggers since past year, and everything works well :) 1 Link to comment
vicisdev Posted January 5, 2020 Author Share Posted January 5, 2020 Just now, majqq said: Why? I'm using tables n triggers since past year, and everything works well :) Idk really ... I've tried to store the table full of functions in the root element with setElementData and all entries gone nil, so maybe functions are not synceable ... idk :p Link to comment
Moderators Patrick Posted January 5, 2020 Moderators Share Posted January 5, 2020 (edited) Try to sync table, something like this: -- SHARED local thisIsClientSide = isElement(localPlayer) -- it returns true if script running on client side and localPlayer defined local t = {} function f(i, v) print((thisIsClientSide and "Client:" or "Server:").." f => i:"..i..", v:"..v) -- debug t[i] = v -- send sync to different side if not source then -- if source is exists, don't need to send back to different side, because we got it from there (otherwise we would make a loop) if thisIsClientSide then triggerServerEvent("f:sync", resourceRoot, i, v) else triggerClientEvent("f:sync", resourceRoot, i, v) end end end addEvent("f:sync", true) addEventHandler("f:sync", root, f) Edited January 5, 2020 by stPatrick 1 Link to comment
vicisdev Posted January 5, 2020 Author Share Posted January 5, 2020 43 minutes ago, stPatrick said: Try to sync table, something like this: 56 minutes ago, majqq said: Why? I'm using tables n triggers since past year, and everything works well Yeah guys ... it sadly doesn't work -- shared_script.Lua addEventHandler("onPlayerJoin", root, function() local server_table = { function() return true end, function() outputChatBox("ANOTHER FUNCTION") return false end, "sadsad" } for k, v in pairs(server_table) do triggerClientEvent("r", source, k, v) end end) addEvent("r", true) addEventHandler("r", root, function(i, v) outputChatBox("RECEIVED > " .. inspect(i) .. " > " .. inspect(v)) end) https://i.imgur.com/E5TV6dS.png (i cant insert images ,_, ) Link to comment
Moderators Patrick Posted January 5, 2020 Moderators Share Posted January 5, 2020 3 minutes ago, vicisdev said: Yeah guys ... it sadly doesn't work -- shared_script.Lua addEventHandler("onPlayerJoin", root, function() local server_table = { function() return true end, function() outputChatBox("ANOTHER FUNCTION") return false end, "sadsad" } for k, v in pairs(server_table) do triggerClientEvent("r", source, k, v) end end) addEvent("r", true) addEventHandler("r", root, function(i, v) outputChatBox("RECEIVED > " .. inspect(i) .. " > " .. inspect(v)) end) https://i.imgur.com/E5TV6dS.png (i cant insert images ,_, ) But why you want to share functions? 1 Link to comment
vicisdev Posted January 5, 2020 Author Share Posted January 5, 2020 1 minute ago, stPatrick said: But why you want to share functions? I'm making a key binding api for my server, but I'll need to change the approach I guess I would really like to know what @IIYAMA has to say about this Link to comment
Moderators Patrick Posted January 5, 2020 Moderators Share Posted January 5, 2020 addEventHandler("onPlayerJoin", root, function() local server_table = { 'function() return true end', 'function() outputChatBox("ANOTHER FUNCTION") return false end', } for k, v in pairs(server_table) do triggerClientEvent("r", source, k, v) end end) addEvent("r", true) addEventHandler("r", root, function(i, v) outputChatBox("RECEIVED > " .. i .. " > " .. v) -- load local func, err = loadstring("return "..v) local results = {pcall(func)} -- call local func_results = {results[2]()} outputChatBox(inspect(func_results)) end) 1 Link to comment
vicisdev Posted January 5, 2020 Author Share Posted January 5, 2020 23 minutes ago, stPatrick said: addEventHandler("onPlayerJoin", root, function() local server_table = { 'function() return true end', 'function() outputChatBox("ANOTHER FUNCTION") return false end', } for k, v in pairs(server_table) do triggerClientEvent("r", source, k, v) end end) addEvent("r", true) addEventHandler("r", root, function(i, v) outputChatBox("RECEIVED > " .. i .. " > " .. v) -- load local func, err = loadstring("return "..v) local results = {pcall(func)} -- call local func_results = {results[2]()} outputChatBox(inspect(func_results)) end) Ooh, great solution, actually. I've read loadstring doesn't return values, I was wrong. I'll need to change some implementations, but this is fine, thank you! Link to comment
Moderators IIYAMA Posted January 5, 2020 Moderators Share Posted January 5, 2020 2 hours ago, vicisdev said: I would really like to know what @IIYAMA has to say about this It seems everything is fine. You can't send loaded functions to the other side, because they are bound they their environment. The file and every variable around the function is part of the environment. If you actually could transfer functions, then Lua would also copy all other variables to the other side, in fact the entire Lua file. That would be catastrophic. local test1, test2 function test1 () local testValue = "test" function test2 () print(testValue) end end test1() I would recommend to use 3 files instead. 1 shared with all the functions inside of a table allStuff = { doThis = function () end, doThat = function () end, dontDoThat = function () end } 1 clientside function handlerFunction (key, ...) allStuff[key](...) -- client stuff end 1 serverside function handlerFunction (key, ...) allStuff[key](...) -- server stuff end etc. 1 Link to comment
vicisdev Posted January 6, 2020 Author Share Posted January 6, 2020 16 hours ago, IIYAMA said: I would recommend to use 3 files instead. Yeah, but the main thing is adding new entries programatically which leads to server/client only insertions. It would be magic if I could force a shared environment when calling a function so the api knows "ok this has to be added here and there" just like what happens when you manually, directly, make calls or insert data on a shared file. There is a way to extract a loaded function's implementation so you get its string? If so ... maaan, revolutionary! 1 Link to comment
Moderators IIYAMA Posted January 6, 2020 Moderators Share Posted January 6, 2020 30 minutes ago, vicisdev said: There is a way to extract a loaded function's implementation so you get its string? If so ... maaan, revolutionary! Not that I know of, but you can change the order. So instead of starting with a function, you could start with a multiline string. thisString = [[ function getName () end ]] Link to comment
vicisdev Posted January 6, 2020 Author Share Posted January 6, 2020 1 hour ago, IIYAMA said: Not that I know of, but you can change the order. So instead of starting with a function, you could start with a multiline string. thisString = [[ function getName () end ]] Yeah, this is the approach I'm following now. Where can I share it when it's finished, like a showcase and stuff? Link to comment
Moderators IIYAMA Posted January 6, 2020 Moderators Share Posted January 6, 2020 2 hours ago, vicisdev said: Yeah, this is the approach I'm following now. Where can I share it when it's finished, like a showcase and stuff? Here: https://forum.multitheftauto.com/forum/87-resources/ 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