| #ifndef _RIVE_IMPORT_STACK_HPP_ | |
| #define _RIVE_IMPORT_STACK_HPP_ | |
| #include "rive/status_code.hpp" | |
| #include <algorithm> | |
| #include <unordered_map> | |
| #include <vector> | |
| #include <algorithm> | |
| namespace rive { | |
| class ImportStackObject { | |
| public: | |
| virtual ~ImportStackObject() {} | |
| virtual StatusCode resolve() { return StatusCode::Ok; } | |
| virtual bool readNullObject() { return false; } | |
| }; | |
| class ImportStack { | |
| private: | |
| std::unordered_map<uint16_t, ImportStackObject*> m_Latests; | |
| std::vector<ImportStackObject*> m_LastAdded; | |
| public: | |
| template <typename T = ImportStackObject> T* latest(uint16_t coreType) { | |
| auto itr = m_Latests.find(coreType); | |
| if (itr == m_Latests.end()) { | |
| return nullptr; | |
| } | |
| return reinterpret_cast<T*>(itr->second); | |
| } | |
| StatusCode makeLatest(uint16_t coreType, ImportStackObject* object) { | |
| // Clean up the old object in the stack. | |
| auto itr = m_Latests.find(coreType); | |
| if (itr != m_Latests.end()) { | |
| auto stackObject = itr->second; | |
| // Remove it from latests. | |
| auto itr = std::find(m_LastAdded.begin(), m_LastAdded.end(), stackObject); | |
| if (itr != m_LastAdded.end()) { | |
| m_LastAdded.erase(itr); | |
| } | |
| StatusCode code = stackObject->resolve(); | |
| delete stackObject; | |
| if (code != StatusCode::Ok) { | |
| m_Latests.erase(coreType); | |
| return code; | |
| } | |
| } | |
| // Set the new one. | |
| if (object == nullptr) { | |
| m_Latests.erase(coreType); | |
| } else { | |
| m_Latests[coreType] = object; | |
| m_LastAdded.push_back(object); | |
| } | |
| return StatusCode::Ok; | |
| } | |
| StatusCode resolve() { | |
| for (auto& pair : m_Latests) { | |
| StatusCode code = pair.second->resolve(); | |
| if (code != StatusCode::Ok) { | |
| return code; | |
| } | |
| } | |
| return StatusCode::Ok; | |
| } | |
| ~ImportStack() { | |
| for (auto& pair : m_Latests) { | |
| delete pair.second; | |
| } | |
| } | |
| bool readNullObject() { | |
| for (auto itr = m_LastAdded.rbegin(); itr != m_LastAdded.rend(); itr++) { | |
| if ((*itr)->readNullObject()) { | |
| return true; | |
| } | |
| } | |
| return false; | |
| } | |
| }; | |
| } // namespace rive | |
| #endif |