unit_manager.cpp 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /*
  2. * Copyright (c) 2012-2018 Daniele Bartolini and individual contributors.
  3. * License: https://github.com/dbartolini/crown/blob/master/LICENSE
  4. */
  5. #include "core/containers/array.h"
  6. #include "core/containers/queue.h"
  7. #include "world/unit_manager.h"
  8. #include "world/world.h"
  9. #define MINIMUM_FREE_INDICES 1024
  10. namespace crown
  11. {
  12. UnitManager::UnitManager(Allocator& a)
  13. : _generation(a)
  14. , _free_indices(a)
  15. {
  16. list::init_head(_callbacks.node);
  17. }
  18. UnitId UnitManager::make_unit(u32 idx, u8 gen)
  19. {
  20. UnitId id = { 0 | idx | u32(gen) << UNIT_INDEX_BITS };
  21. return id;
  22. }
  23. UnitId UnitManager::create()
  24. {
  25. u32 idx;
  26. if (queue::size(_free_indices) > MINIMUM_FREE_INDICES)
  27. {
  28. idx = queue::front(_free_indices);
  29. queue::pop_front(_free_indices);
  30. }
  31. else
  32. {
  33. array::push_back(_generation, u8(0));
  34. idx = array::size(_generation) - 1;
  35. CE_ASSERT(idx < (1 << UNIT_INDEX_BITS), "Indices out of bounds");
  36. }
  37. return make_unit(idx, _generation[idx]);
  38. }
  39. UnitId UnitManager::create(World& world)
  40. {
  41. return world.spawn_empty_unit();
  42. }
  43. bool UnitManager::alive(UnitId id) const
  44. {
  45. return _generation[id.index()] == id.id();
  46. }
  47. void UnitManager::destroy(UnitId id)
  48. {
  49. const u32 idx = id.index();
  50. ++_generation[idx];
  51. queue::push_back(_free_indices, idx);
  52. trigger_destroy_callbacks(id);
  53. }
  54. void UnitManager::register_destroy_callback(UnitDestroyCallback* udc)
  55. {
  56. list::add(udc->node, _callbacks.node);
  57. }
  58. void UnitManager::unregister_destroy_callback(UnitDestroyCallback* udc)
  59. {
  60. list::remove(udc->node);
  61. }
  62. void UnitManager::trigger_destroy_callbacks(UnitId id)
  63. {
  64. ListNode* cur;
  65. list_for_each(cur, &_callbacks.node)
  66. {
  67. UnitDestroyCallback* udc = (UnitDestroyCallback*)container_of(cur, UnitDestroyCallback, node);
  68. udc->destroy(id, udc->user_data);
  69. }
  70. }
  71. } // namespace crown