PDA

View Full Version : Accessing Superceded Ruleset Code



Minty23185Fresh
July 4th, 2016, 16:52
Is there a way to get access to the lua functions in a ruleset that have been superceded or supplanted by another ruleset and/or by an extension?

The EffectManager is a good example. The CoreRPG sets up an EffectManager in the <base> using:


<script name="EffectManager" file="scripts/manager_effect.lua" />


When the 5E ruleset loads, it does the same thing, thereby superceding the Core's EffectManager, with that of 5E's.

If my extension utilizes an EffectManager to add my own functionality to the EffectManager object, the extension supplants the 5E EffectManager.

Experimenting has led me to believe the superceded functions still exist in memory (or wherever). How can I get at them? Something like CoreRPG.EffectManager.AddEffect(...) or 5E.EffectManager.getEffectString(...) doesn't work, but would be marvelous!

Nickademus
July 4th, 2016, 17:06
Just copy/paste the function into your extension.

Minty23185Fresh
July 4th, 2016, 18:28
Just copy/paste the function into your extension.

Thank you. This I know. But not an acceptable solution when there are 50 functions to copy and be mindful of every time a new FG release comes out. The intent is to reduce duplicated code in my extension not increase it.

See this (https://www.fantasygrounds.com/forums/entry.php?171-A-Neophyte-Tackles-the-FG-Extension-Reducing-Copied-Ruleset-Script-Revisited).

Moon Wizard
July 4th, 2016, 19:18
You can't access replaced code in global scripts.

However, you can override a specific function in a global script from another global script. In the onInit function, you specify
"EffectManager.fnToReplace = fnNew"

Cheers,
JPG

Minty23185Fresh
July 5th, 2016, 17:11
However, you can override a specific function in a global script from another global script. In the onInit function, you specify
"EffectManager.fnToReplace = fnNew"

This is brilliant! Thanks, Moon Wizard.
Treating functions within objects as objects...!
<Minty>Doh!!!</Minty>

Going a step further, if fnToReplace() is particularly lengthy, a minor change is involved, and I didn't want to copy the lengthy function to my extension, I could use the same methodology to save it prior to replacement. Then call the saved function from the replacement:


function onInit()
fnEffManSaved = EffectManager.fnToReplace;
EffectManager.fnToReplace = fnNew;
end

-- the "guts" of this function replace the "guts" of fnToReplace
function fnNew()
-- the minor change
someGlobalVar = "my desired value";
-- call the original EffectManager function
ThisScriptObjectsName.fnEffManSaved();
end

function fnEffManSaved()
-- this stub of a function will contain the "guts" of the original EffectManager.fnToReplace
end


It looks a bit spaghetti-like, but it's not really that bad.

Moon Wizard
July 5th, 2016, 19:52
One of the nice things about Lua is that anything that looks like an object is usually just a table of functions and variables.

Cheers,
JPG

Minty23185Fresh
July 7th, 2016, 17:02
Putting this information in practice I learned a couple things...

For one:

However, you can override a specific function in a global script from another global script.
This methodology overrides the function, it does not replace the contents of the function. This is an important distinction. "Indexing" to function calls within the overridden function are lost in the overriding function, so the developer will have to add the explicit object name to those function calls.

For example: Using an extension I am supplanting the getEffectsString() function that is in the 5E EffectManager with additional functionality of my own. Within the overridden function are calls to isTargetedEffect(...) and getEffectTargets(...), among others. To avoid script errors in my overridding function, I have had to explicitly add the object name as in EffectManager.isTargetedEffect(...) and EffectManager.getEffectTargets(...).

Secondly, the following becomes impossible if the overridden function contains any non-explicit function calls...

I could use the same methodology to save it prior to replacement. Then call the saved function from the replacement