90 lines
2.9 KiB
C++
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();
|
|
}
|
|
}
|