Line data Source code
1 : /**
2 : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
3 :
4 : Permission is hereby granted, free of charge, to any person obtaining a copy
5 : of this software and associated documentation files (the "Software"), to deal
6 : in the Software without restriction, including without limitation the rights
7 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 : copies of the Software, and to permit persons to whom the Software is
9 : furnished to do so, subject to the following conditions:
10 :
11 : The above copyright notice and this permission notice shall be included in
12 : all copies or substantial portions of the Software.
13 :
14 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 : THE SOFTWARE.
21 : **/
22 :
23 : #ifndef XENOLITH_APPLICATION_XLAPPLICATION_H_
24 : #define XENOLITH_APPLICATION_XLAPPLICATION_H_
25 :
26 : #include "XLEventHeader.h"
27 : #include "XLResourceCache.h"
28 : #include "SPThreadTaskQueue.h"
29 : #include "XLApplicationExtension.h"
30 :
31 : #if MODULE_XENOLITH_FONT
32 :
33 : #include "XLFontExtension.h"
34 :
35 : #endif
36 :
37 :
38 : #if MODULE_XENOLITH_SCENE
39 :
40 : #include "XLView.h"
41 :
42 : #endif
43 :
44 :
45 : namespace STAPPLER_VERSIONIZED stappler::xenolith {
46 :
47 : class Event;
48 : class EventHandlerNode;
49 :
50 : class Application : protected thread::TaskQueue {
51 : public:
52 : static EventHeader onMessageToken;
53 : static EventHeader onRemoteNotification;
54 :
55 : struct CommonInfo {
56 : String bundleName;
57 : String applicationName;
58 : String applicationVersion;
59 : String userAgent;
60 : String locale;
61 :
62 : uint32_t applicationVersionCode = 0;
63 : void *nativeHandle = nullptr;
64 :
65 : int dpi = 92;
66 : };
67 :
68 : struct CallbackInfo {
69 : Function<void(const Application &)> initCallback;
70 : Function<void(const Application &, const UpdateTime &)> updateCallback;
71 : Function<void(const Application &)> finalizeCallback;
72 : };
73 :
74 : using Task = thread::Task;
75 :
76 : using ExecuteCallback = Function<bool(const Task &)>;
77 : using CompleteCallback = Function<void(const Task &, bool)>;
78 :
79 : static Application *getInstance();
80 :
81 : virtual ~Application();
82 :
83 : virtual bool init(CommonInfo &&info, Rc<core::Instance> &&instance);
84 :
85 : virtual void run(const CallbackInfo &, core::LoopInfo &&, uint32_t threadsCount, TimeInterval);
86 :
87 : virtual void end();
88 :
89 : virtual void wakeup();
90 :
91 : bool isOnMainThread() const;
92 :
93 : void performOnGlThread(Function<void()> &&func, Ref *target = nullptr, bool immediate = false) const;
94 :
95 : /* If current thread is main thread: executes function/task
96 : If not: adds function/task to main thread queue */
97 : void performOnMainThread(Function<void()> &&func, Ref *target = nullptr, bool onNextFrame = false);
98 :
99 : /* If current thread is main thread: executes function/task
100 : If not: adds function/task to main thread queue */
101 : void performOnMainThread(Rc<Task> &&task, bool onNextFrame = false);
102 :
103 : /* Performs action in this thread, task will be constructed in place */
104 : void perform(ExecuteCallback &&, CompleteCallback && = nullptr, Ref * = nullptr);
105 :
106 : /* Performs task in thread, identified by id */
107 : void perform(Rc<Task> &&task);
108 :
109 : /* Performs task in thread, identified by id */
110 : void perform(Rc<Task> &&task, bool performFirst);
111 :
112 : void addEventListener(const EventHandlerNode *listener);
113 : void removeEventListner(const EventHandlerNode *listener);
114 :
115 : void removeAllEventListeners();
116 : void dispatchEvent(const Event &ev);
117 :
118 : uint64_t getClock() const;
119 :
120 : using mem_std::AllocBase::operator new;
121 : using mem_std::AllocBase::operator delete;
122 :
123 : using Ref::release;
124 : using Ref::retain;
125 :
126 56582 : const Rc<ResourceCache> &getResourceCache() const { return _resourceCache; }
127 53349 : const Rc<core::Loop> &getGlLoop() const { return _glLoop; }
128 :
129 : thread::TaskQueue *getQueue();
130 :
131 : template <typename T>
132 : bool addExtension(Rc<T> &&);
133 :
134 : template <typename T>
135 : T *getExtension();
136 :
137 : StringView getMessageToken() const { return _messageToken; }
138 42 : const CommonInfo &getInfo() const { return _info; }
139 :
140 : void openUrl(StringView) const;
141 :
142 : protected:
143 : void update(const CallbackInfo &, const UpdateTime &);
144 :
145 : virtual void handleDeviceStarted(const core::Loop &loop, const core::Device &dev);
146 : virtual void handleDeviceFinalized(const core::Loop &loop, const core::Device &dev);
147 :
148 : virtual void handleMessageToken(String &&);
149 : virtual void handleRemoteNotification(Value &&);
150 :
151 : void nativeInit();
152 : void nativeDispose();
153 :
154 : UpdateTime _time;
155 : std::thread::id _threadId;
156 : memory::pool_t *_updatePool = nullptr;
157 : bool _started = false;
158 : bool _immediateUpdate = false;
159 : mutable std::atomic_flag _shouldQuit;
160 : HashMap<EventHeader::EventID, HashSet<const EventHandlerNode *>> _eventListeners;
161 : Rc<ResourceCache> _resourceCache;
162 : Rc<core::Loop> _glLoop;
163 : Rc<core::Instance> _instance;
164 : const core::Device *_device = nullptr;
165 :
166 : HashMap<std::type_index, Rc<ApplicationExtension>> _extensions;
167 :
168 : String _messageToken;
169 : CommonInfo _info;
170 :
171 : struct WaitCallbackInfo {
172 : Function<void()> func;
173 : Rc<Ref> target;
174 : bool immediate = false;
175 : };
176 :
177 : mutable Vector<WaitCallbackInfo> _glWaitCallback;
178 :
179 : #if MODULE_XENOLITH_SCENE
180 : public:
181 : virtual bool addView(ViewInfo &&);
182 :
183 : protected:
184 : Vector<ViewInfo> _tmpViews;
185 : Set<Rc<xenolith::View>> _activeViews;
186 : #endif
187 : };
188 :
189 : template <typename T>
190 66 : bool Application::addExtension(Rc<T> &&t) {
191 66 : auto it = _extensions.find(std::type_index(typeid(T)));
192 66 : if (it == _extensions.end()) {
193 66 : auto ref = t.get();
194 66 : _extensions.emplace(std::type_index(typeid(T)), move(t));
195 66 : if (_started) {
196 0 : ref->initialize(this);
197 : }
198 66 : return true;
199 : } else {
200 0 : return false;
201 : }
202 : }
203 :
204 : template <typename T>
205 1475 : auto Application::getExtension() -> T * {
206 1475 : auto it = _extensions.find(std::type_index(typeid(T)));
207 1475 : if (it != _extensions.end()) {
208 1475 : return reinterpret_cast<T *>(it->second.get());
209 : }
210 0 : return nullptr;
211 : }
212 :
213 :
214 : }
215 :
216 : #endif /* XENOLITH_APPLICATION_XLAPPLICATION_H_ */
|