2023-05-12 23:15:35 +00:00
|
|
|
#include <map>
|
2023-05-15 19:03:57 +00:00
|
|
|
#include <vector>
|
2023-05-12 23:15:35 +00:00
|
|
|
#include "dynos.cpp.h"
|
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
#include "engine/geo_layout.h"
|
|
|
|
#include "engine/graph_node.h"
|
|
|
|
}
|
|
|
|
|
2023-05-15 19:03:57 +00:00
|
|
|
struct ScheduledFreePool {
|
|
|
|
struct DynamicPool* pool;
|
|
|
|
u32 timeout;
|
|
|
|
};
|
|
|
|
|
2023-05-13 01:53:25 +00:00
|
|
|
static struct DynamicPool* sModelPools[MODEL_POOL_MAX] = { 0 };
|
2023-05-12 23:15:35 +00:00
|
|
|
static std::map<void*, struct GraphNode*> sModelMap[MODEL_POOL_MAX];
|
2023-05-15 19:03:57 +00:00
|
|
|
static std::vector<struct ScheduledFreePool> sPoolsToFree;
|
2023-05-12 23:15:35 +00:00
|
|
|
|
|
|
|
struct GraphNode* DynOS_Model_LoadGeo(enum ModelPool aModelPool, void* aAsset) {
|
|
|
|
// sanity check pool
|
|
|
|
if (aModelPool >= MODEL_POOL_MAX) { return NULL; }
|
|
|
|
|
|
|
|
// allocate pool
|
|
|
|
if (!sModelPools[aModelPool]) {
|
2023-05-13 01:53:25 +00:00
|
|
|
sModelPools[aModelPool] = dynamic_pool_init();
|
2023-05-12 23:15:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// check map
|
|
|
|
auto& map = sModelMap[aModelPool];
|
|
|
|
if (map.count(aAsset)) {
|
|
|
|
return map[aAsset];
|
|
|
|
}
|
|
|
|
|
|
|
|
// load geo
|
|
|
|
struct GraphNode* node = process_geo_layout(sModelPools[aModelPool], aAsset);
|
|
|
|
|
|
|
|
// store and return geo
|
|
|
|
map[aAsset] = node;
|
|
|
|
return node;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct GraphNode* DynOS_Model_LoadDl(enum ModelPool aModelPool, u8 aLayer, void* aAsset) {
|
|
|
|
// sanity check pool
|
|
|
|
if (aModelPool >= MODEL_POOL_MAX) { return NULL; }
|
|
|
|
|
|
|
|
// allocate pool
|
|
|
|
if (!sModelPools[aModelPool]) {
|
2023-05-13 01:53:25 +00:00
|
|
|
sModelPools[aModelPool] = dynamic_pool_init();
|
2023-05-12 23:15:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// check map
|
|
|
|
auto& map = sModelMap[aModelPool];
|
|
|
|
if (map.count(aAsset)) {
|
|
|
|
return map[aAsset];
|
|
|
|
}
|
|
|
|
|
|
|
|
// load geo
|
|
|
|
struct GraphNode* node = (struct GraphNode *) init_graph_node_display_list(sModelPools[aModelPool], NULL, aLayer, aAsset);
|
|
|
|
|
|
|
|
// store and return geo
|
|
|
|
map[aAsset] = node;
|
|
|
|
return node;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DynOS_Model_ClearPool(enum ModelPool aModelPool) {
|
|
|
|
if (!sModelPools[aModelPool]) { return; }
|
|
|
|
|
2023-05-15 19:03:57 +00:00
|
|
|
// schedule pool to be freed
|
|
|
|
sPoolsToFree.push_back({
|
|
|
|
.pool = sModelPools[aModelPool],
|
|
|
|
.timeout = 30
|
|
|
|
});
|
|
|
|
|
|
|
|
// clear pointer
|
2023-05-12 23:15:35 +00:00
|
|
|
sModelPools[aModelPool] = NULL;
|
|
|
|
|
|
|
|
// clear map
|
|
|
|
auto& map = sModelMap[aModelPool];
|
|
|
|
map.clear();
|
|
|
|
}
|
2023-05-15 19:03:57 +00:00
|
|
|
|
|
|
|
void DynOS_Model_Update() {
|
|
|
|
for (auto it = sPoolsToFree.begin(); it != sPoolsToFree.end(); ) {
|
|
|
|
if (--it->timeout <= 0) {
|
|
|
|
dynamic_pool_free_pool(it->pool);
|
|
|
|
it = sPoolsToFree.erase(it);
|
|
|
|
} else {
|
|
|
|
it++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|