Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 

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