143 lines
4.0 KiB
C++
143 lines
4.0 KiB
C++
#ifndef U_CORE_OBJECTFACTORY_H
|
|
#define U_CORE_OBJECTFACTORY_H
|
|
|
|
#include "Core/Object.h"
|
|
#include <functional>
|
|
#include <map>
|
|
#include <string>
|
|
#include <type_traits>
|
|
#include <vector>
|
|
|
|
namespace uLib {
|
|
|
|
/**
|
|
* @brief Singleton factory for dynamic Object instantiation based on class
|
|
* name.
|
|
*/
|
|
class ObjectFactory {
|
|
public:
|
|
typedef std::function<Object *()> FactoryFunction;
|
|
|
|
/** @brief Get the singleton instance. */
|
|
static ObjectFactory &Instance();
|
|
|
|
/** @brief Register a factory function for a given class name. */
|
|
void Register(const std::string &className, FactoryFunction func);
|
|
|
|
/** @brief Create a new instance of the specified class. */
|
|
Object *Create(const std::string &className);
|
|
|
|
/** @brief Get the names of all registered classes. */
|
|
std::vector<std::string> GetRegisteredClasses() const;
|
|
|
|
private:
|
|
ObjectFactory() = default;
|
|
~ObjectFactory() = default;
|
|
|
|
// Prevent copy and assignment
|
|
ObjectFactory(const ObjectFactory &) = delete;
|
|
ObjectFactory &operator=(const ObjectFactory &) = delete;
|
|
|
|
std::map<std::string, FactoryFunction> m_factoryMap;
|
|
};
|
|
|
|
/**
|
|
* @brief Helper class to statically register a factory function.
|
|
*/
|
|
template <typename T> class ObjectRegistrar {
|
|
public:
|
|
ObjectRegistrar(const std::string &className) {
|
|
ObjectFactory::Instance().Register(className,
|
|
[]() -> Object * { return new T(); });
|
|
}
|
|
};
|
|
|
|
#define ULIB_REG_CONCAT_IMPL(a, b) a##b
|
|
#define ULIB_REG_CONCAT(a, b) ULIB_REG_CONCAT_IMPL(a, b)
|
|
|
|
/**
|
|
* @brief Macro to register a class to the factory.
|
|
* Put this in the .cpp file of the class.
|
|
*/
|
|
#define ULIB_REGISTER_OBJECT(className) \
|
|
static uLib::ObjectRegistrar<className> ULIB_REG_CONCAT( \
|
|
g_ObjectRegistrar_, __LINE__)(#className);
|
|
|
|
#define ULIB_REGISTER_OBJECT_NAME(className, registeredName) \
|
|
static uLib::ObjectRegistrar<className> ULIB_REG_CONCAT( \
|
|
g_ObjectRegistrar_, __LINE__)(registeredName);
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
* @brief Utility wrapper that bridges factory registration and shared ownership.
|
|
*
|
|
* ObjectWrapper provides a high-level interface to handle objects that can be
|
|
* both registered in the ObjectFactory and managed through shared ownership
|
|
* using SmartPointer.
|
|
*
|
|
* One of its key roles is static registration: when instantiated with a
|
|
* class name string, it automatically registers a factory function for type T
|
|
* in the ObjectFactory singleton. This allows the factory to subsequently
|
|
* create instances of T dynamically by name.
|
|
*
|
|
* It supports multiple initialization paths, including factory-based
|
|
* construction and direct model wrapping.
|
|
*/
|
|
template <typename T> class ObjectWrapper {
|
|
public:
|
|
ObjectWrapper(const std::string &className) {
|
|
ObjectFactory::Instance().Register(className,
|
|
[]() -> Object * { return new T(); });
|
|
}
|
|
|
|
ObjectWrapper(T *model) : m_model(model) {}
|
|
ObjectWrapper(T &model) : m_model(model) {}
|
|
|
|
template <typename U = T,
|
|
typename = std::enable_if_t<std::is_default_constructible_v<U>>>
|
|
ObjectWrapper() : m_model(new T()) {}
|
|
|
|
ObjectWrapper(const ObjectWrapper &other) : m_model(other.m_model) {}
|
|
|
|
ObjectWrapper &operator=(const ObjectWrapper &other) {
|
|
m_model = other.m_model;
|
|
return *this;
|
|
}
|
|
|
|
ObjectWrapper(ObjectWrapper &&other) noexcept
|
|
: m_model(std::move(other.m_model)) {}
|
|
|
|
ObjectWrapper &operator=(ObjectWrapper &&other) noexcept {
|
|
m_model = std::move(other.m_model);
|
|
return *this;
|
|
}
|
|
|
|
~ObjectWrapper() = default;
|
|
|
|
T *operator->() const { return m_model.get(); }
|
|
|
|
T &operator*() const { return *m_model; }
|
|
|
|
T *GetWrapped() const { return m_model.get(); }
|
|
|
|
bool operator==(const ObjectWrapper &other) const {
|
|
return m_model == other.m_model;
|
|
}
|
|
|
|
bool operator!=(const ObjectWrapper &other) const {
|
|
return m_model != other.m_model;
|
|
}
|
|
|
|
explicit operator bool() const { return m_model != nullptr; }
|
|
|
|
protected:
|
|
SmartPointer<T> m_model;
|
|
};
|
|
|
|
} // namespace uLib
|
|
|
|
#endif // U_CORE_OBJECTFACTORY_H
|