Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

161 рядки
3.0 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright: (c) 2010-2013 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://www.wtfpl.net/ 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. nentities(0)
  31. {
  32. /* Nothing to do */
  33. }
  34. ~DictData()
  35. {
  36. #if !LOL_RELEASE
  37. if (nentities)
  38. Log::Error("still %i entities in dict\n", nentities);
  39. #endif
  40. }
  41. private:
  42. Array<Entity *> m_entities;
  43. int nentities;
  44. };
  45. /*
  46. * Public Dict class
  47. */
  48. Dict::Dict()
  49. : data(new DictData())
  50. {
  51. }
  52. Dict::~Dict()
  53. {
  54. delete data;
  55. }
  56. int Dict::MakeSlot(char const *name)
  57. {
  58. int slotid, empty = -1;
  59. /* If the entry is already registered, remember its ID. Look for an
  60. * empty slot at the same time. */
  61. for (slotid = 0; slotid < data->m_entities.Count(); slotid++)
  62. {
  63. Entity *e = data->m_entities[slotid];
  64. if (!e)
  65. {
  66. empty = slotid;
  67. break;
  68. }
  69. else
  70. {
  71. char const *oldname = e->GetName();
  72. if (*oldname == '<')
  73. {
  74. while (*oldname && *oldname != '>')
  75. oldname++;
  76. while (*oldname == '>')
  77. oldname++;
  78. while (*oldname == ' ')
  79. oldname++;
  80. }
  81. if (!strcasecmp(name, oldname))
  82. break;
  83. }
  84. }
  85. /* If this is a new entry, create a new slot for it. */
  86. if (slotid == data->m_entities.Count() || !data->m_entities[slotid])
  87. {
  88. if (slotid == data->m_entities.Count())
  89. {
  90. empty = data->m_entities.Count();
  91. data->m_entities.Push(NULL);
  92. }
  93. data->m_entities[empty] = NULL;
  94. slotid = empty;
  95. data->nentities++;
  96. }
  97. else
  98. {
  99. Ticker::Ref(data->m_entities[slotid]);
  100. }
  101. return slotid;
  102. }
  103. void Dict::RemoveSlot(int slotid)
  104. {
  105. if (Ticker::Unref(data->m_entities[slotid]) == 0)
  106. {
  107. data->m_entities[slotid] = NULL;
  108. data->nentities--;
  109. }
  110. }
  111. void Dict::RemoveSlot(Entity *entity)
  112. {
  113. for (int slotid = 0; slotid < data->m_entities.Count(); slotid++)
  114. if (data->m_entities[slotid] == entity)
  115. {
  116. RemoveSlot(slotid);
  117. return;
  118. }
  119. #if !LOL_RELEASE
  120. Log::Error("removing unregistered entity %p (%s)\n",
  121. entity, entity->GetName());
  122. #endif
  123. }
  124. void Dict::SetEntity(int slotid, Entity *entity)
  125. {
  126. Ticker::Ref(entity);
  127. data->m_entities[slotid] = entity;
  128. }
  129. Entity *Dict::GetEntity(int slotid)
  130. {
  131. return data->m_entities[slotid];
  132. }
  133. } /* namespace lol */