DICE PACKS BUNDLE
Page 1 of 2 12 Last
  1. #1
    Minty23185Fresh's Avatar
    Join Date
    Dec 2015
    Location
    Goldstone, CA, USA
    Posts
    1,211
    Blog Entries
    29

    Getting a handle to the <script> in a <windowclass> (or other xml)

    Let me preface with, "Sorry if I don't use the proper terminology here. Hopefully, despite my ignorance, readers of this thread will understand what I am referring to and will be able to help me."

    How do I get at the lua that has been defined using <script> within XML, other than the <root> of the ruleset base.xml?
    An example should help.

    In the 5E base.xml file is the script definition:
    Code:
       <script name="PowerManager" file="scripts/manager_power.lua" />
    The contents of manager_power.lua have a name, so I can replace a function in it with a function of my own, like this:
    Code:
       PowerManager.rulesetFunction = myExtensionFunction;
    However, lua script referred to or defined within say, windowclasses, doesn't have a name, so I can't replace it in the same manner. For example, in the record_power.xml file is this windowclass definition
    Code:
       <windowclass name="power_page">
          <margins control="0,0,0,2" />
          <script file="campaign/scripts/power_page.lua" />
          <sheetdata>
             <anchor_column name="columnanchor" />
             <list_powers name="powers" />
          </sheetdata>
       </windowclass>
    Note the script file has no associated name, by which to refer to it.

    Now I could just replace the whole file with my own, by doing something like this in my extension:
    Code:
       <windowclass name="power_page" merge="join">
          <script merge="delete" />
          <script file="campaign/scripts/toms_super_power_page.lua" />
      </windowclass>
    But replacing the entire file with mostly duplicated code is, well, not very palatable. Actually I find it repulsive!

    I've tried naming the file within the xml, like this:
    Code:
       <windowclass name="power_page" merge="join">
          <!-- give the script file a name, so I can augment it, as needed -->
          <script merge="delete" />
          <script name="PowerPageMgr" file="campaign/scripts/power_page.lua" />
       </windowclass>
    But the name seems to be out of scope for the rest of the code because I get this error in the console:
    Code:
    Runtime Notice: Host session started
    Script Error: [string "campaign/scripts/my.lua"]:18: attempt to index global 'PowerPageMgr' (a nil value)
    I've looked at "Interface" hoping to find functionality that would allow me to get a handle to PowerPageMgr but I can't find one, unless I missed it.

    Any suggestions? Thanks in advance.
    Current Projects:
    Always...
    Community Contributions:
    Extensions: Bardic Inspiration, Druid Wild Shapes, Local Dice Tower, Library Field Filters
    Tutorial Blog Series: "A Neophyte Tackles (coding) the FG Extension".

  2. #2
    Minty23185Fresh's Avatar
    Join Date
    Dec 2015
    Location
    Goldstone, CA, USA
    Posts
    1,211
    Blog Entries
    29
    Oh yes, I have done this too, but it also can be cumbersome.

    Code:
    <windowclass name="power_page" merge="join">
        <script merge="join" />
        <script>
            function myFirst()
               ...
            end
            function mySecond()
               ...
            end
          </script>
    </windowclass>
    This too leaves a bit to be desired though. especially for lengthy additions.

  3. #3
    Because the script file of each defined script tag is instantiated (i.e. a copy is made) each time a window or control is opened, you can not reference any window or control by a global reference (because they are each unique).

    Therefore, the way to override window class scripts is exactly how you are doing it. Write a new window class definition with a merge="join" attribute and a new script tag.

    If you leave off the script merge="delete" attribute in your new window class definitions, you could access the old script using the "super" variable. This may allow you to override only small portions of the script, instead of the whole thing. At least, this is how it should work in theory, though I don't think we have any implementations that actually use this much finesse. They usually just override the whole script.

    Regards,
    JPG

  4. #4
    Trenloe's Avatar
    Join Date
    May 2011
    Location
    Colorado, USA
    Posts
    33,407
    Short answer - you can't replace script files used directly in a windowclass with code like you can for global packages.

    The reason being is that the code is assigned to the instance of the windowclass when it is created, not when the ruleset first loads. And you can have multiple instances of the window, each with their own code instance. You could mess around with the onInit function to override code, but then you're still having to make some changes to the base script .lua file and include the whole of that LUA file - so it defeats the purpose.
    Private Messages: My inbox is forever filling up with PMs. Please don't send me PMs unless they are actually private/personal messages. General FG questions should be asked in the forums - don't be afraid, the FG community don't bite and you're giving everyone the chance to respond and learn!

  5. #5
    Minty23185Fresh's Avatar
    Join Date
    Dec 2015
    Location
    Goldstone, CA, USA
    Posts
    1,211
    Blog Entries
    29
    Quote Originally Posted by Trenloe View Post
    Short answer - you can't replace script files used directly in a windowclass with code like you can for global packages.
    Arrgh! That is exactly what I was hoping I would not hear! Waaaaah!! (Wimper, wimper.)

    Thanks Trenloe.

  6. #6
    Minty23185Fresh's Avatar
    Join Date
    Dec 2015
    Location
    Goldstone, CA, USA
    Posts
    1,211
    Blog Entries
    29
    'kaySo. a follow up please.

    I am working with:

    <windowclass name="power_page"> in 5E\campaign\record_power.xml
    function getWindowSortByNode() in 5E\campaign\scripts\power_page.lua

    <windowclass name="power_group_header"> in 5E\campaign\record_power.xml
    function setHeaderCategory() in 5E\campaign\scripts\power_group.lua

    I have tried to brute force replace the functions by doing this in my extension's record_power.xml
    Code:
      <windowclass name="power_page" merge="join">
        <script merge="join">
          function getWindowSortByNode(node)
            Debug.console("my getWindowSortByNode()", "arrived");
            ...
          end
        </script>
      </windowclass>
    
      <windowclass name="power_group_header" merge="join">
        <script  merge="join">
          function setHeaderCategory(rGroup, sGroup, nLevel, bAllowDelete)
            Debug.console("my setHeaderCategory()", "arrived");
            ...
          end
        </script>
      </windowclass>
    The ... in the code represents the copied script from the corresponding .lua file functions plus my modifications. There are similar Debug statements stating "ruleset" instead of "my" in the original ruleset .lua files.

    When I run FG, create a character, and add a spell to the Actions tab on the Character sheet, it triggers the script.

    The replacement script is being executed for the setHeaderCategory() function but not for the getWindowSortByNode() function. I can tell from the results in the console. "my" shows up for the setHeaderCatgory() but "ruleset" shows up for getWindowSortByNode().

    To me this indicates that the ruleset setHeaderCategory() function is being replaced by my script but the getWindowSortByNode() function is not being replaced. Even though the same methodology is being used.

    My question is this: there are a lot of DB add handlers being added in the onInit() of power_page.lua. Could that "lock in" the getWindowSortByNode() function into memory so that my extension cannot replace it? I.e the objects, tables and functions are all in place and therefore not modifiable by the time my extension comes into play?

    Thanks for the help.

  7. #7
    I have no idea why without looking at your extension.

    Cheers,
    JPG

  8. #8
    Minty23185Fresh's Avatar
    Join Date
    Dec 2015
    Location
    Goldstone, CA, USA
    Posts
    1,211
    Blog Entries
    29
    Yikes. That makes me believe one of two things happened:
    I either lied to you or I have an error in my code.
    I'll triple check that neither is true.
    Thanks for your time.

  9. #9
    Minty23185Fresh's Avatar
    Join Date
    Dec 2015
    Location
    Goldstone, CA, USA
    Posts
    1,211
    Blog Entries
    29
    It can't get any simpler than this... I striped everything out of my extension except for the offending functions.
    By starting over.

    The three ruleset files of interest are:
    5E\campaign\record_power.xml
    5E\campaign\scripts\power_group.lua
    5E\campaign\scripts\power_page.xml

    I created my extension file.
    Created the one xml file the extension.xml refers to ETE_record_power.xml.
    In that file I put my two windowclasses and the script substitutions.
    (The script is nothing more than the original ruleset lua, that way Fantasy Grounds functionality has not changed.)
    I added some Debug.console() statements to the two scripts.
    I ran Fantasy Grounds with the .pak ruleset files.
    Created a new campaign, included my "Enigma Test" extension. And brought up the console.
    I then created a new character, Human Cleric. Navigated to the Actions tab.
    The following was dumped to the console:
    Code:
    Runtime Notice: s'ETE | ETE_record_power.xml | power_group_header.setHeaderCategory() | status=' | s'arrived'
    Exactly as expected. Good my extension is working.
    Next I dragged a spell on to the Actions tab, and received this:
    Code:
    Runtime Notice: s'ETE | ETE_record_power.xml | power_group_header.setHeaderCategory() | status=' | s'arrived'
    Runtime Notice: s'ETE | ETE_record_power.xml | power_group_header.setHeaderCategory() | status=' | s'arrived'
    Wait! That's wrong. There should be a call to getWindowSortByNode() in there.

    To see if that function was being called at all I unpacked the 5E ruleset and added Debug.console() statements to the appropriate functions in the power_group.lua and power_test.lua files.
    I restarted FG and created a new character as before, went to the Actions tab, dragged a spell on, and then a second.
    Here's the display in the console:
    Code:
    Runtime Notice: s'ETE | ETE_record_power.xml | power_group_header.setHeaderCategory() | status=' | s'arrived'
    Runtime Notice: s'5E | power_page.lua | getWindowSortByNode() | status=' | s'arrived'
    Runtime Notice: s'ETE | ETE_record_power.xml | power_group_header.setHeaderCategory() | status=' | s'arrived'
    Runtime Notice: s'5E | power_page.lua | getWindowSortByNode() | status=' | s'arrived'
    Runtime Notice: s'ETE | ETE_record_power.xml | power_group_header.setHeaderCategory() | status=' | s'arrived'
    Runtime Notice: s'5E | power_page.lua | getWindowSortByNode() | status=' | s'arrived'
    Runtime Notice: s'ETE | ETE_record_power.xml | power_group_header.setHeaderCategory() | status=' | s'arrived'
    As mentioned in a previous post, note that the setHeaderCategory() in my extension is executing. But rather than my extension's getWindowSortByNode() function being run, the ruleset's copy is being executed. Both ruleset functions are "replaced" in the same manner in ETE_record_power.xml

    I have attached a zip file with all pertinent files: the campaign, the extension and the only two ruleset files I touched (Debug.console() added).

    If I've missed anything let me know.
    If I was to make a wager on this I'd bet Moon Wizard's and Trenloe's explanations, in posts 3 and 4 of this thread, about sum up this confounding behavior.
    Attached Files Attached Files
    Current Projects:
    Always...
    Community Contributions:
    Extensions: Bardic Inspiration, Druid Wild Shapes, Local Dice Tower, Library Field Filters
    Tutorial Blog Series: "A Neophyte Tackles (coding) the FG Extension".

  10. #10
    Minty23185Fresh's Avatar
    Join Date
    Dec 2015
    Location
    Goldstone, CA, USA
    Posts
    1,211
    Blog Entries
    29
    In addition to the testing in the above post #9, I did some more with +/- results.

    A file with two more extensions is attached.

    In Enigma 2, I copied the files power_page.xml and power_group.xml to my extension, rename them with "ETE2_" prefixes and changed the Debug.console() statements to indicate the ETE2 extension. I also copied record_power.xml to the extension, then edited out all the other windowclasses except for the pertinent two. I changed the <script></script> in each windowclass to refer to my two ETE2_ .lua files.

    ETE2 ran perfectly. (I don't like that much copied code, but.....)

    In Enigma 3 I copied the contents of Enigma 2. I edited the windowclasses to be join="merge" but still referring to my (renamed) ETE3_ .lua files. In the two lua files I removed everything but the two functions of interest. I also changed the Debug.console() statements to output "ETE3". What I was trying to accomplish here was essentially the same as in the previous post, except the replacement functions were in .lua files instead of in the windowclass <script> function.....end</script>.

    ETE3 performed the same as ETE 1. It failed to call the extension getWindowSortByNode() function, but did fine with the other function.

    BTW I tried the join="merge" a few different ways.
    in <windowclass> only, fails. In <windowclass> and in <script>, same failure.
    in <script> only fails catastrophically, all the other functions in power_page.lua and power_group.lua are gone.
    Attached Files Attached Files
    Last edited by Minty23185Fresh; October 3rd, 2017 at 16:58.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Starfinder Playlist

Log in

Log in