-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
As part of both the renderer rewrite (#850) and the architectural rework of the engine, we need to decouple subsystems. Without this, proper support for a client/server split and job-based parallelism with communication through channels will be practically impossible. I'm working on the graphics side of things, so I'd like to work on decoupling the GUI first.
To achieve this design goal, we unfortunately have to get rid of all the GuiLinks as they stand, as well as any other links to non-GUI engine components (e.g. EngineQMLInfo). From a very high-level viewpoint, the initial idea of how we could replace this is a callback system, where all communication proceeds solely through the Gui class, with an API of something like:
class Gui {
public:
Gui (SDL_Window*, util::Path const& source, util::Path const& root_dir); // no EngineQMLInfo
void register_on_X_cb(std::function<..> callback); // registers a function to be called when X happens in the GUI
void enqueue_event(SDL_Event*); // stores an event to be processed
void process_events(); // actually processes events and calls callbacks
private:
internal state
};Obviously, we will need more than just the above in practice, but the general idea is that the GUI is an event-based component like any other. By itself it doesn't do anything. The user registers functions that they want called on GUI state changes. To give an example, currently changing properties of a game involves a GameControlLink that directly manipulates Engine members. This is unfortunate, because it will result in completely unpredictable behaviour in a concurrent execution context. Instead, what we would have is a on_game_property_changed callback which is called from process_events whenever the GUI detects that one of the enqueued events is a mouse click on something that triggers a game property change. It is up to the user to ensure threadsafety for that callback, and what we would in fact do is either make that callback send an event on the WorldUpdater concurrent input channel or directly modify some property of the PresentationState, which is local to the Presenter class - the user of the GUI.
I'd be happy to hear thoughts on this, especially from @ChipmunkV, who I understand is the principal author of the GUI.