#ifndef U_CORE_OBJECTFACTORY_H #define U_CORE_OBJECTFACTORY_H #include "Core/Object.h" #include #include #include #include #include namespace uLib { /** * @brief Singleton factory for dynamic Object instantiation based on class * name. */ class ObjectFactory { public: typedef std::function 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 GetRegisteredClasses() const; private: ObjectFactory() = default; ~ObjectFactory() = default; // Prevent copy and assignment ObjectFactory(const ObjectFactory &) = delete; ObjectFactory &operator=(const ObjectFactory &) = delete; std::map m_factoryMap; }; /** * @brief Helper class to statically register a factory function. */ template 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 ULIB_REG_CONCAT( \ g_ObjectRegistrar_, __LINE__)(#className); #define ULIB_REGISTER_OBJECT_NAME(className, registeredName) \ static uLib::ObjectRegistrar 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 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 >> 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 m_model; }; } // namespace uLib #endif // U_CORE_OBJECTFACTORY_H