Overlay manager discussion thread #1529
Replies: 4 comments 11 replies
This comment has been hidden.
This comment has been hidden.
-
Interface methods/properties must be public and also implementations because interface is a contract. You can set interface as internal but then you have to use explicit implementation (Instead of |
Beta Was this translation helpful? Give feedback.
-
Yeah it's mix from render manager and other managers that render things. Yes it calculates boundaries of grid (minXY/maxXY), sadly nothing to cache but pretty cheap to calculate so shouldn't be an issue here. Anyways, try to not overcomplicate things just for sake of "future uses". Personally I would focus on separating things(this only does rendering, thing only grouping/caching, thing only creating thing A or B) and implementing it in a way it could be extended but not necessarily now because it may take ages until we see anything usable if we focus on providing support for things that will be added in the unknown future😂 |
Beta Was this translation helpful? Give feedback.
-
@krzychu124 How are you triggering your |
Beta Was this translation helpful? Give feedback.
-
Dsicussion & brainstorming of overlay manager.
This is what I'm currently chipping away at:
Start
Overlay session starts in one of two ways:
TurnOn()
The process creates two structs (which are passed to other stages via
ref
):RenderConfig
- defines which overlays to show -> what to map cache, etc.RenderState
- current state (eg. camera, mouse, keyboard, etc)Map Caches
Adapted from Krzychu124 code, these use game's render grids to quickly determine what's on-screen and cache ids of validated nodes, etc.
What gets scanned is determined by
RenderState
which in turn is derived fromRenderConfig
. The results are cached until told otherwise - this means that if the camera isn't moving, the map cache is idle (we don't need to keep checking what's on-screen).Because we know which overlays require which caches (target flags per overlay) the generator is able to invoke the required generators.
Additionally, it means we can do targeted micro-generations if new stuff is added to map (eg. Move It pastes intersection) without even needing to refresh the map caches.
Generators
Each overlay has a generator. The generator is responsible for iterating the supplied information to determine what is of interest, and then instantiating wrapper objects of those items, which are then handed to, and cached by, one or more overlay layers.
Code example: Node labels generator
Layers
Each type of overlay (connector, icon, label, etc) has an associated layer. When a generator passes an item to the layer, the layer wraps it in a render cache
struct
(a "task") and adds that to its 'task list'.The layer provides tools for updating/invalidating/clearing the contents of the task list.
Code example: Some features of Label layer
Interact
This is always processing per frame, but is very fast. It iterates the tasks (structs - on heap) and checks
task.BoundsBox.Contains(mousePos)
- only if that'strue
does any additional work get done - eg. triggeringOnHover()
orOnClick()
events of thetask.Item
instance.Code example: Label interactions
Compute
This is the most intensive stage. It iterates the task list structs, and if any are dirty (invalidated) it does whatever computation is required to refresh the render details. Notably, it will need to refer to the item
class
instance (not on heap) which in turn may need to call external managers (eg.SpeedLimitManager
). The struct in the task list is then replaced with the refreshed struct.This means that while the camera isn't moving, the Compute step is sat idle. Additionally, because the layer functionality allows filtered invalidations, we can do micro-computes for individual items (or batches of items) if they change, eg. due to mouse interaction or subtool mode change. In cases of heavy load, we can also spread Compute step across frames.
Code example: Computing a label
Render
This is always processing per frame, but is as fast as possible I think. It iterates the tasks (structs - on heap) and does the GUI render call based entirely on the cached values from Compute stage.
Code example: Rendering a label
Beta Was this translation helpful? Give feedback.
All reactions