From 223bbed2322cc3f3e741b52e2d6e22427b4ad8db Mon Sep 17 00:00:00 2001
From: Dominic Masters <dominic@domsplace.com>
Date: Thu, 5 Dec 2024 15:58:44 -0600
Subject: [PATCH] Made scene loader "work" for now.

---
 assets/prefabs/npc.json                       | 23 ++++++++++
 assets/prefabs/rosa.json                      |  7 +--
 assets/scenes/test_rpg_scene.json             |  9 ++++
 src/dawn/asset/loader/scene/CMakeLists.txt    |  1 +
 .../asset/loader/scene/SceneLoadContext.cpp   | 14 +++++-
 .../asset/loader/scene/SceneLoadContext.hpp   | 43 ++++++++++++++++---
 src/dawnrpg/CMakeLists.txt                    |  1 +
 src/dawnrpg/component/RPGPlayer.cpp           |  5 +--
 8 files changed, 90 insertions(+), 13 deletions(-)
 create mode 100644 assets/prefabs/npc.json

diff --git a/assets/prefabs/npc.json b/assets/prefabs/npc.json
new file mode 100644
index 00000000..3b9d169a
--- /dev/null
+++ b/assets/prefabs/npc.json
@@ -0,0 +1,23 @@
+{
+  "name": "Rosa",
+  
+  "assets": {
+    "rosa": {
+      "type": "texture",
+      "path": "rosa.texture"
+    }
+  },
+
+  "components": {
+    "material": {
+      "type": "SimpleTexturedMaterial",
+      "texture": "rosa"
+    },
+    "meshRenderer": {
+      "type": "MeshRenderer"
+    },
+    "entity": {
+      "type": "RPGEntity"
+    }
+  }
+}
\ No newline at end of file
diff --git a/assets/prefabs/rosa.json b/assets/prefabs/rosa.json
index d56ebb82..16dc7542 100644
--- a/assets/prefabs/rosa.json
+++ b/assets/prefabs/rosa.json
@@ -2,7 +2,7 @@
   "name": "Rosa",
   
   "assets": {
-    "rosa_texture": {
+    "rosa": {
       "type": "texture",
       "path": "rosa.texture"
     }
@@ -11,7 +11,7 @@
   "components": {
     "material": {
       "type": "SimpleTexturedMaterial",
-      "texture": "rosa_texture"
+      "texture": "rosa"
     },
     "meshRenderer": {
       "type": "MeshRenderer"
@@ -20,7 +20,8 @@
       "type": "RPGEntity"
     },
     "player": {
-      "type": "RPGPlayer"
+      "type": "RPGPlayer",
+      "camera": "camera"
     }
   }
 }
\ No newline at end of file
diff --git a/assets/scenes/test_rpg_scene.json b/assets/scenes/test_rpg_scene.json
index af2545ef..69b2f4a6 100644
--- a/assets/scenes/test_rpg_scene.json
+++ b/assets/scenes/test_rpg_scene.json
@@ -5,6 +5,10 @@
     "rosa": {
       "type": "prefab",
       "path": "prefabs/rosa.json"
+    },
+    "npc": {
+      "type": "prefab",
+      "path": "prefabs/npc.json"
     }
   },
 
@@ -20,6 +24,11 @@
     "rosa": {
       "prefab": "rosa",
       "position": [ 0, 0, 0 ]
+    },
+
+    "npc": {
+      "prefab": "npc",
+      "position": [ 32, 0, 0 ]
     }
   }
 }
\ No newline at end of file
diff --git a/src/dawn/asset/loader/scene/CMakeLists.txt b/src/dawn/asset/loader/scene/CMakeLists.txt
index 8ce94116..1d205152 100644
--- a/src/dawn/asset/loader/scene/CMakeLists.txt
+++ b/src/dawn/asset/loader/scene/CMakeLists.txt
@@ -9,4 +9,5 @@ target_sources(${DAWN_TARGET_NAME}
     SceneLoader.cpp
     LoaderForSceneItems.cpp
     PrefabLoader.cpp
+    SceneLoadContext.cpp
 )
\ No newline at end of file
diff --git a/src/dawn/asset/loader/scene/SceneLoadContext.cpp b/src/dawn/asset/loader/scene/SceneLoadContext.cpp
index 0d94250d..bf05865b 100644
--- a/src/dawn/asset/loader/scene/SceneLoadContext.cpp
+++ b/src/dawn/asset/loader/scene/SceneLoadContext.cpp
@@ -3,4 +3,16 @@
 // This software is released under the MIT License.
 // https://opensource.org/licenses/MIT
 
