aboutsummaryrefslogtreecommitdiff
path: root/src/master/scenemgr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/master/scenemgr.cpp')
-rw-r--r--src/master/scenemgr.cpp63
1 files changed, 63 insertions, 0 deletions
diff --git a/src/master/scenemgr.cpp b/src/master/scenemgr.cpp
new file mode 100644
index 0000000..1399d63
--- /dev/null
+++ b/src/master/scenemgr.cpp
@@ -0,0 +1,63 @@
+#include "master.hpp"
+#include <cstring>
+#include <cstdlib>
+int cmp(const void* a,const void* b){return ((pn*)b)->p-((pn*)a)->p;}
+extern sceneManager *sceneMgr;
+SMELT* sceneManager::sm=NULL;
+std::thread* sceneManager::uth=NULL;
+sceneManager::sceneManager(){sm=smGetInterface(SMELT_APILEVEL);utime=scnt=0;thactive=false;dlps=64;}
+sceneManager::~sceneManager(){sm->smRelease();}
+int sceneManager::registerScene(scenePrototype *sp,const char* scenename,int priority)
+{
+ for(int i=0;i<scnt;++i)if(!strncmp(scenename,names[i],16))return -1;
+ sps[scnt]=sp;
+ strncpy(names[scnt],scenename,16);
+ active[scnt]=false;
+ pq[scnt].p=priority;pq[scnt].n=scnt;++scnt;
+ qsort(pq,scnt,sizeof(pn),cmp);
+ return scnt-1;
+}
+void sceneManager::activateScene(const char* scene)
+{for(int i=0;i<scnt;++i)if(!strncmp(scene,names[i],16)){active[i]=true;break;}}
+void sceneManager::deactivateScene(const char* scene)
+{for(int i=0;i<scnt;++i)if(!strncmp(scene,names[i],16)){active[i]=false;break;}}
+void sceneManager::startUpdate(){thactive=true;uth=new std::thread(&sceneManager::threadUpdate,sceneMgr);}
+void sceneManager::stopUpdate(){thactive=false;uth->join();delete uth;}
+bool sceneManager::isThreadActive(){return thactive;}
+int sceneManager::getSceneID(const char* scene)
+{for(int i=0;i<scnt;++i)if(!strncmp(scene,names[i],16))return i;return -1;}
+bool sceneManager::isSceneActive(int sceneid){return active[sceneid];}
+void sceneManager::setLPS(int lps){dlps=lps;}
+float sceneManager::getLPS(){return lps;}
+int sceneManager::getTHUpdateTime(){return utime;}
+//Update functions return true if it wants to terminate the application.
+//Render functions should never return true.
+bool sceneManager::update()
+{
+ for(int i=0;i<scnt;++i)
+ if(active[pq[i].n])if(sps[pq[i].n]->sceneUpdate())return true;
+ sm->smRenderBegin2D(true);
+ for(int i=0;i<scnt;++i)
+ if(active[pq[i].n])sps[pq[i].n]->sceneRender();
+ sm->smRenderEnd();
+ if(sm->smGetKeyState(SMK_S)==SMKST_HIT)sm->smScreenShot("ss0.bmp");
+ return false;
+}
+void sceneManager::threadUpdate()
+{
+ long ddlay;
+ while(thactive)
+ {
+ ddlay=1000000000/dlps;
+ using namespace std::chrono;
+ high_resolution_clock::time_point b=high_resolution_clock::now();
+ for(int i=0;i<scnt;++i)
+ if(active[pq[i].n])sps[pq[i].n]->threadUpdate();
+ high_resolution_clock::time_point a=high_resolution_clock::now();
+ auto updateTime=a-b;utime=updateTime.count();
+ ++lp;lpsud+=updateTime.count()>ddlay?updateTime.count():ddlay;
+ if(lpsud>=1000000000){lps=(float)lp/(lpsud/1000000000.);lp=0;lpsud=0;}
+ if(updateTime<(duration<long,std::ratio<1l,1000000000l>>)ddlay)
+ std::this_thread::sleep_for((duration<long,std::ratio<1l,1000000000l>>)ddlay-updateTime);
+ }
+}