feat(editor): unify component registration pipeline
This commit is contained in:
67
engine/src/Components/ComponentFactoryRegistry.cpp
Normal file
67
engine/src/Components/ComponentFactoryRegistry.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
#include "Components/ComponentFactoryRegistry.h"
|
||||
|
||||
#include "Components/AudioListenerComponent.h"
|
||||
#include "Components/AudioSourceComponent.h"
|
||||
#include "Components/CameraComponent.h"
|
||||
#include "Components/GameObject.h"
|
||||
#include "Components/LightComponent.h"
|
||||
|
||||
namespace XCEngine {
|
||||
namespace Components {
|
||||
|
||||
namespace {
|
||||
|
||||
template<typename T>
|
||||
Component* CreateBuiltInComponent(GameObject* gameObject) {
|
||||
return gameObject ? gameObject->AddComponent<T>() : nullptr;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ComponentFactoryRegistry& ComponentFactoryRegistry::Get() {
|
||||
static ComponentFactoryRegistry registry;
|
||||
return registry;
|
||||
}
|
||||
|
||||
ComponentFactoryRegistry::ComponentFactoryRegistry() {
|
||||
RegisterFactory("Camera", &CreateBuiltInComponent<CameraComponent>);
|
||||
RegisterFactory("Light", &CreateBuiltInComponent<LightComponent>);
|
||||
RegisterFactory("AudioSource", &CreateBuiltInComponent<AudioSourceComponent>);
|
||||
RegisterFactory("AudioListener", &CreateBuiltInComponent<AudioListenerComponent>);
|
||||
}
|
||||
|
||||
void ComponentFactoryRegistry::RegisterFactory(const std::string& typeName, CreateComponentFn createFn) {
|
||||
if (typeName.empty() || !createFn) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto [it, inserted] = m_factories.insert_or_assign(typeName, createFn);
|
||||
(void)it;
|
||||
if (inserted) {
|
||||
m_registrationOrder.push_back(typeName);
|
||||
}
|
||||
}
|
||||
|
||||
Component* ComponentFactoryRegistry::CreateComponent(GameObject* gameObject, const std::string& typeName) const {
|
||||
if (!gameObject) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const auto it = m_factories.find(typeName);
|
||||
if (it == m_factories.end() || !it->second) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return it->second(gameObject);
|
||||
}
|
||||
|
||||
bool ComponentFactoryRegistry::IsRegistered(const std::string& typeName) const {
|
||||
return m_factories.find(typeName) != m_factories.end();
|
||||
}
|
||||
|
||||
const std::vector<std::string>& ComponentFactoryRegistry::GetRegisteredTypes() const {
|
||||
return m_registrationOrder;
|
||||
}
|
||||
|
||||
} // namespace Components
|
||||
} // namespace XCEngine
|
||||
@@ -1,10 +1,7 @@
|
||||
#include "Scene/Scene.h"
|
||||
#include "Components/ComponentFactoryRegistry.h"
|
||||
#include "Components/GameObject.h"
|
||||
#include "Components/TransformComponent.h"
|
||||
#include "Components/CameraComponent.h"
|
||||
#include "Components/LightComponent.h"
|
||||
#include "Components/AudioSourceComponent.h"
|
||||
#include "Components/AudioListenerComponent.h"
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <unordered_map>
|
||||
@@ -66,27 +63,6 @@ std::string UnescapeString(const std::string& value) {
|
||||
return unescaped;
|
||||
}
|
||||
|
||||
Component* CreateComponentByType(GameObject* gameObject, const std::string& type) {
|
||||
if (!gameObject) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (type == "Camera") {
|
||||
return gameObject->AddComponent<CameraComponent>();
|
||||
}
|
||||
if (type == "Light") {
|
||||
return gameObject->AddComponent<LightComponent>();
|
||||
}
|
||||
if (type == "AudioSource") {
|
||||
return gameObject->AddComponent<AudioSourceComponent>();
|
||||
}
|
||||
if (type == "AudioListener") {
|
||||
return gameObject->AddComponent<AudioListenerComponent>();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SerializeGameObjectRecursive(std::ostream& os, GameObject* gameObject) {
|
||||
if (!gameObject) {
|
||||
return;
|
||||
@@ -345,7 +321,7 @@ void Scene::DeserializeFromString(const std::string& data) {
|
||||
}
|
||||
|
||||
for (const PendingComponentData& componentData : pending.components) {
|
||||
if (Component* component = CreateComponentByType(go.get(), componentData.type)) {
|
||||
if (Component* component = ComponentFactoryRegistry::Get().CreateComponent(go.get(), componentData.type)) {
|
||||
if (!componentData.payload.empty()) {
|
||||
std::istringstream componentStream(componentData.payload);
|
||||
component->Deserialize(componentStream);
|
||||
|
||||
Reference in New Issue
Block a user