Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

157 строки
3.0 KiB

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