SubscriptionRegistryProxy.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /*
  2. * SubscriptionRegistryProxy.h, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #pragma once
  11. #include <vcmi/events/Event.h>
  12. #include <vcmi/events/EventBus.h>
  13. #include <vcmi/events/SubscriptionRegistry.h>
  14. #include "../../LuaWrapper.h"
  15. #include "../../LuaStack.h"
  16. #include "../../LuaReference.h"
  17. VCMI_LIB_NAMESPACE_BEGIN
  18. namespace scripting
  19. {
  20. namespace api
  21. {
  22. namespace events
  23. {
  24. class EventSubscriptionProxy : public UniqueOpaqueWrapper<::events::EventSubscription, EventSubscriptionProxy>
  25. {
  26. public:
  27. using Wrapper = UniqueOpaqueWrapper<::events::EventSubscription, EventSubscriptionProxy>;
  28. static const std::vector<typename Wrapper::CustomRegType> REGISTER_CUSTOM;
  29. };
  30. template <typename EventProxy>
  31. class SubscriptionRegistryProxy
  32. {
  33. public:
  34. using EventType = typename EventProxy::ObjectType;
  35. using RegistryType = ::events::SubscriptionRegistry<EventType>;
  36. static_assert(std::is_base_of<::events::Event, EventType>::value, "Invalid template parameter");
  37. static int subscribeBefore(lua_State * L)
  38. {
  39. LuaStack S(L);
  40. // subscription = subscribeBefore(eventBus, callback)
  41. //TODO: use capture by move from c++14
  42. auto callbackRef = std::make_shared<LuaReference>(L);
  43. ::events::EventBus * eventBus = nullptr;
  44. if(!S.tryGet(1, eventBus))
  45. {
  46. S.push("No event bus");
  47. return 1;
  48. }
  49. S.clear();
  50. RegistryType * registry = EventType::getRegistry();
  51. typename EventType::PreHandler callback = [=](EventType & event)
  52. {
  53. LuaStack S(L);
  54. callbackRef->push();
  55. S.push(&event);
  56. if(lua_pcall(L, 1, 0, 0) != 0)
  57. {
  58. std::string msg;
  59. S.tryGet(1, msg);
  60. logMod->error("Script callback error: %s", msg);
  61. }
  62. S.clear();
  63. };
  64. std::unique_ptr<::events::EventSubscription> subscription = registry->subscribeBefore(eventBus, std::move(callback));
  65. S.push(std::move(subscription));
  66. return 1;
  67. }
  68. static int subscribeAfter(lua_State * L)
  69. {
  70. LuaStack S(L);
  71. //TODO: use capture by move from c++14
  72. auto callbackRef = std::make_shared<LuaReference>(L);
  73. ::events::EventBus * eventBus = nullptr;
  74. if(!S.tryGet(1, eventBus))
  75. {
  76. S.push("No event bus");
  77. return 1;
  78. }
  79. S.clear();
  80. RegistryType * registry = EventType::getRegistry();
  81. typename EventType::PostHandler callback = [=](const EventType & event)
  82. {
  83. LuaStack S(L);
  84. callbackRef->push();
  85. S.push(const_cast<EventType *>(&event)); //FIXME:
  86. if(lua_pcall(L, 1, 0, 0) != 0)
  87. {
  88. std::string msg;
  89. S.tryGet(1, msg);
  90. logMod->error("Script callback error: %s", msg);
  91. }
  92. S.clear();
  93. };
  94. std::unique_ptr<::events::EventSubscription> subscription = registry->subscribeAfter(eventBus, std::move(callback));
  95. S.push(std::move(subscription));
  96. return 1;
  97. }
  98. };
  99. }
  100. }
  101. }
  102. VCMI_LIB_NAMESPACE_END