Phodex Games Posted March 10, 2018 Share Posted March 10, 2018 Hi Leadwerkers :), I am wondering for quiet a while now, if and how the two things, I will explain in a second, are possible. First can I grab the "self" value of an function caller WITHOUT using arguments? I would expect this to work with the lua debug.getinfo() functionality? Maybe I better explain it with pseudo code: --Script 1: function Script:Test() Script2:CallingThis() end --Script 2: function Script:CallingThis() --get self of caller end Btw I have no idea how you offically call a "caller" maybe its calle? I dont know Second how to grab an arguments root variable. What I am already aware of is accessing variables like this self["myVariable"] so I could send self as argument 1 and "myVariable" as string in argument 2, but I am looking for a way to prevent this to optimize the code and lower the error rate. Again some pseudo code: --Script 1: Script.myVariable = 10 function Script:Test() Script2:CallingWithArgument(self.myVariable) end --Script 2: function Script:CallingThis(argument) --if I do anything with the variable argument here it only changes the local "argument" variable of course --this is stupid but I guess it will explain what I mean: local rootVariable = argument:GetRoot() rootVariable = 20 --> myVariable is changed to 20 within the Script 1 end You would do me a great favor if you would give me some input on this. I would be able to improve my code even more Thanks in advance for answering and have a nice day Quote Link to comment Share on other sites More sharing options...
AggrorJorn Posted March 10, 2018 Share Posted March 10, 2018 Interesting questions. I don't know if there is a variable in existence that gets you the callers 'self'. But maybe there is something hidden in the lua meta tables that can do this. As for getting the root there are probably neat little tricks you can do here, but not without the use of tables. Maybe this way: --variable is a table Script.myVar = { ["root"] = self, ["value"] = 10 } Function Script:Test1() self:Test2(self.myVar) end Function Script:Test2(myVar) myVar.root myVar.value end Or make a new class object called Variable were you store the above table in. There are probably prettier ways, but I never dug that deep in to lua meta tables. Quote Link to comment Share on other sites More sharing options...
Phodex Games Posted March 10, 2018 Author Share Posted March 10, 2018 Hmm ok thats not a bad idea to store this data directly inside the variable, but to make this work for every variable I would have to change the whole variable management, short, would need to change all variables, which would be a damn lot of work :D. Yeah I am not much into metatable as well, but I guess it would be a good idea to learn more... Thanks anyway, so for the moment I need to send this data as an argument, just searched for a way to do this automated. Quote Link to comment Share on other sites More sharing options...
Josh Posted March 10, 2018 Share Posted March 10, 2018 You can just pass self as an argument: --Script 1: function Script:Test() Script2:CallingThis(self) end --Script 2: function Script:CallingThis(otherthing) local caller = otherthing end Example: --Script 1: Script.myVariable = 10 function Script:Test() Script2:CallingWithArgument(self) end --Script 2: function Script:CallingWithArgument(caller) caller.myVariable = 20 --> myVariable is changed to 20 within the Script 1 end Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Rick Posted March 10, 2018 Share Posted March 10, 2018 I think he's saying he doesn't know what the variable name of the object actually is while inside the function that changes it so he can't hardcode that in the function that's changing the variable. To me it seems like he's asking how to pass primitive variables by reference (or a pointer to them) so when the value is changed it's seen outside of the function call. Josh, the example you have I'm not following. Where is CallingWithArgument() defined? How is doing caller.rootVariable = 20 changing script 1's myVariable? OP: Tables are passed by reference but primitives aren't. The deeper question is why are you thinking you need this? Perhaps there is a different way that isn't so hacky or confusing to anyone reading your code. Quote Link to comment Share on other sites More sharing options...
Josh Posted March 10, 2018 Share Posted March 10, 2018 4 minutes ago, Rick said: Josh, the example you have I'm not following. Where is CallingWithArgument() defined? How is doing caller.rootVariable = 20 changing script 1's myVariable? Fixed. Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Rick Posted March 10, 2018 Share Posted March 10, 2018 Yeah, see he's saying in script 2's function he doesn't know the name of the variable in script 1. To build off Aggror's here's a way to do it by wrapping all primitives in a table. If plugged into here you can see it work: https://www.lua.org/cgi-bin/demo You can do a set/get idea which might make it more readable and understandable Variable = {} function Variable:create(value) local obj = {} obj.value = value for k,v in pairs(Variable) do obj[k] = v end return obj end function Variable:set(value) self.value = value end function Variable:get() return self.value end function ChangeMe(v) v:set(20) end local v1 = Variable:create(10) print(v1:get()) ChangeMe(v1) print(v1:get()) I'll see if there is a way to not have to say .value. You might be able to just make v = 20 and have it translate to v.value somehow with meta stuff lua has. That way it would simulate like it's a primitive value instead of a table. Quote Link to comment Share on other sites More sharing options...
Phodex Games Posted March 10, 2018 Author Share Posted March 10, 2018 First of all thanks for your input. 1 hour ago, Rick said: The deeper question is why are you thinking you need this? Well actually its just to make my code more error proof & simple. I would like to turn something like this: --Example Case --Script1 Script.health = 100 function Script:SomeFunction() Script2:IncreaseHealth(self, 10) end --Script2 function Script:ChangeMyVariable(target, healthAdd) target.health = callerSelf.health + healthAdd end Into this: --Example Case --Script1 Script.health = 100 function Script:SomeFunction() Script2:IncreaseHealth(10) end --Script2 function Script:ChangeMyVariable(healthAdd) --automatically get callerSelf here callerSelf.health = callerSelf.health + healthAdd end I am just asking because I though there may be an easy way of doing this, as debug.getinfo(2).name for example does print the function callers name. So can't you access the self of the caller function with this? All this is just for the sake of improving my code, it is not nessecary in the way of building a mechanic out of it. @Rick I already have such a Get/Set mechanic, for checking if an variable got changed since the last check, but I would not like to move all my variable management over to this system, I just use it for specific variables. However I guess I would be a good idea to do this longterm... Quote Link to comment Share on other sites More sharing options...
Rick Posted March 10, 2018 Share Posted March 10, 2018 In that specific example you might want to think about reversing the flow. Have script2 call script1's IncreaseHealth(10) so that script1 can just increase it's health variable vs the reverse way you have it. The object that owns the variable should really be the thing that controls it directly (encapsulation those variables in the object instead of exposing them for others to change). Functions can be created on that object that other things can call if they want to ultimately manipulate it. Think of these functions as the API to said object. You'll generally have less confusion and easier debugging if said variable is only ever changed in 1 spot (the object member function) vs exposed all over the place being changed by who knows what. I know what you have is just an example an maybe you have some bigger system behind the scenes here but all I can go off is the example and seeing that example I'd reverse how you're doing it. Quote Link to comment Share on other sites More sharing options...
Phodex Games Posted March 10, 2018 Author Share Posted March 10, 2018 26 minutes ago, Rick said: I know what you have is just an example an maybe you have some bigger system behind the scenes here Exactly, I have multiple systems which would have an advantage of this. For example I have a global character commands class giving my player & my AI access to all actions they need. This makes sense so as I want to change a mechanic I do not have to maintain this for both the AI & the player. As it is global (and I want it to be global so that you do not need to initiate it for any script (I initiate it in the main) and can call it from everywhere) I created a client management system that allows my command class to exectue its actions on as many entites as I desire, but I need to send the self "table" as an argument for every command, so the commands class knows on which entity the command should be executed, and this is what I would like to overcome. Eitherway I think having the functionality I explained would be a cool tool for creating systems... Quote Link to comment Share on other sites More sharing options...
Josh Posted March 10, 2018 Share Posted March 10, 2018 I would check to see if the value you are looking for exists and then modify it if it does. My own scripts do this all the time: function Script:ChangeMyVariable(object) if type(object.health)=="number" then object.health = object.health + healthAdd end end I would say this is my official recommended technique of doing stuff like this. 1 Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Crazycarpet Posted March 10, 2018 Share Posted March 10, 2018 Good sir, healthAdd is nil 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.