#ifndef HECLRUNTIME_HPP #define HECLRUNTIME_HPP #include #include #include #include "HECL.hpp" namespace HECL { namespace Runtime { class Entity { public: enum Type { ENTITY_NONE, ENTITY_OBJECT, ENTITY_GROUP }; private: Type m_type; const std::string& m_path; bool m_loaded = false; friend class Group; friend class ObjectBase; Entity(Type type, const std::string& path) : m_type(type), m_path(path) {} public: /** * @brief Get type of runtime object * @return Type enum */ inline Type getType() const {return m_type;} /** * @brief Get database entity path * @return Path string */ inline const std::string& getPath() const {return m_path;} /** * @brief Determine if object is fully loaded and constructed * @return true if so */ inline bool isLoaded() const {return m_loaded;} }; /** * @brief Interface representing a load-ordered group of runtime objects * * HLPK files perform all data retrieval using the notion of 'groups' * Groups are a collection of data objects that have been sequentially packed * in the package file and are constructed in the indexed order of the group. * * RuntimeGroup objects are internally created and weakly-referenced by CRuntime. * RuntimeObject objects are weakly-referenced by RuntimeGroup; they're strongly * referenced by application systems as long as they're needed. * * DO NOT CONSTRUCT THIS DIRECTLY!! */ class Group : public Entity { public: typedef std::vector> GroupObjectsVector; private: friend class HECLRuntime; GroupObjectsVector m_objects; Group(const std::string& path) : Entity(ENTITY_GROUP, path) {} public: inline const GroupObjectsVector& getObjects() const {return m_objects;} }; /** * @brief Base object to subclass for integrating with key runtime operations * * All runtime objects are provided with IDataObject pointers to their database * entries. Subclasses register themselves with a type registry so instances * are automatically constructed when performing operations like runtime-integration. * * DO NOT CONSTRUCT THIS OR SUBCLASSES DIRECTLY!! */ class ObjectBase : public Entity { std::shared_ptr m_parent; protected: /** * @brief Optional subclass method called on background thread or in response to interrupt when data is ready * @param data fully-loaded data buffer * @param len length of buffer * @return true when data is successfully integrated into the runtime */ virtual bool _objectFinishedLoading(const void* data, size_t len) {(void)data;(void)len;return true;} /** * @brief Optional subclass method called in response to reference-count dropping to 0 */ virtual void _objectWillUnload() {} public: ObjectBase(const Group* group, const std::string& path) : Entity(ENTITY_OBJECT, path), m_parent(group) {} /** * @brief Get parent group of object * @return Borrowed pointer of parent RuntimeGroup */ inline const Group* getParentGroup() {return m_parent.get();} }; /** * @brief Loadable/Bindable runtime texture class */ class Texture { }; /** * @brief Bindable runtime material class */ class Material { }; /** * @brief Bindable runtime mesh surface */ class MeshSurface { }; /** * @brief Loadable data representation containing vertex buffers, surfaces and shader refs */ class MeshObject { public: }; /** * @brief HLPK Runtime data-management root * * Interface for controlling runtime data-operations like object lookup * and burst load-transactions using HLPK packages. The runtime's * implementation automatically constructs RuntimeObjectBase and * RuntimeGroup instances as needed. */ class Runtime { public: /** * @brief Constructs the HECL runtime root * @param hlpkDirectory directory to search for .hlpk files */ Runtime(const SystemString& hlpkDirectory); ~Runtime(); /** * @brief Structure indicating the load status of an object group */ struct SGroupLoadStatus { std::atomic_bool done; std::atomic_size_t completedObjects; std::atomic_size_t totalObjects; }; /** * @brief Begin a synchronous group-load transaction * @param pathHash Hashed path string to perform lookup * @return Shared reference to the loading/loaded object * * This method blocks until the entire containing-group is loaded. * Paths to groups or individual objects are accepted. */ std::shared_ptr loadSync(const Hash& pathHash); /** * @brief Begin an asynchronous group-load transaction * @param pathHash Hashed path string to perform lookup * @param statusOut Optional atomically-pollable structure updated with status fields * @return Shared reference to the loading/loaded object * * This method returns once all group entity stubs are constructed. * Paths to groups or individual objects are accepted. */ std::shared_ptr loadAsync(const Hash& pathHash, SGroupLoadStatus* statusOut=NULL); }; } } #endif // HECLRUNTIME_HPP