PDA

View Full Version : getValue() help



Bidmaron
November 5th, 2017, 11:09
I have the following control definition (PF ruleset):


<template name="button_export">
<button_text_sm>
<anchored to="buttonanchor" width="50">
<top />
<left anchor="right" relation="relative" offset="5" />
</anchored>
<state textres="export_button_templates" />
<!-- <script file="export_table_generator.lua" />-->
<script>
function onButtonPress()
Debug.chat("value=",getValue());
end
</script>
</button_text_sm>
</template>


When I press the button in the window itself, I get the following console error:

Script Error: [string "button_custom2"]:1: attempt to call global 'getValue' (a nil value)


What am I missing?

damned
November 5th, 2017, 12:59
what are you getting the value of?
i cant see any value to retrieve?

Bidmaron
November 5th, 2017, 13:40
damned, this is the script for the button I included the code for. That button uses a template that inherits directly from buttoncontrol. Here is an example of its use elsewhere in the CoreRPG 3.3.3 ruleset:


<button_iedit name="list_iedit">
<anchored>
<left anchor="center" offset="-10" />
<bottom offset="-27" />
</anchored>
<gmvisibleonly />
<script>
function onValueChanged()
local bEdit = (getValue() == 1);
window.list_iimport.setVisible(bEdit);
window.list_iadd.setVisible(bEdit);
window.list.update();
end
</script>
</button_iedit>

getValue is defined and should be in scope for anything that inherits from windowcontrol, which buttoncontrol does.

