mirror of
https://github.com/HarbourMasters/Shipwright.git
synced 2025-04-28 13:17:58 +03:00
Add in ActorExtension system
This commit is contained in:
parent
c5e0e32391
commit
b27eb59e2b
3 changed files with 114 additions and 0 deletions
78
soh/soh/ActorExtension/ActorExtension.cpp
Normal file
78
soh/soh/ActorExtension/ActorExtension.cpp
Normal file
|
@ -0,0 +1,78 @@
|
|||
#include "ActorExtension.h"
|
||||
|
||||
static ActorExtensionId sNextId = 0;
|
||||
|
||||
struct ActorExtensionKeyHash {
|
||||
std::size_t operator()(const std::pair<Actor*, ActorExtensionId>& key) const {
|
||||
return std::hash<Actor*>{}(key.first) ^ (std::hash<ActorExtensionId>{}(key.second) << 1);
|
||||
}
|
||||
};
|
||||
|
||||
static std::unordered_map<ActorExtensionId, size_t> sGlobalSizes;
|
||||
static std::unordered_map<s16, std::unordered_map<ActorExtensionId, size_t>> sSizes;
|
||||
static std::unordered_map<std::pair<Actor*, ActorExtensionId>, void*, ActorExtensionKeyHash> sData;
|
||||
|
||||
void* ActorExtension_Get(Actor* actor, ActorExtensionId id) {
|
||||
if (actor == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto it = sData.find(std::make_pair(actor, id));
|
||||
if (it == sData.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
ActorExtensionId ActorExtension_CreateForId(int16_t actorId, size_t size) {
|
||||
ActorExtensionId id = ++sNextId;
|
||||
sSizes[actorId][id] = size;
|
||||
return id;
|
||||
}
|
||||
|
||||
ActorExtensionId ActorExtension_CreateForAll(size_t size) {
|
||||
ActorExtensionId id = ++sNextId;
|
||||
sGlobalSizes[id] = size;
|
||||
return id;
|
||||
}
|
||||
|
||||
void ActorExtension_Alloc(Actor* actor, int16_t actorId) {
|
||||
if (actor == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& [id, size] : sGlobalSizes) {
|
||||
void* data = malloc(size);
|
||||
memset(data, 0, size);
|
||||
sData[std::make_pair(actor, id)] = data;
|
||||
}
|
||||
|
||||
for (auto& [id, size] : sSizes[actorId]) {
|
||||
void* data = malloc(size);
|
||||
memset(data, 0, size);
|
||||
sData[std::make_pair(actor, id)] = data;
|
||||
}
|
||||
}
|
||||
|
||||
void ActorExtension_Free(Actor* actor) {
|
||||
if (actor == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& [ id, size ] : sGlobalSizes) {
|
||||
auto it = sData.find(std::make_pair(actor, id));
|
||||
if (it != sData.end()) {
|
||||
free(it->second);
|
||||
sData.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& [id, size] : sSizes[actor->id]) {
|
||||
auto it = sData.find(std::make_pair(actor, id));
|
||||
if (it != sData.end()) {
|
||||
free(it->second);
|
||||
sData.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
27
soh/soh/ActorExtension/ActorExtension.h
Normal file
27
soh/soh/ActorExtension/ActorExtension.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
#ifndef ACTOR_EXTENSION_H
|
||||
#define ACTOR_EXTENSION_H
|
||||
|
||||
#include <libultraship/libultraship.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#include <z64actor.h>
|
||||
#endif
|
||||
|
||||
typedef uint32_t ActorExtensionId;
|
||||
|
||||
void* ActorExtension_Get(Actor* actor, ActorExtensionId id);
|
||||
|
||||
// These should only ever be called once, before any actors are spawned
|
||||
ActorExtensionId ActorExtension_CreateForId(int16_t actorId, size_t size);
|
||||
ActorExtensionId ActorExtension_CreateForAll(size_t size);
|
||||
|
||||
// Internal, you shouldn't have to touch these
|
||||
void ActorExtension_Alloc(Actor* actor, int16_t actorId);
|
||||
void ActorExtension_Free(Actor* actor);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //ACTOR_EXTENSION_H
|
|
@ -1,4 +1,5 @@
|
|||
#include "global.h"
|
||||
#include "soh/ActorExtension/ActorExtension.h"
|
||||
#include "vt.h"
|
||||
|
||||
#include "overlays/actors/ovl_Arms_Hook/z_arms_hook.h"
|
||||
|
@ -3352,6 +3353,10 @@ Actor* Actor_Spawn(ActorContext* actorCtx, PlayState* play, s16 actorId, f32 pos
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// #region SOH [ActorExtension]
|
||||
ActorExtension_Alloc(actor, dbEntry->id);
|
||||
// #endregion
|
||||
|
||||
assert(dbEntry->numLoaded < 255);
|
||||
|
||||
dbEntry->numLoaded++;
|
||||
|
@ -3494,6 +3499,10 @@ Actor* Actor_Delete(ActorContext* actorCtx, Actor* actor, PlayState* play) {
|
|||
|
||||
newHead = Actor_RemoveFromCategory(play, actorCtx, actor);
|
||||
|
||||
// #region SOH [ActorExtension]
|
||||
ActorExtension_Free(actor);
|
||||
// #endregion
|
||||
|
||||
ZELDA_ARENA_FREE_DEBUG(actor);
|
||||
|
||||
dbEntry->numLoaded--;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue