1 #pragma once 2 3 //******************************************************************************************** 4 //* 5 //* This file is part of Egoboo. 6 //* 7 //* Egoboo is free software: you can redistribute it and/or modify it 8 //* under the terms of the GNU General Public License as published by 9 //* the Free Software Foundation, either version 3 of the License, or 10 //* (at your option) any later version. 11 //* 12 //* Egoboo is distributed in the hope that it will be useful, but 13 //* WITHOUT ANY WARRANTY; without even the implied warranty of 14 //* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 //* General Public License for more details. 16 //* 17 //* You should have received a copy of the GNU General Public License 18 //* along with Egoboo. If not, see <http://www.gnu.org/licenses/>. 19 //* 20 //******************************************************************************************** 21 22 /// @file egoboo_object.h 23 /// @details Definitions of data that all Egoboo objects should "inherit" 24 25 #include "egoboo_typedef.h" 26 #include "egoboo_state_machine.h" 27 28 //-------------------------------------------------------------------------------------------- 29 //-------------------------------------------------------------------------------------------- 30 // some basic data that all Egoboo objects should have 31 32 /// The possible states of an obj_data_t object. The object is essentially 33 /// a state machine in the same way that the "egoboo process" is, so they use analagous 34 /// states 35 enum e_ego_object_state 36 { 37 ego_object_invalid = ego_state_invalid, 38 ego_object_constructing = ego_state_begin, ///< The object has been allocated and had it's critical variables filled with safe values 39 ego_object_initializing = ego_state_entering, ///< The object is being initialized/re-initialized 40 ego_object_active = ego_state_running, ///< The object is fully activated 41 ego_object_deinitializing = ego_state_leaving, ///< The object is being de-initialized 42 ego_object_destructing = ego_state_finish, ///< The object is being destructed 43 44 // the states that are specific to objects 45 ego_object_waiting, ///< The object has been fully destructed and is awaiting final "deletion" 46 ego_object_terminated ///< The object is fully "deleted" and should now be on the free-store 47 }; 48 typedef enum e_ego_object_state ego_object_state_t; 49 50 //-------------------------------------------------------------------------------------------- 51 52 /// The data that is "inherited" by every Egoboo object. 53 struct s_ego_object_base 54 { 55 // basic object definitions 56 STRING _name; ///< what is its "_name" 57 size_t index; ///< what is the index position in the object list? 58 ego_object_state_t state; ///< what state is it in? 59 Uint32 guid; ///< a globally unique identifier 60 61 // "process" control control 62 bool_t allocated; ///< Does it exist? 63 bool_t on; ///< Can it be accessed? 64 bool_t turn_me_on; ///< Has someone requested that the object be turned on? 65 bool_t kill_me; ///< Has someone requested that the object be destroyed? 66 bool_t spawning; ///< is the object in the midst of being created? 67 68 bool_t in_free_list; ///< the object is currently in the free list 69 bool_t in_used_list; ///< the object is currently in the used list 70 71 // things related to the updating of objects 72 size_t update_count; ///< How many updates have been made to this object? 73 size_t frame_count; ///< How many frames have been rendered? 74 75 unsigned update_guid; ///< a value that lets you know if an object bookmark is in synch with the object list 76 }; 77 78 typedef struct s_ego_object_base obj_data_t; 79 80 obj_data_t * ego_object_ctor( obj_data_t * pbase ); 81 obj_data_t * ego_object_dtor( obj_data_t * pbase ); 82 83 //-------------------------------------------------------------------------------------------- 84 //-------------------------------------------------------------------------------------------- 85 86 /// Mark a obj_data_t object as being allocated 87 #define POBJ_ALLOCATE( PDATA, INDEX ) \ 88 if( NULL != PDATA ) \ 89 { \ 90 (PDATA)->obj_base.allocated = btrue; \ 91 (PDATA)->obj_base.on = bfalse; \ 92 (PDATA)->obj_base.turn_me_on = bfalse; \ 93 (PDATA)->obj_base.kill_me = bfalse; \ 94 (PDATA)->obj_base.spawning = bfalse; \ 95 (PDATA)->obj_base.index = INDEX; \ 96 (PDATA)->obj_base.state = ego_object_constructing; \ 97 (PDATA)->obj_base.guid = ego_object_guid++; \ 98 } 99 100 /// Turn on an obj_data_t object 101 #define POBJ_ACTIVATE( PDATA, NAME ) \ 102 if( NULL != PDATA && (PDATA)->obj_base.allocated && !(PDATA)->obj_base.kill_me && ego_object_invalid != (PDATA)->obj_base.state ) \ 103 { \ 104 strncpy( (PDATA)->obj_base._name, NAME, SDL_arraysize((PDATA)->obj_base._name) ); \ 105 (PDATA)->obj_base.state = ego_object_active; \ 106 } 107 108 /// Begin turning off an obj_data_t object 109 #define POBJ_REQUEST_TERMINATE( PDATA ) \ 110 if( NULL != PDATA && (PDATA)->obj_base.allocated && ego_object_invalid != (PDATA)->obj_base.state ) \ 111 { \ 112 if( ego_object_terminated != (PDATA)->obj_base.state ) \ 113 { \ 114 (PDATA)->obj_base.kill_me = btrue; \ 115 } \ 116 (PDATA)->obj_base.on = bfalse; \ 117 } 118 119 /// Completely turn off an obj_data_t object and mark it as no longer allocated 120 #define POBJ_TERMINATE( PDATA ) \ 121 if( NULL != PDATA && (PDATA)->obj_base.allocated ) \ 122 { \ 123 (PDATA)->obj_base.allocated = bfalse; \ 124 (PDATA)->obj_base.on = bfalse; \ 125 (PDATA)->obj_base.state = ego_object_terminated; \ 126 } 127 128 #define POBJ_BEGIN_SPAWN( PDATA ) \ 129 if( NULL != PDATA && (PDATA)->obj_base.allocated ) \ 130 {\ 131 if( !(PDATA)->obj_base.spawning )\ 132 {\ 133 (PDATA)->obj_base.spawning = btrue;\ 134 ego_object_spawn_depth++;\ 135 }\ 136 }\ 137 138 #define POBJ_END_SPAWN( PDATA ) \ 139 if( NULL != PDATA && (PDATA)->obj_base.allocated ) \ 140 {\ 141 if( (PDATA)->obj_base.spawning )\ 142 {\ 143 (PDATA)->obj_base.spawning = bfalse;\ 144 ego_object_spawn_depth--;\ 145 }\ 146 }\ 147 148 /// Is the object flagged as requesting termination? 149 #define FLAG_ALLOCATED_PBASE( PBASE ) ( ( (PBASE)->allocated ) && (ego_object_invalid != (PBASE)->state) ) 150 /// Is the object allocated? 151 #define ALLOCATED_PBASE( PBASE ) FLAG_ALLOCATED_PBASE(PBASE) 152 153 /// Is the object flagged as requesting termination? 154 #define FLAG_ON_PBASE( PBASE ) ( (PBASE)->on ) 155 /// Is the object on? 156 #define ON_PBASE( PBASE ) ( FLAG_ON_PBASE(PBASE) && (ego_object_invalid != (PBASE)->state) ) 157 158 /// Is the object flagged as kill_me? 159 #define FLAG_REQ_TERMINATION_PBASE( PBASE ) ( (PBASE)->kill_me ) 160 /// Is the object kill_me? 161 #define REQ_TERMINATION_PBASE( PBASE ) ( FLAG_REQ_TERMINATION_PBASE(PBASE) && (ego_object_invalid != (PBASE)->state) ) 162 163 /// Has the object been created yet? 164 #define STATE_CONSTRUCTING_PBASE( PBASE ) ( ego_object_constructing == (PBASE)->state ) 165 /// Has the object been created yet? 166 #define CONSTRUCTING_PBASE( PBASE ) ( ALLOCATED_PBASE( PBASE ) && STATE_CONSTRUCTING_PBASE(PBASE) ) 167 168 /// Is the object in the initializing state? 169 #define STATE_INITIALIZING_PBASE( PBASE ) ( ego_object_initializing == (PBASE)->state ) 170 /// Is the object being initialized right now? 171 #define INITIALIZING_PBASE( PBASE ) ( ALLOCATED_PBASE( PBASE ) && STATE_INITIALIZING_PBASE(PBASE) ) 172 173 /// Is the object in the active state? 174 #define STATE_ACTIVE_PBASE( PBASE ) ( ego_object_active == (PBASE)->state ) 175 /// Is the object active? 176 #define ACTIVE_PBASE( PBASE ) ( ALLOCATED_PBASE( PBASE ) && STATE_ACTIVE_PBASE(PBASE) ) 177 178 /// Is the object in the deinitializing state? 179 #define STATE_DEINITIALIZING_PBASE( PBASE ) ( ego_object_deinitializing == (PBASE)->state ) 180 /// Is the object being deinitialized right now? 181 #define DEINITIALIZING_PBASE( PBASE ) ( ALLOCATED_PBASE( PBASE ) && STATE_DEINITIALIZING_PBASE(PBASE) ) 182 183 /// Is the object in the destructing state? 184 #define STATE_DESTRUCTING_PBASE( PBASE ) ( ego_object_destructing == (PBASE)->state ) 185 /// Is the object being deinitialized right now? 186 #define DESTRUCTING_PBASE( PBASE ) ( ALLOCATED_PBASE( PBASE ) && STATE_DESTRUCTING_PBASE(PBASE) ) 187 188 /// Is the object "waiting to die" state? 189 #define STATE_WAITING_PBASE( PBASE ) ( ego_object_waiting == (PBASE)->state ) 190 /// Is the object "waiting to die"? 191 #define WAITING_PBASE( PBASE ) ( ALLOCATED_PBASE( PBASE ) && STATE_WAITING_PBASE(PBASE) ) 192 193 /// Has the object in the terminated state? 194 #define STATE_TERMINATED_PBASE( PBASE ) ( ego_object_terminated == (PBASE)->state ) 195 /// Has the object been marked as terminated? 196 #define TERMINATED_PBASE( PBASE ) STATE_TERMINATED_PBASE(PBASE) 197 198 /// Grab a pointer to the obj_data_t of an object that "inherits" this data 199 #define POBJ_GET_PBASE( POBJ ) ( &((POBJ)->obj_base) ) 200 201 /// Grab the index value of object that "inherits" from obj_data_t 202 #define GET_INDEX_POBJ( POBJ, FAIL_VALUE ) ( !ALLOCATED_PBASE( POBJ_GET_PBASE( POBJ ) ) ? FAIL_VALUE : (POBJ)->obj_base.index ) 203 #define GET_REF_POBJ( POBJ, FAIL_VALUE ) ((REF_T)GET_INDEX_POBJ( POBJ, FAIL_VALUE )) 204 205 /// Grab the state of object that "inherits" from obj_data_t 206 #define GET_STATE_POBJ( POBJ ) ( !ALLOCATED_PBASE( POBJ_GET_PBASE( POBJ ) ) ? ego_object_invalid : (POBJ)->obj_base.index ) 207 208 //-------------------------------------------------------------------------------------------- 209 //-------------------------------------------------------------------------------------------- 210 211 /// A variable to hold the object guid counter 212 extern Uint32 ego_object_guid; 213 214 extern Uint32 ego_object_spawn_depth; 215 216 //-------------------------------------------------------------------------------------------- 217 //-------------------------------------------------------------------------------------------- 218 #define egoboo_object_h