PDA

View Full Version : Extending pre-existing objects with extensions?



Dachannien
September 27th, 2008, 14:04
Hi, all,

I'm trying to convert my The Box mod into chocolate-chip-covered Extension form. Part of the original The Box modifies the ChatManager script and the chat windowclass objects by adding one scripting function to each of those two objects.

Now, I know I can make the extensified version of The Box work by copying out the entire chat windowclass into my extension along with the entire chat_chat.lua script, tacking on my additional function, and then do the same with the chatmanager.lua script. But that's not really all that extensiony - while it would make it easier to add The Box to a default ruleset, it also would create the potential for huge interoperability problems with other extensions and other custom rulesets that modify those same files. (There is also the issue of copying SmiteWorks's code into my extension, which would create licensing and copyright problems that I don't want to deal with.)

Anyway, my question is this: Does anyone know of a way using the new extensions interface to modify a base ruleset object without having to redefine those objects altogether in the extension?

Otherwise, I'll make it a feature request, probably in the form of adding merge rules to extensions, similar to how templates work.

Thanks!

Foen
September 27th, 2008, 14:39
I think this issue has been trailed a bit by Smite Works, Joshuha and others.

What it seems to imply at this stage is that a well-defined set of basic API hooks is needed in the core ruleset that others can then use for extensions. I think this forms part of the basis of the proposed Foundation ruleset.

If we all have an agreed set of API hooks to play with, adding extended functionality becomes that much easier.

It would be helpful to understand what functionality you are using in chat_chat and chatmanager, so that it might be exposed in a more modular way.

An example would be the new desktop code in 2.2, as it allows extensions to register themselves. Similarly, my rudimentary RPC calls in chat manager use the same approach.

Stuart

Valarian
September 27th, 2008, 15:12
Not tried it yet, but doesn't the way things are loaded mean that only the modified functions should need to be within the extension? The loading precedence described would seem to indicate this.

Foen
September 27th, 2008, 15:58
Good point Valarian, I've not tried it either. I just thought that when an extension redefined chatmanager.lua and loaded it as the ChatManager module, it would completely replace the existing defined module.

Worth trying out I think, but it may still lead to problems between incompatible rulesets/extensions (for example if the onDiceLanded function is redefined in two different extensions).

Cheers

Stuart

Valarian
September 27th, 2008, 17:37
I would imagine in this case it'd take the definition from the last extension loaded. I managed to do this with windowclasses for skills in the Conspiracy X ruleset. I defined the skill line in the files for both the main and skill tabs. The definition used was the one in the charsheet_skills file.

Dachannien
September 27th, 2008, 22:48
I had already tried Valarian's original suggestion (trying to define only the parts I'm changing and hoping it only replaces those parts) but since I'm using tags with the same identifiers in XML that the default ruleset uses, it sees those tags and replaces the original objects altogether.

The part of the chat window interface that I need access to is the onReceiveMessage event. I thought about trying to hook this by replacing the event function with my own function and then calling the old one (if non-nil) when my stuff is done, but you can't use findWindow to get access to panels (which is why the original chat window script registers itself with ChatManager).

I also tried creating a second invisible chat window, hoping that the messages would be dispatched to both chat windows on the host. Unfortunately, the messages only go to the first one.

(As it turns out, the chatmanager stuff was from an older version and isn't even necessary, so I commented it out with no ill effect. Doh!)

joshuha
September 27th, 2008, 23:24
I had already tried Valarian's original suggestion (trying to define only the parts I'm changing and hoping it only replaces those parts) but since I'm using tags with the same identifiers in XML that the default ruleset uses, it sees those tags and replaces the original objects altogether.

The part of the chat window interface that I need access to is the onReceiveMessage event. I thought about trying to hook this by replacing the event function with my own function and then calling the old one (if non-nil) when my stuff is done, but you can't use findWindow to get access to panels (which is why the original chat window script registers itself with ChatManager).

I also tried creating a second invisible chat window, hoping that the messages would be dispatched to both chat windows on the host. Unfortunately, the messages only go to the first one.

(As it turns out, the chatmanager stuff was from an older version and isn't even necessary, so I commented it out with no ill effect. Doh!)

The key here is to think of this at an API level type approach and build those into the base onReceiveMesage event. You would need to write into the base one checks to see if the default one should be used or to then check tables (possibly in the registry) or other registered libraries for processing instead. Basically, similar to the new desktopmanager.lua you have to redesign the base to be modular and then rewrite the defaults as one instance of that modularity. Does that make sense?

Dachannien
September 28th, 2008, 01:30
Yeah, that makes sense, although it seems like something that needs to be implemented in the foundational ruleset project, so that people who want to distribute extensions that change or add to base behavior can do so without having to distribute portions of other people's work.

joshuha
September 28th, 2008, 01:40
Correct, and one of the goals of that project (or similiar projects) will need to be ideas of where to hook in modular functionality.