PDA

View Full Version : How to reference 'self' in Lua?



Hamish
June 23rd, 2007, 22:11
Can anyone tell me how to reference the control that the running script is tied to? Let me explain:
I'm building a template, and I want to add a bit of script to it. In this script I need to get some properties (like size and position) of the current control. But since I define the script in the template, I can't reference the control by name, but need something like Me (in Visual Basic) or self (in HTML). Is this possible?

Hamish

Toadwart
June 23rd, 2007, 22:32
Err, I think you answered your own question: "self" is the way to do it

refer to the "The self and super variables" section for Templates in the reference library:
https://www.fantasygrounds.com/modguide/templates.xcp

Hamish
June 24th, 2007, 07:11
Okay.... thought it had to be something like that... but it's not working. What am I doing wrong here:



function onInit()
Test()
end

function Test()
local x, y = self.getPosition()
print(y)
end


I've got a list of controls based on the same template, and the display in a column very nicely. But the according to my function y=0 for each of them. It looks like self references the window all controls are in, or something like that, but not the control itself.

Dachannien
June 24th, 2007, 07:51
Does it also give you the wrong answer for x?

Hamish
June 24th, 2007, 09:28
Yes it does. Zeros all around.

Toadwart
June 24th, 2007, 20:31
Hmm, is your template based on a standard control (like stringfield) or is it a template based on another template?

I'm not completely familiar with the self/super stuff but I think you'd only need to use it if you were creating a template that inherits from another template. You should also have direct access to the inherited functions unless you overrode them (i.e. created a function with the same name in your template)

try



function onInit()
Test();
end

function Test()
print(getName());
local x, y = getPosition();
print(y);
end

Hamish
June 24th, 2007, 20:50
Tried that, still nothing, getName doesn't return anything either.

My template is basically a windowreferencecontrol with some default values set, and a bit of scripting added.

Toadwart
June 24th, 2007, 21:25
My bad. I think getName() is a databasenode function so would need to be getDatabaseNode().getName() or self.getDatabaseNode().getName()

I shouldn't try to answer this while I'm at work, for various reasons (the most important being that I can't actually test it ;))

If you can post your template xml I'll try and take a look at it after work.

Dachannien
June 24th, 2007, 21:28
Here's a thought: You're invoking the function from within onInit, which means that the object hasn't been initialized yet. Perhaps the object's position is not yet defined.

Hamish
June 24th, 2007, 21:30
Using self.getDatabaseNode().getName() or getDatabaseNode().getName() results in an error:

Script Error: [string "charsheet_progress:<unnamed>"]:1: attempt to index a nil value

Hamish
June 24th, 2007, 21:32
Here's a thought: You're invoking the function from within onInit, which means that the object hasn't been initialized yet. Perhaps the object's position is not yet defined.

Now that sounds like a probable cause.... any thoughts on how to solve this? I need to code to run as soon as the control is created, because it sets the control to be invisible in some cases.

Toadwart
June 24th, 2007, 21:57
What control is your template inheriting from?
If its stringcontrol or numbercontrol then try stringfield or numberfield instead. The only diff between stringcontrol and stringfield is that stringcontrol does not save itself to the database. Possibly why getDatabaseNode() is nil...

Hamish
June 25th, 2007, 06:19
It's a windowreferencecontrol actually..... Maybe I just want something impossible, I'll think about another way to do what I want.

Toadwart
June 25th, 2007, 07:09
Now that sounds like a probable cause.... any thoughts on how to solve this? I need to code to run as soon as the control is created, because it sets the control to be invisible in some cases.

Dachannien was right on the money there. getPosition returns 0 during the onInit but returns actal values after the control has been created (e.g. in the onHover event)

Tried a few things (putting the script in a control that is created after the one we are trying to modify, or against the windowclass itself) but nothing worked.
Using onHover is the best I can come up with at the moment. Probably won't do what you need but might spark another idea:


local triggered = false;

function Test()
local x, y = getPosition();
print(x);
print(y);
setVisible(false);
end

function onHover(state)
Test();
end

Dachannien
June 25th, 2007, 07:19
Not sure if it works this way, but when the window's position is set for the first time, it might trigger an onMove event (https://www.fantasygrounds.com/refdoc/windowinstance.xcp#onMove), so you could register a handler function for onMove as part of your onInit.

I don't know whether that particular event handler is called if, say, you move the sheet that it's part of (thereby changing its position relative to the application window), but you'd probably want to be careful about that, just in case.

joshuha
June 25th, 2007, 14:29
Another possibility is storing a trigger flag in the database and creating on onUpdate event handler for that node. Due to the slight delay in writing to the DB this should not get triggered till after the control has been initialized. At least in theory.

Dachannien
June 25th, 2007, 14:34
Hehe, reminds me of the stories of optimizing code on old drum core computers ;)

Hamish
June 25th, 2007, 19:14
Thanks everyone for the suggestions, but I've decided to take a completely new approach to the functionality I wanted to add. So I won't need this particular piece of code anymore. But I've read all your replies with interest, I keep learning all the time. :)