1 #include "RuntimeLifecycleMonitor.h"
2
3 #include <unordered_map>
4 #include <unordered_set>
5 #include <utility>
6
7 namespace ABI49_0_0RNJsi {
8
9 static std::unordered_map<jsi::Runtime *,
10 std::unordered_set<RuntimeLifecycleListener *>>
11 listeners;
12
13 struct RuntimeLifecycleMonitorObject : public jsi::HostObject {
14 jsi::Runtime *_rt;
RuntimeLifecycleMonitorObjectABI49_0_0RNJsi::RuntimeLifecycleMonitorObject15 explicit RuntimeLifecycleMonitorObject(jsi::Runtime *rt) : _rt(rt) {}
~RuntimeLifecycleMonitorObjectABI49_0_0RNJsi::RuntimeLifecycleMonitorObject16 ~RuntimeLifecycleMonitorObject() {
17 auto listenersSet = listeners.find(_rt);
18 if (listenersSet != listeners.end()) {
19 for (auto listener : listenersSet->second) {
20 listener->onRuntimeDestroyed(_rt);
21 }
22 listeners.erase(listenersSet);
23 }
24 }
25 };
26
addListener(jsi::Runtime & rt,RuntimeLifecycleListener * listener)27 void RuntimeLifecycleMonitor::addListener(jsi::Runtime &rt,
28 RuntimeLifecycleListener *listener) {
29 auto listenersSet = listeners.find(&rt);
30 if (listenersSet == listeners.end()) {
31 // We install a global host object in the provided runtime, this way we can
32 // use that host object destructor to get notified when the runtime is being
33 // terminated. We use a unique name for the object as it gets saved with the
34 // runtime's global object.
35 rt.global().setProperty(
36 rt, "__rnskia_rt_lifecycle_monitor",
37 jsi::Object::createFromHostObject(
38 rt, std::make_shared<RuntimeLifecycleMonitorObject>(&rt)));
39 std::unordered_set<RuntimeLifecycleListener *> newSet;
40 newSet.insert(listener);
41 listeners.emplace(&rt, std::move(newSet));
42 } else {
43 listenersSet->second.insert(listener);
44 }
45 }
46
removeListener(jsi::Runtime & rt,RuntimeLifecycleListener * listener)47 void RuntimeLifecycleMonitor::removeListener(
48 jsi::Runtime &rt, RuntimeLifecycleListener *listener) {
49 auto listenersSet = listeners.find(&rt);
50 if (listenersSet == listeners.end()) {
51 // nothing to do here
52 } else {
53 listenersSet->second.erase(listener);
54 }
55 }
56
57 } // namespace ABI49_0_0RNJsi
58