aboutsummaryrefslogtreecommitdiff
path: root/src/master/scenemgr.cpp
blob: 1399d63e0e02be03065ad8018086a158223d5951 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
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);
	}
}