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.
 
 
 

149 lines
2.7 KiB

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