From a36e89ca6dcd6ed68e4f9bf7a521016d17c4116f Mon Sep 17 00:00:00 2001
From: Joseph Walton-Rivers <joseph@walton-rivers.uk>
Date: Sun, 20 Nov 2022 14:47:41 +0000
Subject: [PATCH] mark scripts as scene dependencies

---
 demo/demo/rollball.cpp         |  2 +-
 fggl/assets/types.cpp          |  3 ++-
 fggl/entity/module.cpp         | 33 +++++++++++++++++++++++++++++++++
 include/fggl/assets/loader.hpp |  5 +++++
 include/fggl/entity/module.hpp |  8 ++++++--
 5 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/demo/demo/rollball.cpp b/demo/demo/rollball.cpp
index 24aa3da..ec8a050 100644
--- a/demo/demo/rollball.cpp
+++ b/demo/demo/rollball.cpp
@@ -88,7 +88,7 @@ namespace demo {
 		// asset loader
 		auto* assetLoader = m_owner.service<fggl::assets::Loader>();
 		assetLoader->load("rollball.yml", fggl::entity::ENTITY_PROTOTYPE, entFactory);
-		assetLoader->load("rollball.yml", fggl::entity::ENTITY_SCENE, this);
+		assetLoader->loadChain( fggl::assets::make_asset_id_rt("core", "rollerball/rollball.yml"), this);
 
 		// collectable callbacks
 		/*auto* collectableCallbacks = world().get<fggl::phys::CollisionCallbacks>(prefabs.collectable);
diff --git a/fggl/assets/types.cpp b/fggl/assets/types.cpp
index ef1a812..591e0fc 100644
--- a/fggl/assets/types.cpp
+++ b/fggl/assets/types.cpp
@@ -34,7 +34,8 @@ namespace fggl::assets {
 	}
 
 	AssetID asset_from_user(const std::string &input, const std::string &pack) {
-		if (input.find(':') != 0) {
+
+		if (input.find(':') != std::string::npos ) {
 			// probably fully qualified
 			#ifndef NDEBUG
 			util::internString(input.c_str());
diff --git a/fggl/entity/module.cpp b/fggl/entity/module.cpp
index 5ebda82..3d70df9 100644
--- a/fggl/entity/module.cpp
+++ b/fggl/entity/module.cpp
@@ -37,6 +37,34 @@ namespace fggl::entity {
 		factory->bind(math::Transform::guid, make_transform);
 	}
 
+	static assets::AssetTypeID is_scene(std::filesystem::path path) {
+		if ( path.extension() == ".yml" ) {
+			return ENTITY_SCENE;
+		}
+
+		return assets::INVALID_ASSET_TYPE;
+	}
+
+	bool get_scene_deps(const std::string& packName, std::filesystem::path packRoot, assets::ResourceRecord& rr) {
+
+		auto nodes = YAML::LoadAllFromFile( rr.m_path );
+		for ( auto& node : nodes ) {
+			auto scripts = node["scripts"];
+			if ( !scripts ) {
+				continue;
+			}
+
+			for (auto script : scripts) {
+				auto scriptName = script.as<std::string>();
+				auto scriptRef = assets::asset_from_user(scriptName, rr.m_pack);
+				rr.m_requires.push_back(scriptRef);
+			}
+		}
+
+		return true;
+	}
+
+
 	bool ECS::factory(modules::ModuleService service, modules::Services &services) {
 		if (service == EntityFactory::service) {
 			auto *factory = services.create<EntityFactory>(services);
@@ -53,6 +81,11 @@ namespace fggl::entity {
 			}, assets::LoadType::PATH);
 			assetLoader->setFactory(ENTITY_SCENE, load_scene, assets::LoadType::PATH);
 
+			// allow auto-detection
+			auto *checkin = services.get<assets::CheckinAdapted>();
+			checkin->setLoader(MIME_SCENE, assets::NEEDS_CHECKIN, is_scene);
+			checkin->setProcessor(MIME_SCENE, get_scene_deps);
+
 			return true;
 		}
 		return false;
diff --git a/include/fggl/assets/loader.hpp b/include/fggl/assets/loader.hpp
index b07a9a6..2ccbfd2 100644
--- a/include/fggl/assets/loader.hpp
+++ b/include/fggl/assets/loader.hpp
@@ -88,6 +88,11 @@ namespace fggl::assets {
 					auto current = openSet.top();
 					openSet.pop();
 
+					if ( !m_checkin->exists(current) ) {
+						debug::warning("attempted to load chain with unknown assert, {} - abort!", current);
+						return;
+					}
+
 					// this WILL (probably) break if an asset ends up in the chain twice
 					loadOrder.push_back( current );
 					const auto& record = m_checkin->find(current);
diff --git a/include/fggl/entity/module.hpp b/include/fggl/entity/module.hpp
index 6df1944..cb27abc 100644
--- a/include/fggl/entity/module.hpp
+++ b/include/fggl/entity/module.hpp
@@ -22,17 +22,21 @@
 #include "fggl/modules/module.hpp"
 #include "fggl/assets/loader.hpp"
 
+#include "fggl/assets/packed/adapter.hpp"
 #include "fggl/entity/loader/loader.hpp"
 
 namespace fggl::entity {
 
+	constexpr auto MIME_SCENE = assets::from_mime("x-fggl/scene");
+
 	struct ECS {
 		constexpr static const char *name = "fggl::entity::ECS";
 		constexpr static const std::array<modules::ModuleService, 1> provides = {
 			EntityFactory::service
 		};
-		constexpr static const std::array<modules::ModuleService, 1> depends = {
-			assets::Loader::service
+		constexpr static const std::array<modules::ModuleService, 2> depends = {
+			assets::Loader::service,
+			assets::CheckinAdapted::service
 		};
 		static bool factory(modules::ModuleService name, modules::Services &serviceManager);
 	};
-- 
GitLab