framework2
263 строки · 10.9 Кб
1/*
2* ofMainLoop.cpp
3*
4* Created on: Oct 25, 2014
5* Author: arturo
6*/
7
8#include "ofMainLoop.h"
9#include "ofBaseApp.h"
10#include "ofConstants.h"
11
12//========================================================================
13// default windowing
14#ifdef TARGET_NODISPLAY
15#include "ofAppNoWindow.h"
16#elif defined(TARGET_OF_IOS)
17#include "ofAppiOSWindow.h"
18#elif defined(TARGET_ANDROID)
19#include "ofAppAndroidWindow.h"
20#include "ofxAndroidUtils.h"
21#include "ofxAndroidApp.h"
22#elif defined(TARGET_RASPBERRY_PI) && defined(TARGET_GLFW_WINDOW)
23#include "ofAppGLFWWindow.h"
24#elif defined(TARGET_RASPBERRY_PI)
25#include "ofAppEGLWindow.h"
26#elif defined(TARGET_EMSCRIPTEN)
27#include "ofxAppEmscriptenWindow.h"
28#else
29#include "ofAppGLFWWindow.h"
30#endif
31
32ofMainLoop::ofMainLoop()
33:bShouldClose(false)
34,status(0)
35,allowMultiWindow(true)
36,escapeQuits(true){
37
38}
39
40ofMainLoop::~ofMainLoop() {
41exit();
42}
43
44std::shared_ptr<ofAppBaseWindow> ofMainLoop::createWindow(const ofWindowSettings & settings){
45#ifdef TARGET_NODISPLAY
46shared_ptr<ofAppNoWindow> window = std::make_shared<ofAppNoWindow>();
47#else
48#if defined(TARGET_OF_IOS)
49std::shared_ptr<ofAppiOSWindow> window = std::make_shared<ofAppiOSWindow>();
50#elif defined(TARGET_ANDROID)
51std::shared_ptr<ofAppAndroidWindow> window = std::make_shared<ofAppAndroidWindow>();
52#elif (defined(TARGET_RASPBERRY_PI) && defined(TARGET_GLFW_WINDOW))
53std::shared_ptr<ofAppGLFWWindow> window = std::make_shared<ofAppGLFWWindow>();
54#elif defined(TARGET_RASPBERRY_PI)
55std::shared_ptr<ofAppEGLWindow> window = std::make_shared<ofAppEGLWindow>();
56#elif defined(TARGET_EMSCRIPTEN)
57std::shared_ptr<ofxAppEmscriptenWindow> window = std::make_shared<ofxAppEmscriptenWindow>();
58#elif defined(TARGET_OPENGLES)
59std::shared_ptr<ofAppGLFWWindow> window = std::make_shared<ofAppGLFWWindow>();
60#else
61std::shared_ptr<ofAppGLFWWindow> window = std::make_shared<ofAppGLFWWindow>();
62#endif
63#endif
64addWindow(window);
65window->setup(settings);
66return window;
67}
68
69void ofMainLoop::run(const std::shared_ptr<ofAppBaseWindow> & window, std::shared_ptr<ofBaseApp> && app){
70windowsApps[window] = app;
71if(app){
72ofAddListener(window->events().setup,app.get(),&ofBaseApp::setup,OF_EVENT_ORDER_APP);
73ofAddListener(window->events().update,app.get(),&ofBaseApp::update,OF_EVENT_ORDER_APP);
74ofAddListener(window->events().draw,app.get(),&ofBaseApp::draw,OF_EVENT_ORDER_APP);
75ofAddListener(window->events().exit,app.get(),&ofBaseApp::exit,OF_EVENT_ORDER_APP);
76ofAddListener(window->events().keyPressed,app.get(),&ofBaseApp::keyPressed,OF_EVENT_ORDER_APP);
77ofAddListener(window->events().keyReleased,app.get(),&ofBaseApp::keyReleased,OF_EVENT_ORDER_APP);
78ofAddListener(window->events().mouseMoved,app.get(),&ofBaseApp::mouseMoved,OF_EVENT_ORDER_APP);
79ofAddListener(window->events().mouseDragged,app.get(),&ofBaseApp::mouseDragged,OF_EVENT_ORDER_APP);
80ofAddListener(window->events().mousePressed,app.get(),&ofBaseApp::mousePressed,OF_EVENT_ORDER_APP);
81ofAddListener(window->events().mouseReleased,app.get(),&ofBaseApp::mouseReleased,OF_EVENT_ORDER_APP);
82ofAddListener(window->events().mouseScrolled,app.get(),&ofBaseApp::mouseScrolled,OF_EVENT_ORDER_APP);
83ofAddListener(window->events().mouseEntered,app.get(),&ofBaseApp::mouseEntered,OF_EVENT_ORDER_APP);
84ofAddListener(window->events().mouseExited,app.get(),&ofBaseApp::mouseExited,OF_EVENT_ORDER_APP);
85ofAddListener(window->events().windowResized,app.get(),&ofBaseApp::windowResized,OF_EVENT_ORDER_APP);
86ofAddListener(window->events().messageEvent,app.get(),&ofBaseApp::messageReceived,OF_EVENT_ORDER_APP);
87ofAddListener(window->events().fileDragEvent,app.get(),&ofBaseApp::dragged,OF_EVENT_ORDER_APP);
88ofAddListener(window->events().touchCancelled,app.get(),&ofBaseApp::touchCancelled,OF_EVENT_ORDER_APP);
89ofAddListener(window->events().touchDoubleTap,app.get(),&ofBaseApp::touchDoubleTap,OF_EVENT_ORDER_APP);
90ofAddListener(window->events().touchDown,app.get(),&ofBaseApp::touchDown,OF_EVENT_ORDER_APP);
91ofAddListener(window->events().touchMoved,app.get(),&ofBaseApp::touchMoved,OF_EVENT_ORDER_APP);
92ofAddListener(window->events().touchUp,app.get(),&ofBaseApp::touchUp,OF_EVENT_ORDER_APP);
93#ifdef TARGET_ANDROID
94auto androidApp = dynamic_cast<ofxAndroidApp*>(app.get());
95if(androidApp){
96ofAddListener(ofxAndroidEvents().okPressed,androidApp,&ofxAndroidApp::okPressed,OF_EVENT_ORDER_APP);
97ofAddListener(ofxAndroidEvents().cancelPressed,androidApp,&ofxAndroidApp::cancelPressed,OF_EVENT_ORDER_APP);
98ofAddListener(ofxAndroidEvents().backPressed,androidApp,&ofxAndroidApp::backPressed,OF_EVENT_ORDER_APP);
99ofAddListener(ofxAndroidEvents().networkConnected,androidApp,&ofxAndroidApp::networkConnectedEvent,OF_EVENT_ORDER_APP);
100ofAddListener(ofxAndroidEvents().pause,androidApp,&ofxAndroidApp::pause,OF_EVENT_ORDER_APP);
101ofAddListener(ofxAndroidEvents().resume,androidApp,&ofxAndroidApp::resume,OF_EVENT_ORDER_APP);
102ofAddListener(ofxAndroidEvents().unloadGL,androidApp,&ofxAndroidApp::unloadGL,OF_EVENT_ORDER_APP);
103ofAddListener(ofxAndroidEvents().reloadGL,androidApp,&ofxAndroidApp::reloadGL,OF_EVENT_ORDER_APP);
104ofAddListener(ofxAndroidEvents().swipe,androidApp,&ofxAndroidApp::swipe,OF_EVENT_ORDER_APP);
105ofAddListener(ofxAndroidEvents().deviceOrientationChanged,androidApp,&ofxAndroidApp::deviceOrientationChangedEvent,OF_EVENT_ORDER_APP);
106}
107#endif
108}
109currentWindow = window;
110window->makeCurrent();
111if(!windowLoop){
112window->events().notifySetup();
113}
114}
115
116void ofMainLoop::run(std::shared_ptr<ofBaseApp> && app){
117if(!windowsApps.empty()){
118run(windowsApps.begin()->first, std::move(app));
119}
120}
121
122int ofMainLoop::loop(){
123if(!windowLoop){
124while(!bShouldClose && !windowsApps.empty()){
125loopOnce();
126pollEvents();
127}
128}else{
129windowLoop();
130}
131return status;
132}
133
134void ofMainLoop::loopOnce(){
135if(bShouldClose) return;
136for(auto i = windowsApps.begin(); !windowsApps.empty() && i != windowsApps.end();){
137if(i->first->getWindowShouldClose()){
138const auto & window = i->first;
139window->close();
140windowsApps.erase(i++); ///< i now points at the window after the one which was just erased
141}else{
142currentWindow = i->first;
143i->first->makeCurrent();
144i->first->update();
145i->first->draw();
146i++; ///< continue to next window
147}
148}
149loopEvent.notify(this);
150}
151
152void ofMainLoop::pollEvents(){
153if(windowPollEvents){
154windowPollEvents();
155}
156}
157
158void ofMainLoop::exit(){
159exitEvent.notify(this);
160
161for(auto i: windowsApps){
162std::shared_ptr<ofAppBaseWindow> window = i.first;
163std::shared_ptr<ofBaseApp> app = i.second;
164
165if(window == nullptr) {
166continue;
167}
168if(app == nullptr) {
169continue;
170}
171
172ofEventArgs args;
173ofNotifyEvent(window->events().exit, args, this);
174
175ofRemoveListener(window->events().setup,app.get(),&ofBaseApp::setup,OF_EVENT_ORDER_APP);
176ofRemoveListener(window->events().update,app.get(),&ofBaseApp::update,OF_EVENT_ORDER_APP);
177ofRemoveListener(window->events().draw,app.get(),&ofBaseApp::draw,OF_EVENT_ORDER_APP);
178ofRemoveListener(window->events().exit,app.get(),&ofBaseApp::exit,OF_EVENT_ORDER_APP);
179ofRemoveListener(window->events().keyPressed,app.get(),&ofBaseApp::keyPressed,OF_EVENT_ORDER_APP);
180ofRemoveListener(window->events().keyReleased,app.get(),&ofBaseApp::keyReleased,OF_EVENT_ORDER_APP);
181ofRemoveListener(window->events().mouseMoved,app.get(),&ofBaseApp::mouseMoved,OF_EVENT_ORDER_APP);
182ofRemoveListener(window->events().mouseDragged,app.get(),&ofBaseApp::mouseDragged,OF_EVENT_ORDER_APP);
183ofRemoveListener(window->events().mousePressed,app.get(),&ofBaseApp::mousePressed,OF_EVENT_ORDER_APP);
184ofRemoveListener(window->events().mouseReleased,app.get(),&ofBaseApp::mouseReleased,OF_EVENT_ORDER_APP);
185ofRemoveListener(window->events().mouseScrolled,app.get(),&ofBaseApp::mouseScrolled,OF_EVENT_ORDER_APP);
186ofRemoveListener(window->events().mouseEntered,app.get(),&ofBaseApp::mouseEntered,OF_EVENT_ORDER_APP);
187ofRemoveListener(window->events().mouseExited,app.get(),&ofBaseApp::mouseExited,OF_EVENT_ORDER_APP);
188ofRemoveListener(window->events().windowResized,app.get(),&ofBaseApp::windowResized,OF_EVENT_ORDER_APP);
189ofRemoveListener(window->events().messageEvent,app.get(),&ofBaseApp::messageReceived,OF_EVENT_ORDER_APP);
190ofRemoveListener(window->events().fileDragEvent,app.get(),&ofBaseApp::dragged,OF_EVENT_ORDER_APP);
191ofRemoveListener(window->events().touchCancelled,app.get(),&ofBaseApp::touchCancelled,OF_EVENT_ORDER_APP);
192ofRemoveListener(window->events().touchDoubleTap,app.get(),&ofBaseApp::touchDoubleTap,OF_EVENT_ORDER_APP);
193ofRemoveListener(window->events().touchDown,app.get(),&ofBaseApp::touchDown,OF_EVENT_ORDER_APP);
194ofRemoveListener(window->events().touchMoved,app.get(),&ofBaseApp::touchMoved,OF_EVENT_ORDER_APP);
195ofRemoveListener(window->events().touchUp,app.get(),&ofBaseApp::touchUp,OF_EVENT_ORDER_APP);
196#ifdef TARGET_ANDROID
197auto androidApp = dynamic_cast<ofxAndroidApp*>(app.get());
198if(androidApp){
199ofRemoveListener(ofxAndroidEvents().okPressed,androidApp,&ofxAndroidApp::okPressed,OF_EVENT_ORDER_APP);
200ofRemoveListener(ofxAndroidEvents().cancelPressed,androidApp,&ofxAndroidApp::cancelPressed,OF_EVENT_ORDER_APP);
201ofRemoveListener(ofxAndroidEvents().backPressed,androidApp,&ofxAndroidApp::backPressed,OF_EVENT_ORDER_APP);
202ofRemoveListener(ofxAndroidEvents().networkConnected,androidApp,&ofxAndroidApp::networkConnectedEvent,OF_EVENT_ORDER_APP);
203ofRemoveListener(ofxAndroidEvents().pause,androidApp,&ofxAndroidApp::pause,OF_EVENT_ORDER_APP);
204ofRemoveListener(ofxAndroidEvents().resume,androidApp,&ofxAndroidApp::resume,OF_EVENT_ORDER_APP);
205ofRemoveListener(ofxAndroidEvents().unloadGL,androidApp,&ofxAndroidApp::unloadGL,OF_EVENT_ORDER_APP);
206ofRemoveListener(ofxAndroidEvents().reloadGL,androidApp,&ofxAndroidApp::reloadGL,OF_EVENT_ORDER_APP);
207ofRemoveListener(ofxAndroidEvents().swipe,androidApp,&ofxAndroidApp::swipe,OF_EVENT_ORDER_APP);
208ofRemoveListener(ofxAndroidEvents().deviceOrientationChanged,androidApp,&ofxAndroidApp::deviceOrientationChangedEvent,OF_EVENT_ORDER_APP);
209}
210#endif
211}
212
213
214// reset applications then windows
215// so events are present until the
216// end of the application
217for(auto & window_app: windowsApps){
218window_app.second.reset();
219}
220windowsApps.clear();
221}
222
223std::shared_ptr<ofAppBaseWindow> ofMainLoop::getCurrentWindow(){
224return currentWindow.lock();
225}
226
227void ofMainLoop::setCurrentWindow(const std::shared_ptr<ofAppBaseWindow> & window){
228currentWindow = window;
229}
230
231void ofMainLoop::setCurrentWindow(ofAppBaseWindow * window){
232if(currentWindow.lock().get() == window){
233return;
234}
235for(auto i: windowsApps){
236if(i.first.get() == window){
237currentWindow = i.first;
238break;
239}
240}
241}
242
243std::shared_ptr<ofBaseApp> ofMainLoop::getCurrentApp(){
244return windowsApps[currentWindow.lock()];
245}
246
247void ofMainLoop::shouldClose(int _status){
248for(auto i: windowsApps){
249i.first->setWindowShouldClose();
250}
251bShouldClose = true;
252status = _status;
253}
254
255void ofMainLoop::setEscapeQuitsLoop(bool quits){
256escapeQuits = quits;
257}
258
259void ofMainLoop::keyPressed(ofKeyEventArgs & key){
260if (key.key == OF_KEY_ESC && escapeQuits == true){ // "escape"
261shouldClose(0);
262}
263}
264