You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

164 regels
3.1 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright: (c) 2010-2012 Sam Hocevar <sam@hocevar.net>
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the Do What The Fuck You Want To
  7. // Public License, Version 2, as published by Sam Hocevar. See
  8. // http://sam.zoy.org/projects/COPYING.WTFPL for more details.
  9. //
  10. #if defined HAVE_CONFIG_H
  11. # include "config.h"
  12. #endif
  13. #include <cstring>
  14. #include <cstdlib>
  15. #include "core.h"
  16. #if defined _WIN32 || defined _XBOX
  17. # define strcasecmp _stricmp
  18. #endif
  19. using namespace std;
  20. namespace lol
  21. {
  22. /*
  23. * Dict implementation class
  24. */
  25. class DictData
  26. {
  27. friend class Dict;
  28. public:
  29. DictData() :
  30. entities(0),
  31. maxid(0),
  32. nentities(0)
  33. {
  34. /* Nothing to do */
  35. }
  36. ~DictData()
  37. {
  38. #if !LOL_RELEASE
  39. if (nentities)
  40. Log::Error("still %i entities in dict\n", nentities);
  41. #endif
  42. free(entities);
  43. }
  44. private:
  45. Entity **entities;
  46. int maxid, nentities;
  47. };
  48. /*
  49. * Public Dict class
  50. */
  51. Dict::Dict()
  52. : data(new DictData())
  53. {
  54. }
  55. Dict::~Dict()
  56. {
  57. delete data;
  58. }
  59. int Dict::MakeSlot(char const *name)
  60. {
  61. int slotid, empty = -1;
  62. /* If the entry is already registered, remember its ID. Look for an
  63. * empty slot at the same time. */
  64. for (slotid = 0; slotid < data->maxid; slotid++)
  65. {
  66. Entity *e = data->entities[slotid];
  67. if (!e)
  68. {
  69. empty = slotid;
  70. break;
  71. }
  72. else
  73. {
  74. char const *oldname = e->GetName();
  75. if (*oldname == '<')
  76. {
  77. while (*oldname && *oldname != '>')
  78. oldname++;
  79. while (*oldname == '>')
  80. oldname++;
  81. while (*oldname == ' ')
  82. oldname++;
  83. }
  84. if (!strcasecmp(name, oldname))
  85. break;
  86. }
  87. }
  88. /* If this is a new entry, create a new slot for it. */
  89. if (slotid == data->maxid || !data->entities[slotid])
  90. {
  91. if (slotid == data->maxid)
  92. {
  93. empty = data->maxid++;
  94. data->entities = (Entity **)realloc(data->entities,
  95. data->maxid * sizeof(Entity *));
  96. }
  97. data->entities[empty] = NULL;
  98. slotid = empty;
  99. data->nentities++;
  100. }
  101. else
  102. {
  103. Ticker::Ref(data->entities[slotid]);
  104. }
  105. return slotid;
  106. }
  107. void Dict::RemoveSlot(int slotid)
  108. {
  109. if (Ticker::Unref(data->entities[slotid]) == 0)
  110. {
  111. data->entities[slotid] = NULL;
  112. data->nentities--;
  113. }
  114. }
  115. void Dict::RemoveSlot(Entity *entity)
  116. {
  117. for (int slotid = 0; slotid < data->maxid; slotid++)
  118. if (data->entities[slotid] == entity)
  119. {
  120. RemoveSlot(slotid);
  121. return;
  122. }
  123. #if !LOL_RELEASE
  124. Log::Error("removing unregistered entity %p\n", entity);
  125. #endif
  126. }
  127. void Dict::SetEntity(int slotid, Entity *entity)
  128. {
  129. Ticker::Ref(entity);
  130. data->entities[slotid] = entity;
  131. }
  132. Entity *Dict::GetEntity(int slotid)
  133. {
  134. return data->entities[slotid];
  135. }
  136. } /* namespace lol */