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.

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