aboutsummaryrefslogtreecommitdiff
path: root/src/brussel.engine/Level.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/brussel.engine/Level.hpp')
-rw-r--r--src/brussel.engine/Level.hpp95
1 files changed, 95 insertions, 0 deletions
diff --git a/src/brussel.engine/Level.hpp b/src/brussel.engine/Level.hpp
new file mode 100644
index 0000000..c030b8e
--- /dev/null
+++ b/src/brussel.engine/Level.hpp
@@ -0,0 +1,95 @@
+#pragma once
+
+#include "EditorCore.hpp"
+#include "GameObject.hpp"
+
+#include <MacrosCodegen.hpp>
+#include <RcPtr.hpp>
+#include <Uid.hpp>
+
+#include <robin_hood.h>
+#include <filesystem>
+#include <vector>
+
+// Forward declarations
+class Level;
+class LevelManager;
+
+/// Represents a seralized GameObject tree.
+class Level : public RefCounted {
+ friend class LevelManager;
+
+private:
+ struct InstanciationEntry;
+
+ LevelManager* mMan;
+ Uid mUid;
+ std::vector<InstanciationEntry> mEntries;
+
+public:
+ Level();
+ ~Level();
+
+ void Instanciate(GameObject* relRoot) const;
+
+ LevelManager* GetLinkedLevelManager() const { return mMan; }
+ const Uid& GetUid() const { return mUid; }
+
+ // Editor stuff
+ void ShowInstanciationEntries(IEditor& editor);
+};
+
+class LevelManager {
+public:
+ static inline LevelManager* instance = nullptr;
+
+public: // NOTE: public for the editor; actual game components should not modify the map using this
+ // TODO maybe cut this struct to only the first RcPtr<Level> field in release mode?
+ struct LoadableObject {
+ RcPtr<Level> level; // TODO make weak pointer
+ std::filesystem::path filePath;
+ // NOTE: these fields are only loaded in dev mode
+ std::string name;
+ std::string description;
+
+ // Editor book keeping fields
+ bool edited = false;
+ };
+ // We want pointer stability here for the editor (inspector object)
+ robin_hood::unordered_node_map<Uid, LoadableObject> mObjByUid;
+
+public:
+ void DiscoverFilesDesignatedLocation();
+ void DiscoverFiles(const std::filesystem::path& dir);
+
+ Level* FindLevel(const Uid& uid) const;
+ /// Get or load the given level
+ Level* LoadLevel(const Uid& uid);
+ /// Send the given level to be loaded on another thread
+ void PrepareLevel(const Uid& uid);
+
+ /// Create and add a new level object with the given uid.
+ /// Should only be used by the editor.
+ LoadableObject& AddLevel(const Uid& uid);
+ /// Should only be used by the editor.
+ void SaveLevel(const Uid& uid) const;
+ /// Should only be used by the editor.
+ void SaveLevel(const Uid& uid, const std::filesystem::path& path) const;
+
+private:
+ void SaveLevelImpl(const LoadableObject& obj, const std::filesystem::path& path) const;
+};
+
+class LevelWrapperObject : public GameObject {
+ BRUSSEL_CLASS()
+
+private:
+ RcPtr<Level> mLevel;
+
+public:
+ LevelWrapperObject(GameWorld* world);
+ ~LevelWrapperObject() override;
+
+ Level* GetBoundLevel() const;
+ void SetBoundLevel(Level* level);
+};