Files
sophia/editor/editor_context.hpp

90 lines
2.9 KiB
C++

#pragma once
#include <sophia/entity.hpp>
#include <sophia/handles.hpp>
#include <sophia/scene.hpp>
#include <sophia/scene_registry.hpp>
#include <sophia/scene_view_registry.hpp>
#include <string>
#include <vector>
/**
* 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<OpenScene>& 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<OpenScene> 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();
}
}