Bidmaron
November 5th, 2017, 22:36
Trenloe or MW OR Celestian maybe? What am I doing wrong? Is there a compatibility setting or something that needs to be in my extension (there is a ruleset note to that effect but doesn’t discuss extensions in the documentation for getValue.

Moon Wizard
November 5th, 2017, 23:39
Not sure without seeing all templates used to build up the control. Maybe post a link to files, or PM/email?

One clarification, getValue is not part of windowcontrol object. It is specifically part of stringcontrol, numbercontrol, buttoncontrol, windowreferencecontrol, and formattedtextcontrol. It does not exist in other window control types, such as genericcontrol or windowlist.

Regards,
JPG

Bidmaron
November 5th, 2017, 23:51
MW, attached is my complete xml file for all my controls. I can from the onButtonPress access getName, but I cannot get to anything associated with buttonControl, which the template I am invoking on my control inherits from. That is why I was wondering whether there was a compatibility problem as the buttonControl docs seem to indicate (v3.0 compatibility or higher).


<?xml version="1.0" encoding="iso-8859-1"?>

<!--
Template and interface materials for generators.
-->

<root>
<!-- Icon resources -->
<icon name="button_generators" file="button_generators.png" />
<!-- General -->
<template name="button_generators">
<button_text_sm>
<anchored to="buttonanchor" width="80">
<top />
<left anchor="right" relation="relative" offset="5" />
</anchored>
<state textres="generator_button_templates" />
<script>
function onButtonPress()
Interface.openWindow("masterindex", "generators");
end
</script>
</button_text_sm>
</template>
<template name="button_import">
<button_text_sm>
<anchored to="buttonanchor" width="50">
<top />
<left anchor="right" relation="relative" offset="5" />
</anchored>
<state textres="import_button_templates" />
<script file="import_table_generator.lua" />
</button_text_sm>
</template>
<template name="button_export">
<button_text_sm>
<anchored to="buttonanchor" width="50">
<top />
<left anchor="right" relation="relative" offset="5" />
</anchored>
<state textres="export_button_templates" />
<!-- <script file="export_table_generator.lua" />-->
<script>
function onButtonPress()
Debug.chat("in onButtonPress");
Debug.chat("name=",getName());
end
</script>
</button_text_sm>
</template>
<template name="line_button_export">
<buttoncontrol>
<anchored to="rightanchor">
<top />
<right anchor="left" relation="absolute" offset="-5" />
</anchored>
<anchored width="20" height="20" />
<icon normal="button_export" pressed="button_export_down" />
<tooltip textres="tabselect_tooltip_export" />
<script>
function onButtonPress()
TableManager.exportTabGen(window.getDatabaseNode() );
end
</script>
</buttoncontrol>
</template>
<!-- Window Declarations -->
<windowclass name="generator">
<frame>recordsheet</frame>
<placement>
<size width="400" height="400" />
</placement>
<sizelimits>
<minimum width="400" height="400" />
<dynamic />
</sizelimits>
<minimize>minimized_utility</minimize>
<nodelete />
<playercontrol />
<sharable />
<tooltip field="name" />
<script>
function onLockChanged()
if header.subwindow then
header.subwindow.update();
end
if main.subwindow then
main.subwindow.update();
end

local bReadOnly = WindowManager.getReadOnlyState(getDatabaseNode());
notes.setReadOnly(bReadOnly);
end
</script>
<sheetdata>
<sub_record_header name="header">
<class>table_header</class>
</sub_record_header>

<frame_record_content_tabbed name="contentframe" />

<subwindow_record name="main">
<class>table_main</class>
<script>
function onDrop(x, y, draginfo)
return subwindow.onDrop(x, y, draginfo);
end
</script>
</subwindow_record>
<ft_record name="notes">
<anchored to="contentframe">
<top />
<left offset="10" />
<right />
<bottom />
</anchored>
<empty textres="ft_empty" hidereadonly="true" />
<invisible />
</ft_record>

<scrollbar_record>
<target>main</target>
</scrollbar_record>
<scrollbar_record>
<target>notes</target>
</scrollbar_record>

<tabs_recordsheet>
<tab>
<icon>tab_main</icon>
<subwindow>main</subwindow>
</tab>
<tab>
<icon>tab_notes</icon>
<subwindow>notes</subwindow>
</tab>
</tabs_recordsheet>

<resize_recordsheet />
<close_recordsheet />
</sheetdata>
</windowclass>

</root>


The control where I cannot use getValue is buttonExport. Note the version above uses getName, which works, but getValue does not. Note that button_text_sm inherits directly from buttonControl, which SHOULD provide getValue.

Bidmaron
November 5th, 2017, 23:53
Also, note that the example I show from a built-in edit button clearly has getValue working, so something is amiss, and I cannot find anything on a compatibility flag, if that is the problem.

Moon Wizard
November 6th, 2017, 07:24
Looking at the button_export template, I don't see anything that stands out. (as long as button_text_sm template is not being overriden) Also, any scripts that have a getValue function will override the default getValue control function.

Can you send me an example extension where this is not working?
It will be the easiest way for me to dissect the issue.

Thanks,
JPG

lokiare
November 6th, 2017, 11:47
You might try:

self.getValue();
super.getValue();

https://www.fantasygrounds.com/wiki/index.php/Developer_Guide_-_Rulesets_-_Scripting#Script_Block_Scope

Bidmaron
November 6th, 2017, 12:49
Thanks, Iocaire, but what I am trying to convey is that this isn't an inheritance/override issue. This is an issue where calls to built-in stuff is not working. I think it may have something to do with the documentation for these calls (note what is in red), and that there is some kind of compatibility flag I need to set but cannot figure out how to do that.


getValue


function getValue( )
Note: Only available for rulesets with compatibility mode v3.0 or higher.

Retrieves the value of the control.

Return values

(number)
The value contained in the control

MW, that is not what is going on. Please see my complete extension attached.

Steps to recreate the problem:
1. Start up FG with only this extension loaded in a CoreRPG-based campaign.
2. Click the Tables sidebar icon.
3. Click the Generators button at top. This opens the Generators window.
4. Click the export button at top of Generators window. You will get a debug message in chat window showing the name of the export button control.
5. Edit the button_export template in the Generators.xml file under the onButtonPress event handler to say ' Debug.chat("value=",getValue());'
6. Reload ruleset and repeat steps 1-4. Now you will get the console error:

Runtime Notice: Reloading ruleset
Script Error: [string "button_custom2"]:1: attempt to call global 'getValue' (a nil value)


So, the getName call from windowcontrol works (inherited from buttoncotntrol through the button_text_sm template), but the getValue call from buttoncotntrol does not (inherited through the button_text_sm template declared in the CoreRPG ruleset file common\template_buttons.xml).

Trenloe
November 6th, 2017, 12:57
...some kind of compatibility flag I need to set but cannot figure out how to do that.
https://www.fantasygrounds.com/refdoc/ First line of "Ruleset Application Compatibility".

Bidmaron
November 6th, 2017, 13:03
https://www.fantasygrounds.com/refdoc/ First line of "Ruleset Application Compatibility".

The CoreRPG has this in its version:


<root version="3.0" release="3" logo="logo.png">


which I think should be okay for the calls I am using. Should I have the same version attribute in my extension.xml file? That should be documented more clearly if that is the case.

Note that the getValue call works in the code files in the ruleset but it does not work in codifies of my extension, as I have attempted to illustrate in my series of posts.

Bidmaron
November 6th, 2017, 13:11
Crud! Never mind!

I started my extension with a shell from one of my earlier extensions, and discovered that this shell had "version=2.8" in the root node. Once I fixed that to 3.0, the getValue call started working. Sorry for the fire drill.

THANKS FOR THE HELP, PROBLEM IS SOLVED.

Moon Wizard
November 6th, 2017, 17:40
I love problems that get solved while I'm sleeping. :)

All this is jogging my memory now. The compatibility flag for buttoncontrol.getValue calls was added, because some buttoncontrols in rulesets prior to v3.0 had their own getValue functions in custom scripts, and I believe buttoncontrols didn't have a built-in "value".

Cheers,
JPG

Bidmaron
November 6th, 2017, 21:50
Interesting background, MW. I wondered. Honestly, it is difficult to understand why windowcontrol doesn't have a getValue/setValue, as it seems a pretty fundamental concept to a base-level control (where it could be pure virtual in qindowcontrol).

Moon Wizard
November 6th, 2017, 22:35
Backward compatibility as always. There are many scripts genericcontrol templates written with getValue functions embedded, as people try to use similar naming to mimic behaviors. It happens a lot less now, because CoreRPG provides the pieces. However, always trying not to break old rulesets as much as possible.

Cheers,
JPG

Bidmaron
November 7th, 2017, 01:54
OK, I am trying to figure out how the code for the edit button in the standard record list window (e.g. tables or almost any sidebar-invoked record list) works. The edit button at bottom of the screen is defined in campaign_masterindex.xml as:


<button_iedit_campaign name="list_iedit" />

button_iedit_campaign is defined in template_campaign.xml as:


<template name="button_iedit_campaign">
<button_iedit name="list_iedit">
<anchored to="rightanchor">
<top />
<right anchor="left" relation="relative" offset="-5" />
</anchored>
<target>list</target>
</button_iedit>
</template>


This defines target to be the list control (more on that in a minute).
button_iedit is defined in the same file as:


<template name="button_iedit">
<buttoncontrol>
<anchored width="20" height="20" />
<state icon="button_edit" tooltipres="button_editon" />
<state icon="button_edit_down" tooltipres="button_editoff" />
<script>
function onInit()
if visible then
return;
end
local node = window.getDatabaseNode();
if not node or node.isReadOnly() then
setVisible(false);
end
end

function onValueChanged()
local sAdd = target[1] .. "_iadd";
if window[sAdd] then
window[sAdd].setVisible(getValue() == 1);
end
if window.onEditModeChanged then
window.onEditModeChanged(getValue() == 1);
end
window[target[1]].update();
end
</script>
</buttoncontrol>
</template>


Ah, now we are getting somewhere.... This has the code for the onValueChanged function of the edit button when you click it. To find the functions invoked inside that routine, we have to find out what the script file for the list window list control is. Okay, the list is defined in the sheet data of the master list windowclass in the file campaign_masterindex.xml as:


<masterindex_list name="list" />


masterindex_list is defined in template_campaign.xml as:


<template name="masterindex_list">
<windowlist name="list">
<anchored to="contentanchor">
<top anchor="bottom" relation="relative" offset="20" />
<left />
<right />
<bottom parent="bottomanchor" anchor="top" relation="relative" offset="-70" />
</anchored>
<frame name="groupbox" offset="15,15,20,15" />
<child></child>
<child><backcolor>1A40301E</backcolor></child>
<class>masterindexitem</class>
<allowdelete />
<useallmodules />
<skipempty />
<sortby><control>name</control></sortby>
<script file="campaign/scripts/masterindex_list.lua" />
</windowlist>
</template>


So, in here we find out that the script file for the list is in master index_list.lua. Great, but there is no update() function there. So, the question is, where is the update() function. Evidently there is some inheritance here I am just no grasping....

celestian
November 7th, 2017, 03:09
<script file="campaign/scripts/masterindex_list.lua" /> seems to have the .update() you're looking for?

Bidmaron
November 7th, 2017, 03:30
I have been back and forth through that file and used the search. What line number please?

celestian
November 7th, 2017, 03:33
I have been back and forth through that file and used the search. What line number please?

It's pretty small, is this not it?



--
-- Please see the license.html file included with this distribution for
-- attribution and copyright information.
--

function onMenuSelection(selection)
if selection == 5 then
window.addEntry(true);
end
end

function onListChanged()
window.onListChanged();
end

function onDrop(x, y, draginfo)
local vReturn = nil;
if draginfo.isType("shortcut") then
vReturn = CampaignDataManager.handleDrop(window.getRecordTyp e(), draginfo);
elseif draginfo.isType("file") then
vReturn = CampaignDataManager.handleFileDrop(window.getRecor dType(), draginfo);
end
return vReturn;
end

function update()
local bEditMode = (window[getName() .. "_iedit"].getValue() == 1);

for _,w in pairs(getWindows()) do
local node = w.getDatabaseNode();
if node then
if not node.isReadOnly() then
w.idelete.setVisibility(bEditMode);
else
w.idelete.setVisibility(false);
end
end
end
end

damned
November 7th, 2017, 03:48
BidMaron maybe you are looking in a ruleset file? Its in CoreRPG.

Bidmaron
November 7th, 2017, 03:51
Like I said, I knew I'd feel like an idiot. Every time I wanted to reference that file, I instead was looking at masterindex_window.lua. Thanks, Celestian.

celestian
November 7th, 2017, 03:51
BidMaron maybe you are looking in a ruleset file? Its in CoreRPG.

Good point! yes sorry that was where I found that .lua file. I thought he had said he was working in CoreRPG so that was my assumption. If not, woops!

Bidmaron
November 7th, 2017, 03:52
No, I was in CoreRPG, but wrong file.

celestian
November 7th, 2017, 03:55
No, I was in CoreRPG, but wrong file.

Ah, ok well glad you found it now ;) All it takes is a different pair of eyes at times. Happens a lot at work also. I'll get stuck and paste something and someone else will immediately see the cause.

