gcsx_rundata.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /* GCSx
  2. ** RUNDATA.H
  3. **
  4. ** Runtime data support- stacks, variables, hashes, arrays
  5. */
  6. /*****************************************************************************
  7. ** Copyright (C) 2003-2006 Janson
  8. **
  9. ** This program is free software; you can redistribute it and/or modify
  10. ** it under the terms of the GNU General Public License as published by
  11. ** the Free Software Foundation; either version 2 of the License, or
  12. ** (at your option) any later version.
  13. **
  14. ** This program is distributed in the hope that it will be useful,
  15. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. ** GNU General Public License for more details.
  18. **
  19. ** You should have received a copy of the GNU General Public License
  20. ** along with this program; if not, write to the Free Software
  21. ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
  22. *****************************************************************************/
  23. #ifndef __GCSx_RUNDATA_H_
  24. #define __GCSx_RUNDATA_H_
  25. // Subtypes for entitys/objects
  26. enum {
  27. // Type unknown/any (within entity domain or object domain only)
  28. SUB_NONE = 0,
  29. // Actual built-in types go here
  30. SUB_SPRITE = 1,
  31. SUB_SCENE = 2,
  32. SUB_ENTITY = 255,
  33. // The start of user script type ids
  34. SUB_ENTITY_FIRST = 256
  35. };
  36. // Stack entry/data types
  37. enum {
  38. STACK_UNDEF = 0,
  39. // Basic types match up with opcode modes
  40. STACK_INT = 1, // i
  41. STACK_FLOAT = 2, // f
  42. STACK_STRING = 3, // p(string), owned by us
  43. STACK_ARRAY = 5, // p(Array), reference counted
  44. STACK_HASH = 6, // p(Hash), reference counted
  45. STACK_ENTITY = 7, // p(Entity) subtype must be manually looked up if needed
  46. STACK_OBJECT = 8, // p(ObjectBase) subtype must be manually looked up if needed
  47. STACK_BASETYPE = 15, // bitmask/maximum
  48. STACK_INDIRECT = 16, // Added to 1-15, becomes p(RunData)
  49. STACK_REPLYPTR = 32, // p(StackEntry); added to 1-15
  50. STACK_CODEPTR = 48, // p(Uint32)
  51. STACK_RETURNPTR = 49, // p(StackEntry)
  52. STACK_TYPE_COUNT = 50
  53. };
  54. // Data stored in our data structures
  55. // i)nteger, f)loat, p)ointer (various types)
  56. union RunData {
  57. Sint32 i;
  58. BCfloat f;
  59. void* p;
  60. };
  61. // Built-in object types, base class
  62. class ObjectBase {
  63. public:
  64. // May be any number of members- based on object type
  65. RunData* members;
  66. int subtype;
  67. // 0 = destroy (counted manually for speed/simplicity)
  68. // As long as positive, object must NOT delete itself
  69. // unless game is unloading.
  70. int ref;
  71. // @TODO: way to handle member functions
  72. };
  73. // Reference-counted hashes/arrays
  74. // @TODO: better method without storing RunData-sized items?
  75. // do as manual dyn-array similar to stacks?
  76. struct Array {
  77. int ref; // 0 = destroy
  78. int type;
  79. int subtype;
  80. std::vector<RunData> data;
  81. };
  82. struct Hash {
  83. int ref; // 0 = destroy
  84. int type;
  85. int subtype;
  86. // @TODO: be wary of deleting the keys before the entries/clearing
  87. // note that this is case-sensitive! (and will remain so)
  88. typedef hash_map<const char*, RunData, hash<const char*>, hash_eqstr> Data;
  89. Data data;
  90. };
  91. // Hash/array reference counting
  92. // Decreases assume you are discarding your ptr
  93. inline void refIncArray(Array* a) {
  94. ++a->ref;
  95. }
  96. inline void refDecArray(Array* a) {
  97. interpretAssert(a->ref > 0);
  98. if (--a->ref == 0) {
  99. // @TODO: delete strings/objects within array
  100. delete a;
  101. }
  102. }
  103. inline void refIncHash(Hash* h) {
  104. ++h->ref;
  105. }
  106. inline void refDecHash(Hash* h) {
  107. interpretAssert(h->ref > 0);
  108. if (--h->ref == 0) {
  109. // @TODO: delete strings/objects within hash
  110. delete h;
  111. }
  112. }
  113. // Also used for global variables, for consistency
  114. struct StackEntry {
  115. RunData data;
  116. int type;
  117. };
  118. // Not OOP to streamline+optimize
  119. struct Stack {
  120. StackEntry* data;
  121. StackEntry* top; // Points to one past top element
  122. StackEntry* allocSize; // Points to one past last allocated element
  123. };
  124. // Slower functions
  125. void createStack(Stack* s);
  126. void destroyStack(Stack* s);
  127. void increaseStack(Stack* s);
  128. // Ensure room for another push
  129. inline void prepStack(Stack& s) {
  130. if (s.top == s.allocSize)
  131. increaseStack(&s);
  132. }
  133. inline void prepStack(Stack* s) {
  134. if (s->top == s->allocSize)
  135. increaseStack(s);
  136. }
  137. // Stack Entry dereferencing functions- assumes you're discarding or overwriting
  138. // it afterwards so doesn't entirely/safely clean it for further use
  139. // @TODO: just inline into deref* functions if we don't call them elsewhere
  140. inline void seDerefString(StackEntry* s) {
  141. interpretAssert(s->type == STACK_STRING);
  142. delete (std::string*)s->data.p;
  143. }
  144. inline void seDerefArray(StackEntry* s) {
  145. interpretAssert(s->type == STACK_ARRAY);
  146. refDecArray((Array*)s->data.p);
  147. }
  148. inline void seDerefHash(StackEntry* s) {
  149. interpretAssert(s->type == STACK_HASH);
  150. refDecHash((Hash*)s->data.p);
  151. }
  152. // (seDerefEntity is part of Entity)
  153. inline void seDerefObject(StackEntry* s) {
  154. interpretAssert(s->type == STACK_OBJECT);
  155. if (s->data.p) --(((ObjectBase*)s->data.p)->ref);
  156. }
  157. #endif