// Copyright (c) 2023 Alex Diener. All rights reserved. #include "PROJECT_NAME/GameEntity.h" #include "PROJECT_NAME/RoomState.h" #include "PROJECT_NAME/SharedDefinitions.h" #include "PROJECT_NAME/Sprites.h" #include "PROJECT_NAME/Utilities.h" #include #define stemobject_implementation GameEntity stemobject_vtable_begin(); stemobject_vtable_entry(createWithEncodedState); stemobject_vtable_entry(initWithEncodedState); stemobject_vtable_entry(dispose); stemobject_vtable_entry(copy); stemobject_vtable_entry(initCopy); stemobject_vtable_entry(postinit); stemobject_vtable_entry(getComponent); stemobject_vtable_entry(roomEntered); stemobject_vtable_entry(roomExited); stemobject_vtable_entry(preadvance); stemobject_vtable_entry(advanceTurn); stemobject_vtable_entry(postadvance); stemobject_vtable_entry(isEqual); stemobject_vtable_entry(encodeState); stemobject_vtable_entry(xorState); stemobject_vtable_entry(enumerateProperties); stemobject_vtable_entry(undoActionPerformed); stemobject_vtable_end(); bool GameEntity_init(GameEntity * self, struct RoomState * roomState) { static unsigned int nextEntityID; call_super(init, self); self->roomState = roomState; self->entityID = nextEntityID++; self->markedForRemoval = false; return true; } GameEntity * GameEntity_createWithEncodedState(struct memreadContext * memreadContext, struct RoomState * roomState) { #ifdef DEBUG fprintf(stderr, "GameEntity_createWithEncodedState() must be overridden\n"); #endif abort(); return NULL; } static void initWithEncodedStateCallback(void * address, GameEntity_propertyType type, void * context) { struct memreadContext * memreadContext = context; switch (type) { case PROPERTY_TYPE_Vector2i_int8_t: { Vector2i * value = address; memreadPrimitive(memreadContext, value->x, int8_t); memreadPrimitive(memreadContext, value->y, int8_t); break; } case PROPERTY_TYPE_bool: { bool * value = address; memreadPrimitive(memreadContext, *value, uint8_t); break; } case PROPERTY_TYPE_uint8_t: { uint8_t * value = address; memreadPrimitive(memreadContext, *value, uint8_t); break; } case PROPERTY_TYPE_uint16_t: { uint16_t * value = address; memreadPrimitive(memreadContext, *value, uint16_t); break; } case PROPERTY_TYPE_uint32_t: { uint32_t * value = address; memreadPrimitive(memreadContext, *value, uint32_t); break; } } } void GameEntity_initWithEncodedState(GameEntity * self, struct memreadContext * memreadContext, struct RoomState * roomState) { call_super(init, self); self->roomState = roomState; self->markedForRemoval = false; call_virtual(enumerateProperties, self, false, initWithEncodedStateCallback, memreadContext); } void GameEntity_dispose(GameEntity * self) { call_super_virtual(dispose, self); } GameEntity * GameEntity_copy(GameEntity * self, struct RoomState * roomState) { #ifdef DEBUG fprintf(stderr, "GameEntity_copy() must be overridden\n"); #endif abort(); return NULL; } void GameEntity_initCopy(GameEntity * self, compat_type(GameEntity *) originalUntyped, struct RoomState * roomState) { call_super(init, self); GameEntity * original = originalUntyped; self->entityID = original->entityID; self->roomState = roomState; self->markedForRemoval = original->markedForRemoval; } void GameEntity_postinit(GameEntity * self) { } compat_type(GameEntityComponent *) GameEntity_getComponent(GameEntity * self, ComponentType type) { return NULL; } void GameEntity_roomEntered(GameEntity * self) { } void GameEntity_roomExited(GameEntity * self) { } void GameEntity_preadvance(GameEntity * self) { } void GameEntity_advanceTurn(GameEntity * self) { } void GameEntity_postadvance(GameEntity * self) { } bool GameEntity_isEqual(GameEntity * self, GameEntity * compare) { return true; } static void encodeStateCallback(void * address, GameEntity_propertyType type, void * context) { struct memwriteContext * memwriteContext = context; switch (type) { case PROPERTY_TYPE_Vector2i_int8_t: { Vector2i * value = address; memwritePrimitive(memwriteContext, value->x, int8_t); memwritePrimitive(memwriteContext, value->y, int8_t); break; } case PROPERTY_TYPE_bool: { bool * value = address; memwritePrimitive(memwriteContext, *value, uint8_t); break; } case PROPERTY_TYPE_uint8_t: { uint8_t * value = address; memwritePrimitive(memwriteContext, *value, uint8_t); break; } case PROPERTY_TYPE_uint16_t: { uint16_t * value = address; memwritePrimitive(memwriteContext, *value, uint16_t); break; } case PROPERTY_TYPE_uint32_t: { uint32_t * value = address; memwritePrimitive(memwriteContext, *value, uint32_t); break; } } } void GameEntity_encodeState(GameEntity * self, struct memwriteContext * memwriteContext, bool transient) { call_virtual(enumerateProperties, self, transient, encodeStateCallback, memwriteContext); } static void xorStateCallback(void * address, GameEntity_propertyType type, void * context) { struct memreadContext * memreadContext = context; switch (type) { case PROPERTY_TYPE_Vector2i_int8_t: { Vector2i * value = address; memreadXorPrimitive(memreadContext, value->x, int8_t); memreadXorPrimitive(memreadContext, value->y, int8_t); break; } case PROPERTY_TYPE_bool: { bool * value = address; memreadXorPrimitive(memreadContext, *value, uint8_t); break; } case PROPERTY_TYPE_uint8_t: { uint8_t * value = address; memreadXorPrimitive(memreadContext, *value, uint8_t); break; } case PROPERTY_TYPE_uint16_t: { uint16_t * value = address; memreadXorPrimitive(memreadContext, *value, uint16_t); break; } case PROPERTY_TYPE_uint32_t: { uint32_t * value = address; memreadXorPrimitive(memreadContext, *value, uint32_t); break; } } } void GameEntity_xorState(GameEntity * self, struct memreadContext * memreadContext) { call_virtual(enumerateProperties, self, true, xorStateCallback, memreadContext); } void GameEntity_enumerateProperties(GameEntity * self, bool transient, GameEntity_enumeratePropertiesCallback callback, void * context) { if (!transient) { callback(&self->entityID, PROPERTY_TYPE_uint32_t, context); } } void GameEntity_undoActionPerformed(GameEntity * self) { }