Line data Source code
1 : /**
2 : Copyright (c) 2020 Roman Katuntsev <sbkarr@stappler.org>
3 : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
4 :
5 : Permission is hereby granted, free of charge, to any person obtaining a copy
6 : of this software and associated documentation files (the "Software"), to deal
7 : in the Software without restriction, including without limitation the rights
8 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 : copies of the Software, and to permit persons to whom the Software is
10 : furnished to do so, subject to the following conditions:
11 :
12 : The above copyright notice and this permission notice shall be included in
13 : all copies or substantial portions of the Software.
14 :
15 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 : THE SOFTWARE.
22 : **/
23 :
24 : #include "XLEventHandler.h"
25 : #include "XLApplication.h"
26 :
27 : namespace STAPPLER_VERSIONIZED stappler::xenolith {
28 :
29 2195 : EventHandler::EventHandler() { }
30 :
31 2195 : EventHandler::~EventHandler() {
32 2195 : clearEvents();
33 2195 : }
34 :
35 2270 : void EventHandler::addHandlerNode(EventHandlerNode *handler) {
36 2270 : auto linkId = handler->retain();
37 2270 : _handlers.insert(handler);
38 2270 : Application::getInstance()->performOnMainThread([handler, linkId] {
39 2270 : Application::getInstance()->addEventListener(handler);
40 :
41 2270 : handler->release(linkId);
42 2270 : }, nullptr);
43 2270 : }
44 90 : void EventHandler::removeHandlerNode(EventHandlerNode *handler) {
45 90 : auto linkId = handler->retain();
46 90 : if (_handlers.erase(handler) > 0) {
47 75 : handler->setSupport(nullptr);
48 75 : Application::getInstance()->performOnMainThread([handler, linkId] {
49 75 : Application::getInstance()->removeEventListner(handler);
50 75 : handler->release(linkId);
51 75 : }, nullptr);
52 : }
53 90 : }
54 :
55 0 : EventHandlerNode * EventHandler::setEventHandler(const EventHeader &h, Callback && callback, bool destroyAfterEvent) {
56 0 : return EventHandlerNode::onEvent(h, nullptr, std::move(callback), this, destroyAfterEvent);
57 : }
58 :
59 0 : EventHandlerNode * EventHandler::setEventHandlerForObject(const EventHeader &h, Ref *obj, Callback && callback, bool destroyAfterEvent) {
60 0 : return EventHandlerNode::onEvent(h, obj, std::move(callback), this, destroyAfterEvent);
61 : }
62 :
63 90 : Ref *EventHandler::getInterface() const {
64 90 : if (auto ref = dynamic_cast<const Ref *>(this)) {
65 90 : return const_cast<Ref *>(ref);
66 : }
67 0 : return nullptr;
68 : }
69 :
70 2210 : void EventHandler::clearEvents() {
71 2210 : auto h = move(_handlers);
72 2210 : _handlers.clear();
73 :
74 4405 : for (auto it : h) {
75 2195 : it->setSupport(nullptr);
76 2195 : }
77 :
78 2210 : Application::getInstance()->performOnMainThread([h = move(h)] {
79 4405 : for (auto it : h) {
80 2195 : Application::getInstance()->removeEventListner(it);
81 2195 : }
82 2210 : }, nullptr);
83 2210 : }
84 :
85 2270 : Rc<EventHandlerNode> EventHandlerNode::onEvent(const EventHeader &header, Ref *ref, Callback && callback, EventHandler *obj, bool destroyAfterEvent) {
86 2270 : if (callback) {
87 2270 : auto h = Rc<EventHandlerNode>::alloc(header, ref, std::move(callback), obj, destroyAfterEvent);
88 2270 : obj->addHandlerNode(h);
89 2270 : return h;
90 2270 : }
91 0 : return nullptr;
92 : }
93 :
94 2270 : EventHandlerNode::EventHandlerNode(const EventHeader &header, Ref *ref, Callback && callback, EventHandler *obj, bool destroyAfterEvent)
95 2270 : : _destroyAfterEvent(destroyAfterEvent), _eventID(header.getEventID()), _callback(std::move(callback)), _obj(ref), _support(obj) { }
96 :
97 4510 : EventHandlerNode::~EventHandlerNode() { }
98 :
99 2270 : void EventHandlerNode::setSupport(EventHandler *s) {
100 2270 : _support = s;
101 2270 : }
102 :
103 90 : bool EventHandlerNode::shouldRecieveEventWithObject(EventHeader::EventID eventID, Ref *object) const {
104 90 : return _eventID == eventID && (!_obj || object == _obj);
105 : };
106 :
107 4585 : EventHeader::EventID EventHandlerNode::getEventID() const { return _eventID; }
108 :
109 90 : void EventHandlerNode::onEventRecieved(const Event &event) const {
110 90 : auto self = (Ref *)this;
111 90 : auto id = self->retain();
112 90 : auto s = _support.load();
113 90 : if (s) {
114 90 : Rc<Ref> iface(s->getInterface());
115 90 : _callback(event);
116 90 : if (_destroyAfterEvent) {
117 90 : s->removeHandlerNode(const_cast<EventHandlerNode *>(this));
118 : }
119 90 : }
120 90 : self->release(id);
121 90 : }
122 :
123 : }
|