The problem is that to figure out whether a station has docking screens, we call <GetGlobalDockScreen>. And we call this for every object, including asteroids.

There should be some way to short-circuit it since asteroids never have dock screens.

Maybe if a station has no native docking ports and no overlays (which can add docking screens) then we assume it has no dock screens.

The downside is that we won't be able to add dock screens via <GetGlobalDockScreen> for stations that don't already have docking ports (basically, asteroids). This might be OK; for those cases we just need to add an overlay.

nms 29 Feb 2020:

That seems reasonable.

Some other ideas:

- I assume you're caching a list of types that have this event, so you don't have to check each type each time. Are inactive missions excluded?

- Could the event only be passed the object's type, rather than the object, so you only have to check for each type? If this breaks missions, could they work by adding event handlers instead?

- Do you actually need this information during game creation? When is it first used? If it has to do with painting docking indicators, you could maybe just do it for the starting system and do the others in the background later.

george moromisato 29 Feb 2020:

@NMS: Thanks, those are good thoughts.

I believe this performance problem happened due to the recent change of allowing overlays to add docking screens to asteroids: https://github.com/kronosaur/TranscendenceDev/commit/83d761eefebd2660977c9e7c035a96258a42f5b9

The way it works is this:

When an overlay is added, we recompute various flags on the object because the overlay may have changed things. This is handled in CSpaceObject::SetEventFlags. SetEventFlags will remember, for example, whether an object has a <GetDockScreen> event (either natively or in an overlay).

It will also create docking ports if we have a docking screen but no docking ports.

SetEventFlags calls HasDockScreen to figure out whether an object has a dock screen. We need to call this on the object (not the type), since it has to check whether the object has overlays, etc.

HasDockScreen calls <GetGlobalDockScreen> on all types that have that event to see if they add dock screens. This is almost always to override the first dock screen (e.g., to confiscate illegal goods). [The set of types with the events is cached, so that should be OK. Note also that we call types not mission instances.]

We call SetEventFlags at create-time, since we want the same code to initialize the object's state.