-#include "SceneLoadContext.hpp"
\ No newline at end of file
+#include "SceneLoadContext.hpp"
+
+using namespace Dawn;
+
+std::shared_ptr<SceneItem> SceneLoadContext::getItem(const std::string &j) {
+  auto it = items.find(j);
+  if(it == items.end()) {
+    auto parent = this->parent.lock();
+    assertNotNull(parent, "Couldn't find item.");
+    return parent->getItem(j);
+  }
+  return it->second;
+}
\ No newline at end of file
diff --git a/src/dawn/asset/loader/scene/SceneLoadContext.hpp b/src/dawn/asset/loader/scene/SceneLoadContext.hpp
index 94cb563f..082b12a1 100644
--- a/src/dawn/asset/loader/scene/SceneLoadContext.hpp
+++ b/src/dawn/asset/loader/scene/SceneLoadContext.hpp
@@ -14,19 +14,23 @@ namespace Dawn {
   class AssetLoader;
   class SceneLoadContext;
 
+  class PrefabLoader;
+  class LoaderForSceneItems;
+  class SceneLoader;
+
   class SceneLoadContext {
-    public:
+    private:
       std::weak_ptr<SceneLoadContext> parent;
       std::unordered_map<std::string, std::shared_ptr<SceneItem>> items;
       std::unordered_map<std::string, std::shared_ptr<SceneComponent>> components;
       std::unordered_map<std::string, std::shared_ptr<AssetLoader>> assets;
-
-      json data;
-
       std::shared_ptr<Scene> currentScene;
       std::shared_ptr<SceneItem> currentItem;
       std::shared_ptr<SceneComponent> currentComponent;
 
+    public:
+      json data;
+
       /**
        * Gets an asset from the context.
        * 
@@ -46,6 +50,35 @@ namespace Dawn {
         return asset;
       }
 
-      
+      /**
+       * Gets an item from the context.
+       * 
+       * @param j Name of the item to get.
+       * @return Item from the context.
+       */
+      std::shared_ptr<SceneItem> getItem(const std::string &j);
+
+      /**
+       * Gets a component from the context.
+       * 
+       * @param j Name of the component to get.
+       * @return Component from the context.
+       */
+      template<class T>
+      std::shared_ptr<T> getComponent(const std::string &j) const {
+        auto it = components.find(j);
+        if(it == components.end()) {
+          auto parent = this->parent.lock();
+          assertNotNull(parent, "Couldn't find component.");
+          return parent->getComponent<T>(j);
+        }
+        auto cmp = std::dynamic_pointer_cast<T>(it->second);
+        assertNotNull(cmp, "Component is not of the correct type.");
+        return cmp;
+      }
+
+      friend class PrefabLoader;
+      friend class LoaderForSceneItems;
+      friend class SceneLoader;
   };
 }
\ No newline at end of file
diff --git a/src/dawnrpg/CMakeLists.txt b/src/dawnrpg/CMakeLists.txt
index 71e26daa..3111623d 100644
--- a/src/dawnrpg/CMakeLists.txt
+++ b/src/dawnrpg/CMakeLists.txt
@@ -16,4 +16,5 @@ add_subdirectory(game)
 # Assets
 tool_texture(rosa rosa.png)
 tool_copy(prefab_rosa prefabs/rosa.json)
+tool_copy(prefab_npc prefabs/npc.json)
 tool_copy(test_rpg_scene scenes/test_rpg_scene.json)
\ No newline at end of file
diff --git a/src/dawnrpg/component/RPGPlayer.cpp b/src/dawnrpg/component/RPGPlayer.cpp
index 37903d50..57fa80f2 100644
--- a/src/dawnrpg/component/RPGPlayer.cpp
+++ b/src/dawnrpg/component/RPGPlayer.cpp
@@ -75,9 +75,6 @@ void RPGPlayer::load(std::shared_ptr<SceneLoadContext> ctx) {
   SceneComponent::load(ctx);
 
   if(ctx->data.contains("camera")) {
-    assertMapHasKey(ctx->components, ctx->data["camera"], "Camera not found!");
-    const auto component = ctx->components[ctx->data["camera"].get<std::string>()];
-    this->camera = std::dynamic_pointer_cast<Camera>(component);
-    assertNotNull(this->camera, "Camera not found!");
+    this->camera = ctx->getComponent<Camera>(ctx->data["camera"]);
   }
 }
\ No newline at end of file