]> git.tdb.fi Git - libs/game.git/commitdiff
Support custom lookup functions for retrieving setups in Spawner
authorMikko Rasa <tdb@tdb.fi>
Sat, 17 Jun 2023 21:40:21 +0000 (00:40 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sat, 17 Jun 2023 21:49:05 +0000 (00:49 +0300)
source/game/spawner.cpp
source/game/spawner.h

index f696d4dc2674dc038bce389471c00fa2314a6ad4..9c0c3e647d0eca77654dd826f5a68522ee562953 100644 (file)
@@ -45,7 +45,7 @@ void Spawner::spawn(const SpawnableType &type, const string &setup_name, const T
        if(i==spawn_infos.end())
                i = spawn_infos.emplace(spawn_infos.end(), make_unique<SpawnInfo>(this, type.type.get_name(), setup_name));
 
-       Owned<Entity> entity = (this->*type.create_func)(setup_name, tf);
+       Owned<Entity> entity = type.create_func(setup_name, tf);
        if(Handle<Zygote> zygote = entity->get_component<Zygote>())
                zygote->set_spawn_info(**i);
        handler.spawned(move(entity));
index 95ac903cff35bbf1bc7504b126789acccc5829dd..0473e71d10b57181cc38b1e4c619197ab189ebbb 100644 (file)
@@ -2,6 +2,7 @@
 #define MSP_GAME_SPAWNER_H_
 
 #include <algorithm>
+#include <functional>
 #include "messages.h"
 #include "owned.h"
 
@@ -28,11 +29,17 @@ public:
 
 class MSPGAME_API Spawner
 {
+public:
+       template<typename T>
+       using LookupFunc = std::function<const T &(const std::string &)>;
+
 private:
+       using CreateFunc = std::function<Owned<Entity>(const std::string &, const TransformValues &)>;
+
        struct SpawnableType
        {
                const Reflection::ClassBase &type;
-               Owned<Entity> (Spawner::*create_func)(const std::string &, const TransformValues &) const;
+               CreateFunc create_func;
        };
 
        DataFile::Collection &resources;
@@ -50,6 +57,10 @@ public:
                requires std::is_base_of_v<Entity, T>
        void add_spawnable_type();
 
+       template<typename T>
+               requires std::is_base_of_v<Entity, T>
+       void add_spawnable_type(LookupFunc<typename T::Setup>);
+
 private:
        void add_to_replicator(const std::string &);
 
@@ -64,20 +75,26 @@ public:
 
 private:
        void spawn(const SpawnableType &, const std::string &, const TransformValues &);
-
-       template<typename T>
-       Owned<Entity> create(const std::string &, const TransformValues &) const;
 };
 
 
 template<typename T>
        requires std::is_base_of_v<Entity, T>
 void Spawner::add_spawnable_type()
+{
+       add_spawnable_type<T>([this](const std::string &n) -> const typename T::Setup & { return resources.get<typename T::Setup>(n); });
+}
+
+template<typename T>
+       requires std::is_base_of_v<Entity, T>
+void Spawner::add_spawnable_type(LookupFunc<typename T::Setup> lookup_func)
 {
        const Reflection::ClassBase &type = reflector.get_or_create_class<T>();
        /* There's assumed to be only a few types per spawner, so sorting is not
        necessary */
-       spawnable_types.emplace_back(type, &Spawner::create<T>);
+       spawnable_types.emplace_back(type, [this, lookup_func=std::move(lookup_func)](const std::string &sn, const TransformValues &tf){
+               return Owned<T>(parent, lookup_func(sn), tf);
+       });
        add_to_replicator(type.get_name());
 }
 
@@ -93,13 +110,6 @@ void Spawner::spawn(const std::string &sname, const TransformValues &tf)
        spawn(*i, sname, tf);
 }
 
-template<typename T>
-Owned<Entity> Spawner::create(const std::string &setup_name, const TransformValues &tf) const
-{
-       const typename T::Setup &setup = resources.get<typename T::Setup>(setup_name);
-       return Owned<T>(parent, setup, tf);
-}
-
 } // namespace Msp::Game
 
 #endif