PDA

View Full Version : Improving Extensions Compatability



xelab
October 5th, 2020, 21:14
Hi,

I am trying to improve compatability of my extension with those of other people and I have figured out how to cleanly override functions in named .lua scripts:


func_old = NamedScript.func
NamedScript.func = func_new

function func_new(args)
-- my code

return func_old(args)
end


This way I only need to make sure my load order is higher than that of other extensions and even if they overload same functions both extensions should coexist well.

Similarly in XML I understand, that I have to use merge="join" in the appropriate blocks and they could in theory be modified by multiple extensions.

What I have not figured out is how to deal with cases, where I am overriding functions from unnamed scripts:


<windowclass name="windowname" merge="join">
<script file="path/scriptname.lua" />
</windowclass>


or even LUA snippets within XML, like in:


<windowclass name="windowname" merge="join">
<sheetdata>
<class_name name="instance">
<script>
function onButtonPress()
-- my code
end
</script>
</class_name >
</sheetdata>
</windowclass>


Is there a way to cleanly preserve the original functions in these cases, similarly to how it is done for named scripts?

darrenan
October 5th, 2020, 21:25
removed

darrenan
October 5th, 2020, 21:29
https://www.fantasygrounds.com/wiki/index.php/Developer_Guide

Read the sections "Scripting", "Templates", and "Layering" under the rulesets section. Within you'll find descriptions of how to chain scripts correctly using self. and super. which work the same way in extensions.

EDIT: On the Templates page, there is a Scripting section which has most of the useful information about chaining together scripts.

xelab
October 5th, 2020, 21:57
https://www.fantasygrounds.com/wiki/index.php/Developer_Guide

Read the sections "Scripting", "Templates", and "Layering" under the rulesets section. Within you'll find descriptions of how to chain scripts correctly using self. and super. which work the same way in extensions.

EDIT: On the Templates page, there is a Scripting section which has most of the useful information about chaining together scripts.

Thank you for the quick reply!
But I have re-read the "Overloading Functions" and I do not see anywhere how to preserve the inherited code.

All I see is that the original function gets completely overridden:

function onSourceUpdate()
setValue(10 + calculateSources());
end

Sure the calculateSources gets reused, but the onSourceUpdate is brand new and has nothing to do with original onSourceUpdate.
What I would like to achieve is to save the original function, override it and than call it from within my new function

Here is example, lets say the ruleset looks like this:


<script>
function onButtonPress()
-- original code
end
</script>


Now I would like to override it with this:


<script>
function onButtonPress()
-- new code

-- call original onButtonPress()
end
</script>


If I have to copy the old code in my new function this would defeat the purpose, since any changes to original would require me to update the extension

Or do I misunderstand everything completely?

Trenloe
October 5th, 2020, 22:09
If you have a <script> section within a control or windowclass, if that XML is merged then the new script is layered on top of the old. Access the old using the super variable.

Some info here: https://www.fantasygrounds.com/forums/showthread.php?58755-ct_entry-lua&p=516228&viewfull=1#post516228 You probably don't need to call the super.xxxx of every function - just the ones you're layering on top of.

For example:

<script>
function onButtonPress()
-- new code

if super and super.onButtonPress then
super.onButtonPress();
end

end
</script>

xelab
October 5th, 2020, 22:18
If you have a <script> section within a control or windowclass, if that XML is merged then the new script is layered on top of the old. Access the old using the super variable.

Some info here: https://www.fantasygrounds.com/forums/showthread.php?58755-ct_entry-lua&p=516228&viewfull=1#post516228 You probably don't need to call the super.xxxx of every function - just the ones you're layering on top of.

For example:

<script>
function onButtonPress()
-- new code

if super and super.onButtonPress then
super.onButtonPress();
end

end
</script>


Trenloe, thank you very much! Now it is much more clear to me.
Just a clarification question: if the load order is Ruleset -> Extension1 -> Extension2 and all 3 have the same function in them, would "super" in Extension2 point to Extension1 or Ruleset?

And lastly, is it exactly the same for the situation like this:


<windowclass name="windowname" merge="join">
<script file="path/scriptname_new.lua" />
</windowclass>

so in scriptname_new.lua if I define function with the same name as in scriptname_old.lua I can also use "super" to access the original?

Trenloe
October 6th, 2020, 09:34
Just a clarification question: if the load order is Ruleset -> Extension1 -> Extension2 and all 3 have the same function in them, would "super" in Extension2 point to Extension1 or Ruleset?
super refers to the next layer up. So super in Ext2 would refer to Ext1. super in Ext1 would refer to Ruleset.


And lastly, is it exactly the same for the situation like this:


<windowclass name="windowname" merge="join">
<script file="path/scriptname_new.lua" />
</windowclass>

so in scriptname_new.lua if I define function with the same name as in scriptname_old.lua I can also use "super" to access the original?
Using a file or code directly in the XML should work the same.

For a windowclass, I believe it works the same, based off the documentation. I don't think I've specifically tried it in a windowclass myself

SilentRuin
October 6th, 2020, 14:12
Hi,

I am trying to improve compatability of my extension with those of other people and I have figured out how to cleanly override functions in named .lua scripts:


func_old = NamedScript.func
NamedScript.func = func_new

function func_new(args)
-- my code

return func_old(args)
end


This way I only need to make sure my load order is higher than that of other extensions and even if they overload same functions both extensions should coexist well.

Similarly in XML I understand, that I have to use merge="join" in the appropriate blocks and they could in theory be modified by multiple extensions.

What I have not figured out is how to deal with cases, where I am overriding functions from unnamed scripts:


<windowclass name="windowname" merge="join">
<script file="path/scriptname.lua" />
</windowclass>


or even LUA snippets within XML, like in:


<windowclass name="windowname" merge="join">
<sheetdata>
<class_name name="instance">
<script>
function onButtonPress()
-- my code
end
</script>
</class_name >
</sheetdata>
</windowclass>


Is there a way to cleanly preserve the original functions in these cases, similarly to how it is done for named scripts?

As I've said very recently - this is how I handle that issue..

https://www.fantasygrounds.com/forums/showthread.php?62377-Shared-Function-in-Ext&p=546087&viewfull=1#post546087

xelab
October 6th, 2020, 19:13
Trenloe, SilentRuin, thank you both very much!!!