unit_manager.cpp 1.8 KB

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