Bidmaron
November 7th, 2017, 22:30
MW or whoever may know:
Is there anywhere that defines the characters that are legal in a record name. That is, when you click on a sidebar and add a data record of any sidebar-defined record type, what characters are legal in the record name? I am not aware this is defined anywhere, but there are probably several that would cause real problems (the xml-illegal characters immediately come to mind).

I ask because I need to write a lua search string for a table invocation, and the current table manager simply looks for any characters enclosed within square brackets, no matter what characters they are. This seems very unsafe, but I thought I'd check to see if there was a policy.

Nickademus
November 7th, 2017, 22:43
In my experience, FG converts xml-illegal characters to escapes. Though I haven't done extensive testing.

Bidmaron
November 7th, 2017, 22:51
Only where explicitly done in the code. Unless MW or Trenloe chimes in, I will just call it I suppose. For right now, I'm leaving it dangerous.

The other thing that wouldn't work well in the case of tables is anything that looked like a valid die expression. Now that I am working to include variables in tables and table names (as someone requested the other day), it becomes important to limit the characters that can be in a valid table name so as to make parsing simpler and less error-prone.

Currently, in keeping with the story templates' usage of <> delimited table names (where the last roll on the given table can be used with a <table name> kind of syntax), I am inclined to say that table names should not include '@' (to permit tables from a module to be used without confusing the module name as part of the table), any of the xml-illegals, and that they must start with a non-numeric and not include a plus sign. This still will cause confusion because d6-1 should probably be a die expression but could also be a valid table name (seems like a dash might be useful in a table name). Other illegal characters would be square brackets and angle brackets (which will be interpreted as a variable name).

Can anyone think of any other characters that should not be permitted?

Moon Wizard
November 7th, 2017, 23:02
If you have an invalid XML tag or invalid XMl data for a record in the raw XML and try to load it into the FG client, you will get an XML error and the XML will fail to load.

If you are entering data for a record through the UI, then the data characters are escaped as XML data.
If you are creating record fields through the API, then field names are escaped as XML tags.

Regards,
JPG

Bidmaron
November 7th, 2017, 23:06
Yes, but I am also allowing import of tables from an external source and need to guard against bad data. Would you be okay if I define a valid table name as anything starting with a letter and including any valid ascii character except xml escaped characters (why would anyone want to use any of them in a table name?), '@', square brackets, angle brackets (since one of them is technically okay in xml), and a colon (which I am using as a separator between the table name and sub-table name [this is to support importing of TableSmith tables]), and a '+' sign?

Moon Wizard
November 8th, 2017, 01:30
Those should all be fine. The FG client should handle any encoding once in the client. And any invalid XML won’t load.

Cheers,
JPG

Bidmaron
November 8th, 2017, 03:07
Thanks, MW