#pragma once #include #include #include #include #include #include #include /** * What the editor is working on, shared by its panels. Panels read it every * frame instead of holding on to a scene, so switching scenes is one call. */ class EditorContext { public: // A scene the editor has open, and can switch to. struct OpenScene { sophia::SceneHandle handle; std::string name; }; explicit EditorContext(sophia::SceneRegistry& scenes) : scenes{scenes} {} // Creates an open scene with a "Main Camera", without switching to it. sophia::SceneHandle createScene(std::string name) { sophia::SceneHandle handle = scenes.create(); scenes.get(handle).createCamera("Main Camera"); openScenes.push_back({handle, std::move(name)}); return handle; } const std::vector& getOpenScenes() const { return openScenes; } // Null if `handle` isn't an open scene. const std::string* getSceneName(sophia::SceneHandle handle) const { for (const OpenScene& open : openScenes) { if (open.handle == handle) { return &open.name; } } return nullptr; } void renameScene(sophia::SceneHandle handle, std::string name) { for (OpenScene& open : openScenes) { if (open.handle == handle) { open.name = std::move(name); } } } bool hasScene() const { return scenes.isAlive(activeScene); } sophia::SceneHandle getSceneHandle() const { return activeScene; } sophia::Scene& getScene() { return scenes.get(activeScene); } // Also clears the selection, which belonged to the previous scene. void setScene(sophia::SceneHandle handle) { activeScene = handle; selected = {}; } // Null when nothing is selected. Always an entity of the active scene. sophia::Entity selected; private: sophia::SceneRegistry& scenes; sophia::SceneHandle activeScene = sophia::INVALID_HANDLE; // Kept open even when not active: with no saving yet, closing one would // lose it. std::vector openScenes; }; // Points `view` at the context's active scene, and renders it only while // there is one and its panel is `shown`. Call every frame from the panel that // owns the view. inline void syncSceneView(EditorContext& context, sophia::SceneViewRegistry& sceneViews, sophia::SceneViewHandle view, bool shown) { bool enabled = shown && context.hasScene(); const sophia::SceneView& current = sceneViews.peek(view); // get() re-sorts the render queue, so only use it when something changed. if (current.enabled != enabled || (context.hasScene() && current.scene != context.getSceneHandle())) { sophia::SceneView& updated = sceneViews.get(view); updated.enabled = enabled; updated.scene = context.getSceneHandle(); } }