Opened 10 years ago

Closed 10 years ago

Last modified 10 years ago

#2517 closed enhancement (fixed)

[PATCH] Register all component classes as global

Reported by: sanderd17 Owned by: Radagast
Priority: Should Have Milestone: Alpha 17
Component: Core engine Keywords: patch
Cc: Patch:

Description (last modified by sanderd17)

When someone makes a mod now, they have to copy the entire component over to their mod (which can be quite hard to maintain).

By registering all components as a global, mods can just extend functionality from the existing prototype in the public mod by doing that in a different file that's loaded afterwards (f.e. by creating an Attack.MyMod.js file to extend the Attack prototype defined in Attack.js).

There's a separate Engine function now to register variables as global (Engine.RegisterGlobal(name, var)), but it would be better to put this functionality inside the Engine.RegisterComponentType() method, so the actual JS components don't have to be modified.

As the schema gets saved to the Engine on RegisterComponentType, we should also allow to register the same component multiple times to allow schema overriding by mods (this might be less simple than the other part to get it right).

Attachments (3)

RegisterComponentsAsGlobal.diff (682 bytes ) - added by Radagast 10 years ago.
global_components.diff (5.0 KB ) - added by sanderd17 10 years ago.
RegisterComponentsAsGlobal.2.diff (1.1 KB ) - added by Radagast 10 years ago.

Download all attachments as: .zip

Change History (29)

comment:1 by Niek, 10 years ago

Didn't it work already?

comment:2 by sanderd17, 10 years ago

Apparently not

in reply to:  2 comment:3 by Niek, 10 years ago

Replying to sanderd17:

Apparently not

But I extended the Aristeia scripts like the way you described, and no errors are thrown...

comment:4 by Radagast, 10 years ago

That's strange. It didn't work for me. It rather was random. Did you test the healing priests/converter unit after your changes?

(that's the only unit that uses the Convert Attack. Which for me didn't work.)

in reply to:  4 comment:5 by Niek, 10 years ago

Replying to Radagast:

That's strange. It didn't work for me. It rather was random. Did you test the healing priests/converter unit after your changes?

(that's the only unit that uses the Convert Attack. Which for me didn't work.)

No, I did only test the cheat.

comment:6 by sanderd17, 10 years ago

The cheat isn't a component.

comment:7 by sanderd17, 10 years ago

Description: modified (diff)

comment:8 by Radagast, 10 years ago

Attached a patch. Still I'm not really sure about this. Because my warnings were shown from random files mixed. As if they only overwrote temporarily. I will have to investigate.

And then if the GlobalRegistering should prove obsolete, then we might have to remove it again. This time with a regular expression. It's always at the end of the file. So this shouldn't be too difficult (if potential following blank lines also are matchin the regex.)

comment:9 by Radagast, 10 years ago

Owner: set to Radagast
Status: newassigned
Summary: Register all component classes as global[Patch] Register all component classes as global

comment:10 by Radagast, 10 years ago

Keywords: review added

comment:11 by scythetwirler, 10 years ago

Summary: [Patch] Register all component classes as global[PATCH] Register all component classes as global

comment:12 by sanderd17, 10 years ago

Keywords: review removed

Euhm, I'd like to see the RegisterComponentType method modified, rather than changing every component file.

comment:13 by Radagast, 10 years ago

oh ... yes .. I remember :D sorry.

comment:14 by Radagast, 10 years ago

Keywords: review added; simple removed

comment:15 by Radagast, 10 years ago

Note i might have mistake in because the linker forced me to change several parameters. Perhaps this was a random error. If so, then I should check. Will do.

comment:16 by sanderd17, 10 years ago

Looks good, the TODO is unnecessary (I think this will be quite permanent). Now the other part ;)

by Radagast, 10 years ago

comment:17 by Radagast, 10 years ago

Keywords: simple added; review removed

comment:18 by Radagast, 10 years ago

Will remove TODO then.

For part 2 I thought of splitting the C++ Script_RegisterComponentType() into 2. Is this fine?

We could also trigger hotloading but this would override all other mods' components with this IID and thus we needed a spearate flag to skip this hotloading branch (which is entered if the IID_Component already is registered).

Currently we return here:

if (!componentManager->m_CurrentlyHotloading) 
    return /*after error message: component already registered*/;

So either we split the C++ method in two. Or we introduce a flag that tell the function now not to delete/reset the component but only to add the schema.

Will have to create a patch.

Last edited 10 years ago by Radagast (previous) (diff)

comment:19 by Stan, 10 years ago

I don't think Hotloading is a good idea, because that would bring more reason for the program to crash.

comment:20 by Radagast, 10 years ago

The hotloading is reloading all files/components. We in our case need to just overwrite the schema of the first component that was registered (partially overloading of components if they have the same IID and name). But I still have not completely grasped the consequences. I will have to experiment with it I'm afraid.

You're right it's usually troublesome. 0AD has apparently solved this properly as there are few issues I can recall here.

by sanderd17, 10 years ago

Attachment: global_components.diff added

comment:21 by sanderd17, 10 years ago

I gave it a shot, added a new ReRegisterComponentType method (the RegisterComponentType has been renamed to RegisterNewComponentType, but the JS version of that name still needs to be updated).

RegisterNewComponentType makes it global, and has the same limitations as the old method (not able to overwrite f.e.).

The ReRegisterComponentType makes you able to overwrite existing stuff (and even fails if you don't overwrite something existing), but doesn't make anything global.

This is still very untested, but it seems to work in the most basic cases: overwriting methods, schema's and On... message catchers.

Hotloading needs to be tested more (what happens if you hotload the original file, the replacing file, what should we support?).

comment:22 by sanderd17, 10 years ago

Keywords: simple removed

Not that simple after all

comment:23 by sanderd17, 10 years ago

Keywords: patch review added

comment:24 by Radagast, 10 years ago

ups. Didn't realise your effort. thx sander. Yet here is my patch. Just re-using the hotloading functionality instead of a separate ReRegisterComponentType.

Essentially just had to comment one if condition out.

Tested with Converting priests.

Nevermind yours sounds interesting too. A separate function was what I also thought of but I was never sure if I not missed something, so I just opted for the attached patch. But I'm for your patch as now you have had the work with it (and it's more probable to work properly. thx again for fixing. This is huge improvement for modding.).

by Radagast, 10 years ago

comment:25 by sanderd17, 10 years ago

Resolution: fixed
Status: assignedclosed

In 15150:

Mark all components as global variables and allow to re-register existing components to update their schema and/or message receiving methods.
This allows for components to be extended in other files, so mods don't have to overwrite entire components.
Fixes #2517. Thanks to Rada for helping on this
(also fix some tests broken in the previous commit)

comment:26 by sanderd17, 10 years ago

Keywords: review removed
Note: See TracTickets for help on using tickets.