Bonsai Posted January 23, 2014 Author Share Posted January 23, 2014 That snippet of code is irrelevant. You talk about an issue on setfenv call but you show nothing about it. As I said, I'm doing it just like u did in your example, but with some script not only one command. local env = {} --env.all functions... function loadScript(file, dim) dimension = dim local file = fileOpen(file) local content = fileRead(file, fileGetSize(file)) local loaded = loadstring(content) setfenv(loaded, env) pcall(loaded) end _addEventHandler("onLoadScript", root, loadScript) Link to comment
ixjf Posted January 24, 2014 Share Posted January 24, 2014 Is that all of your code? Do you ever initialize your environment with required functions? Link to comment
Bonsai Posted January 24, 2014 Author Share Posted January 24, 2014 Is that all of your code? Do you ever initialize your environment with required functions? Yeah, thats this --env.all functions... I didn't write them all down here since I deleted that try after it didn't work. Link to comment
ixjf Posted January 24, 2014 Share Posted January 24, 2014 Can you send me all of the source code (either here or via PM, if you don't want to share it with everybody) so I can see what you're doing? Link to comment
Gallardo9944 Posted January 25, 2014 Share Posted January 25, 2014 @Bonsai, default environment is always empty and has no default functions. Try changing your env table to "local env = { outputChatBox = outputChatBox }" and run a script which has ONLY outputChatBox in it. It will work. Link to comment
Bonsai Posted January 25, 2014 Author Share Posted January 25, 2014 Can you send me all of the source code (either here or via PM, if you don't want to share it with everybody) so I can see what you're doing? @Bonsai, default environment is always empty and has no default functions. Try changing your env table to "local env = { outputChatBox = outputChatBox }" and run a script which has ONLY outputChatBox in it. It will work. Yeah, I know. I added all the function that are in that script like env.function. But it didn't work. I'll add this again and show it to u guys. Link to comment
Bonsai Posted January 26, 2014 Author Share Posted January 26, 2014 Alright, I tested loading a few different script. Turned out they all work, except the ones who contain eventHandlers. CommandHandlers or timers work fine, but eventHandlers are screwing it up. Works: env = {} env.setTimer = setTimer Doesn't: env = {} env.addEventHandler = addEventHandler Now, whats the problem here? EventHandler work fine when I'm not using setfenv. And of course I'm replacing the "onResourceStart" event. Bonsai Link to comment
ixjf Posted January 26, 2014 Share Posted January 26, 2014 I think you still didn't get what an environment is or how it works. Every function, every variable (except locals, which are stored somewhere else) is stored in the environment table. The default environment is _G. Whenever you call a function, Lua attempts to find it in the environment table - it is the same as _G["function_name"] ( ... ) or even _G.function_name ( ... ) (which is syntatic sugar). Locals are not stored in the environment, that's why using local variables is faster than using global ones - you avoid a lookup in the environment table, which may be very slow if it is big enough. When you set the environment in which a function will run, you're telling it to assume the environment is, e.g. your table env. Now, whenever it calls a function, instead of attempting to find the function in _G, it attempts to find it in env. env is empty, therefore it is going to fail. This is why it fails to load your code. root is a constant variable that contains the root element. It is the same as calling getRootElement, although faster since the value is already stored, you don't need to call the function over and over. I assume root is not defined in your environment table, and that's your problem. Link to comment
qaisjp Posted January 26, 2014 Share Posted January 26, 2014 Try using table.copy (env=table.copy(_G)), no need for a recursive copy. table.copy Link to comment
Bonsai Posted January 26, 2014 Author Share Posted January 26, 2014 But if locals are not stored in the new environment, they won't be deleted after you clear that table, right? Try using table.copy (env=table.copy(_G)), no need for a recursive copy. table.copy Okay, I'll try to do that. EDIT: It's working by copying the table, but clearing the table does not affect variables.. Link to comment
ixjf Posted January 27, 2014 Share Posted January 27, 2014 EDIT: It's working by copying the table, but clearing the table does not affect variables.. I cannot reproduce that - local variables stay in the scope of the function created by loadstring and shouldn't exist outside of it. Do you have some code that I can use to attempt to reproduce your issue? Try using table.copy (env=table.copy(_G)), no need for a recursive copy. table.copy Yes, this is an alternative, but the code loaded at env will be able to access functions that were defined in the default environment, and as such, it may call these functions and cause issues. Link to comment
Bonsai Posted January 27, 2014 Author Share Posted January 27, 2014 EDIT: It's working by copying the table, but clearing the table does not affect variables.. I cannot reproduce that - local variables stay in the scope of the function created by loadstring and shouldn't exist outside of it. Do you have some code that I can use to attempt to reproduce your issue? Try using table.copy (env=table.copy(_G)), no need for a recursive copy. table.copy Yes, this is an alternative, but the code loaded at env will be able to access functions that were defined in the default environment, and as such, it may call these functions and cause issues. I have a map that sets a variables after u hit a marker, to make u have to follow an order. But after map restart, that variable is still set so u can just go for the last marker. I'll send u that map. Link to comment
Bonsai Posted January 27, 2014 Author Share Posted January 27, 2014 Alright, I got it working now. Thanks to you guys. Link to comment
Gallardo9944 Posted January 28, 2014 Share Posted January 28, 2014 @Bonsai, so how did you solve the problem? Link to comment
Bonsai Posted January 28, 2014 Author Share Posted January 28, 2014 @Bonsai, so how did you solve the problem? After some testing, I'm not sure its solved at all. When I do this environment stuff and e.g. create an marker this happens: Script of a map contains if source == marker1 onClientMarkerHit Nothing happens. I checked the userdata of the source and marker1, and they are not equal, even though its the only marker being created. I don't understand how this happened.. Link to comment
Gallardo9944 Posted January 28, 2014 Share Posted January 28, 2014 i don't have issues with that though. Markers work as intended. Link to comment
Bonsai Posted January 29, 2014 Author Share Posted January 29, 2014 i don't have issues with that though. Markers work as intended. Ye, I found out its not the markers. Its the source. The source of that onClientMarkerHit event is always the local player. It's probably because the function that loads the script is triggered by an event and the source of that event is indeed the localPlayer. I've no idea how to get that right.. Link to comment
Saml1er Posted January 29, 2014 Share Posted January 29, 2014 Well you are loading code from a lua file, can't you just simply use brackets and send the data? I mean -- Client Sided local Bonsai = [[ -- Your code -- blah -- bah ]] addEventHandler("onResourceStart",getRootElement(), function () triggerServerEvent ("onSendCode", getLocalPlayer(), Bonsai ) end) -- Server Sided addEvent ("onSendCode", true ) addEventHandler ("onSendCode", getRootElement(), function(commandstring) local notReturned local commandFunction, errorMsg = loadstring("return "..commandstring) if errorMsg then notReturned = true commandFunction, errorMsg = loadstring(commandstring) end if errorMsg then outputDebugString(errorMsg); return end results = { pcall(commandFunction) } if not results[1] then return end if not notReturned then local resultsString = "" local first = true for i = 2, #results do if first then first = false else resultsString = resultsString..", " end local resultType = type(results[i]) if isElement(results[i]) then resultType = "element:"..getElementType(results[i]) end resultsString = resultsString..tostring(results[i]).." ["..resultType.."]" end outputDebugString(errorMsg); elseif not errorMsg then outputChatBox("See? It works", getRootElement(), 255, 255, 0, false ) end end) Link to comment
Gallardo9944 Posted January 29, 2014 Share Posted January 29, 2014 @Saml1er, would totally be the same. @Bonsai, in fact, you're getting userdata of 000001 (or similar) when using markers, right? That's root. You have to use rawget within the __index and specify source, root, resourceRoot, localPlayer, etc in the metatable. You have to return them in rawget if your key is "source", ... P.S. Thanks to Arezu for the way of fixing the issue. Link to comment
Bonsai Posted January 30, 2014 Author Share Posted January 30, 2014 At least it seems to be fixable. Even though I'm not sure how to do what you said there. Link to comment
Saml1er Posted January 30, 2014 Share Posted January 30, 2014 At least it seems to be fixable. Even though I'm not sure how to do what you said there. Are you talking about brackets? Link to comment
Bonsai Posted January 30, 2014 Author Share Posted January 30, 2014 Nooo, why or how would brackets work? I was talking about rawget. Link to comment
Saml1er Posted January 30, 2014 Share Posted January 30, 2014 Nooo, why or how would brackets work? I was talking about rawget. They do work. I saw this in sigmar lobby script. Link to comment
Gallardo9944 Posted January 30, 2014 Share Posted January 30, 2014 At least it seems to be fixable. Even though I'm not sure how to do what you said there. yes, it's fixable, I'll ask Arezu if I may share the way with you, and if yes - i'll give you the code. Link to comment
Bonsai Posted January 30, 2014 Author Share Posted January 30, 2014 At least it seems to be fixable. Even though I'm not sure how to do what you said there. yes, it's fixable, I'll ask Arezu if I may share the way with you, and if yes - i'll give you the code. Well thanks, but it's not too bad if he doesn't want to. I really want to understand how it works, especially what's causing the problem. 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