Bladeren bron

core: try to merge Ticker and Emcee. Still not very good.

legacy
Sam Hocevar sam 13 jaren geleden
bovenliggende
commit
0161879a84
15 gewijzigde bestanden met toevoegingen van 169 en 263 verwijderingen
  1. +1
    -1
      src/Makefile.am
  2. +0
    -2
      src/application/application.cpp
  3. +0
    -1
      src/core.h
  4. +0
    -5
      src/eglapp.cpp
  5. +0
    -82
      src/emcee.cpp
  6. +0
    -41
      src/emcee.h
  7. +2
    -2
      src/entity.cpp
  8. +1
    -0
      src/entity.h
  9. +0
    -2
      src/platform/android/androidapp.cpp
  10. +0
    -3
      src/platform/nacl/nacl_instance.cpp
  11. +0
    -5
      src/platform/nacl/naclapp.cpp
  12. +0
    -5
      src/platform/ps3/ps3app.cpp
  13. +0
    -4
      src/platform/sdl/sdlapp.cpp
  14. +161
    -108
      src/ticker.cpp
  15. +4
    -2
      src/ticker.h

+ 1
- 1
src/Makefile.am Bestand weergeven

@@ -11,7 +11,7 @@ liblol_a_SOURCES = \
text.cpp text.h emitter.cpp emitter.h numeric.h hash.cpp hash.h \
worldentity.cpp worldentity.h gradient.cpp gradient.h half.cpp half.h \
platform.cpp platform.h sprite.cpp sprite.h trig.cpp trig.h \
real.cpp real.h emcee.cpp emcee.h \
real.cpp real.h \
\
lol/unit.h \
\


+ 0
- 2
src/application/application.cpp Bestand weergeven

@@ -59,7 +59,6 @@ class ApplicationData

Application::Application(char const *name, ivec2 resolution, float framerate)
{
Emcee::Setup();
data = new ApplicationData(name, resolution, framerate);
}

@@ -76,7 +75,6 @@ void Application::Run()
Application::~Application()
{
delete data;
Emcee::Shutdown();
}

} /* namespace lol */


+ 0
- 1
src/core.h Bestand weergeven

@@ -103,7 +103,6 @@ static inline int isnan(float f)
#include "application/application.h"

// Managers
#include "emcee.h"
#include "ticker.h"
#include "forge.h"
#include "tiler.h"


+ 0
- 5
src/eglapp.cpp Bestand weergeven

@@ -158,16 +158,11 @@ void EglApp::Run()
{
while (!Ticker::Finished())
{
/* Tick the game */
Ticker::TickGame();

/* Tick the renderer, show the frame and clamp to desired framerate. */
Ticker::TickDraw();
#if defined USE_EGL
eglSwapBuffers(data->egl_dpy, data->egl_surf);
#endif

Ticker::ClampFps();
}
}



+ 0
- 82
src/emcee.cpp Bestand weergeven

@@ -1,82 +0,0 @@
//
// Lol Engine
//
// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net>
// This program is free software; you can redistribute it and/or
// modify it under the terms of the Do What The Fuck You Want To
// Public License, Version 2, as published by Sam Hocevar. See
// http://sam.zoy.org/projects/COPYING.WTFPL for more details.
//

#if defined HAVE_CONFIG_H
# include "config.h"
#endif

#include <cstdlib>
#include <stdint.h>

#include "core.h"

namespace lol
{

/*
* Emcee implementation class
*/

static Thread *GameThread, *DrawThread;

static Queue gametick, drawtick;

static void *GameThreadMain(void *data)
{
while (!Ticker::Finished())
for (;;)
{
int tick = gametick.Pop();
if (!tick)
break;

Ticker::TickGame();

drawtick.Push(1);
}

drawtick.Push(0);
}

static void *DrawThreadMain(void *data)
{
for (;;)
{
int tick = drawtick.Pop();
if (!tick)
break;

Ticker::TickDraw();
}
}

void Emcee::Setup()
{
GameThread = new Thread(GameThreadMain, NULL);
DrawThread = new Thread(DrawThreadMain, NULL);
}

void Emcee::Shutdown()
{
}

void Emcee::SetState(Entity *entity, uint32_t state)
{

}

void Emcee::SetStateWhenMatch(Entity *entity, uint32_t state,
Entity *other_entity, uint32_t other_state)
{

}

} /* namespace lol */


+ 0
- 41
src/emcee.h Bestand weergeven

@@ -1,41 +0,0 @@
//
// Lol Engine
//
// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net>
// This program is free software; you can redistribute it and/or
// modify it under the terms of the Do What The Fuck You Want To
// Public License, Version 2, as published by Sam Hocevar. See
// http://sam.zoy.org/projects/COPYING.WTFPL for more details.
//

//
// The Emcee class
// ---------------
// The Emcee manages tasks and their dependencies
//

#if !defined __LOL_EMCEE_H__
#define __LOL_EMCEE_H__

#include <stdint.h>

#include "entity.h"

namespace lol
{

class Emcee
{
public:
static void Setup();
static void Shutdown();

static void SetState(Entity *entity, uint32_t state);
static void SetStateWhenMatch(Entity *entity, uint32_t state,
Entity *other_entity, uint32_t other_state);
};

} /* namespace lol */

#endif // __LOL_EMCEE_H__


+ 2
- 2
src/entity.cpp Bestand weergeven

@@ -70,13 +70,13 @@ void Entity::TickDraw(float deltams)

void Entity::SetState(uint32_t state)
{
Emcee::SetState(this, state);
Ticker::SetState(this, state);
}

void Entity::SetStateWhenMatch(uint32_t state,
Entity *other_entity, uint32_t other_state)
{
Emcee::SetStateWhenMatch(this, state, other_entity, other_state);
Ticker::SetStateWhenMatch(this, state, other_entity, other_state);
}

} /* namespace lol */


+ 1
- 0
src/entity.h Bestand weergeven

@@ -29,6 +29,7 @@ class Entity
friend class Ticker;
friend class TickerData;
friend class Dict;
friend class Emcee;

protected:
Entity();


+ 0
- 2
src/platform/android/androidapp.cpp Bestand weergeven

@@ -96,8 +96,6 @@ Java_org_zoy_LolEngine_LolView_nativeMove(JNIEnv* env, jobject thiz,
extern "C" void
Java_org_zoy_LolEngine_LolRenderer_nativeRender(JNIEnv* env)
{
Ticker::ClampFps();
Ticker::TickGame();
Ticker::TickDraw();
}


+ 0
- 3
src/platform/nacl/nacl_instance.cpp Bestand weergeven

@@ -126,9 +126,6 @@ void NaClInstance::DrawSelf()
if (opengl_context_ == NULL)
return;

Ticker::ClampFps();
Ticker::TickGame();

opengl_context_->MakeContextCurrent(this);
Ticker::TickDraw();
opengl_context_->FlushContext();


+ 0
- 5
src/platform/nacl/naclapp.cpp Bestand weergeven

@@ -58,16 +58,11 @@ void NaClApp::Run()
{
while (!Ticker::Finished())
{
/* Tick the game */
Ticker::TickGame();

/* Tick the renderer, show the frame and clamp to desired framerate. */
Ticker::TickDraw();

#if defined __native_client__
#endif

Ticker::ClampFps();
}
}



+ 0
- 5
src/platform/ps3/ps3app.cpp Bestand weergeven

@@ -118,9 +118,6 @@ void Ps3App::Run()
{
while (!Ticker::Finished())
{
/* Tick the game */
Ticker::TickGame();

/* Tick the renderer, show the frame and clamp to desired framerate. */
Ticker::TickDraw();

@@ -130,8 +127,6 @@ void Ps3App::Run()
/* Check if exit callback was called */
cellSysutilCheckCallback();
#endif

Ticker::ClampFps();
}
}



+ 0
- 4
src/platform/sdl/sdlapp.cpp Bestand weergeven

@@ -84,15 +84,11 @@ void SdlApp::Run()
{
while (!Ticker::Finished())
{
/* Tick the game */
Ticker::TickGame();

/* Tick the renderer, show the frame and clamp to desired framerate. */
Ticker::TickDraw();
#if defined USE_SDL
SDL_GL_SwapBuffers();
#endif
Ticker::ClampFps();
}
}



+ 161
- 108
src/ticker.cpp Bestand weergeven

@@ -67,6 +67,12 @@ private:
Timer timer;
float deltams, bias, fps;

/* Background threads */
static void *GameThreadMain(void *p);
static void *DrawThreadMain(void *p); /* unused */
Thread *gamethread, *drawthread;
Queue gametick, drawtick;

/* Shutdown management */
int quit, quitframe, quitdelay, panic;
}
@@ -141,145 +147,188 @@ int Ticker::Unref(Entity *entity)
return --entity->ref;
}

void Ticker::Setup(float fps)
void *TickerData::GameThreadMain(void *p)
{
data->fps = fps;
}
for (;;)
{
int tick = data->gametick.Pop();
if (!tick)
break;

void Ticker::TickGame()
{
Profiler::Stop(Profiler::STAT_TICK_FRAME);
Profiler::Start(Profiler::STAT_TICK_FRAME);
Profiler::Stop(Profiler::STAT_TICK_FRAME);
Profiler::Start(Profiler::STAT_TICK_FRAME);

Profiler::Start(Profiler::STAT_TICK_GAME);
Profiler::Start(Profiler::STAT_TICK_GAME);

#if 0
Log::Debug("-------------------------------------\n");
for (int i = 0; i < Entity::ALLGROUP_END; i++)
{
Log::Debug("%s Group %i\n",
(i < Entity::GAMEGROUP_END) ? "Game" : "Draw", i);

for (Entity *e = data->list[i]; e; )
Log::Debug("-------------------------------------\n");
for (int i = 0; i < Entity::ALLGROUP_END; i++)
{
Log::Debug(" \\-- %s (ref %i, destroy %i)\n", e->GetName(), e->ref, e->destroy);
e = (i < Entity::GAMEGROUP_END) ? e->gamenext : e->drawnext;
Log::Debug("%s Group %i\n",
(i < Entity::GAMEGROUP_END) ? "Game" : "Draw", i);

for (Entity *e = data->list[i]; e; )
{
Log::Debug(" \\-- %s (ref %i, destroy %i)\n", e->GetName(), e->ref, e->destroy);
e = (i < Entity::GAMEGROUP_END) ? e->gamenext : e->drawnext;
}
}
}
#endif

data->frame++;
data->frame++;

/* If recording with fixed framerate, set deltams to a fixed value */
if (data->recording && data->fps)
{
data->deltams = 1000.0f / data->fps;
}
else
{
data->deltams = data->timer.GetMs();
data->bias += data->deltams;
}
/* If recording with fixed framerate, set deltams to a fixed value */
if (data->recording && data->fps)
{
data->deltams = 1000.0f / data->fps;
}
else
{
data->deltams = data->timer.GetMs();
data->bias += data->deltams;
}

/* If shutdown is stuck, kick the first entity we meet and see
* whether it makes things better. Note that it is always a bug to
* have referenced entities after 20 frames, but at least this
* safeguard makes it possible to exit the program cleanly. */
if (data->quit && !((data->frame - data->quitframe) % data->quitdelay))
{
int n = 0;
data->panic = 2 * (data->panic + 1);
/* If shutdown is stuck, kick the first entity we meet and see
* whether it makes things better. Note that it is always a bug to
* have referenced entities after 20 frames, but at least this
* safeguard makes it possible to exit the program cleanly. */
if (data->quit && !((data->frame - data->quitframe) % data->quitdelay))
{
int n = 0;
data->panic = 2 * (data->panic + 1);

for (int i = 0; i < Entity::ALLGROUP_END && n < data->panic; i++)
for (Entity *e = data->list[i]; e && n < data->panic; e = e->gamenext)
if (e->ref)
{
for (int i = 0; i < Entity::ALLGROUP_END && n < data->panic; i++)
for (Entity *e = data->list[i]; e && n < data->panic; e = e->gamenext)
if (e->ref)
{
#if !LOL_RELEASE
Log::Error("poking %s\n", e->GetName());
Log::Error("poking %s\n", e->GetName());
#endif
e->ref--;
n++;
}
e->ref--;
n++;
}

#if !LOL_RELEASE
if (n)
Log::Error("%i entities stuck after %i frames, poked %i\n",
data->nentities, data->quitdelay, n);
if (n)
Log::Error("%i entities stuck after %i frames, poked %i\n",
data->nentities, data->quitdelay, n);
#endif

data->quitdelay = data->quitdelay > 1 ? data->quitdelay / 2 : 1;
}
data->quitdelay = data->quitdelay > 1 ? data->quitdelay / 2 : 1;
}

/* Garbage collect objects that can be destroyed. We can do this
* before inserting awaiting objects, because only objects already in
* the tick lists can be marked for destruction. */
for (int i = 0; i < Entity::ALLGROUP_END; i++)
for (Entity *e = data->list[i], *prev = NULL; e; )
{
if (e->destroy && i < Entity::GAMEGROUP_END)
/* Garbage collect objects that can be destroyed. We can do this
* before inserting awaiting objects, because only objects already
* inthe tick lists can be marked for destruction. */
for (int i = 0; i < Entity::ALLGROUP_END; i++)
for (Entity *e = data->list[i], *prev = NULL; e; )
{
/* If entity is to be destroyed, remove it from the
* game tick list. */
(prev ? prev->gamenext : data->list[i]) = e->gamenext;

e = e->gamenext;
if (e->destroy && i < Entity::GAMEGROUP_END)
{
/* If entity is to be destroyed, remove it from the
* game tick list. */
(prev ? prev->gamenext : data->list[i]) = e->gamenext;

e = e->gamenext;
}
else if (e->destroy)
{
/* If entity is to be destroyed, remove it from the
* draw tick list and destroy it. */
(prev ? prev->drawnext : data->list[i]) = e->drawnext;

Entity *tmp = e;
e = e->drawnext; /* Can only be in a draw group list */
delete tmp;

data->nentities--;
}
else
{
if (e->ref <= 0 && i >= Entity::DRAWGROUP_BEGIN)
e->destroy = 1;
prev = e;
e = (i < Entity::GAMEGROUP_END) ? e->gamenext : e->drawnext;
}
}
else if (e->destroy)
{
/* If entity is to be destroyed, remove it from the
* draw tick list and destroy it. */
(prev ? prev->drawnext : data->list[i]) = e->drawnext;

Entity *tmp = e;
e = e->drawnext; /* Can only be in a draw group list */
delete tmp;
/* Insert waiting objects into the appropriate lists */
while (data->todolist)
{
Entity *e = data->todolist;
data->todolist = e->gamenext;

data->nentities--;
}
else
{
if (e->ref <= 0 && i >= Entity::DRAWGROUP_BEGIN)
e->destroy = 1;
prev = e;
e = (i < Entity::GAMEGROUP_END) ? e->gamenext : e->drawnext;
}
e->gamenext = data->list[e->gamegroup];
data->list[e->gamegroup] = e;
e->drawnext = data->list[e->drawgroup];
data->list[e->drawgroup] = e;
}

/* Insert waiting objects into the appropriate lists */
while (data->todolist)
{
Entity *e = data->todolist;
data->todolist = e->gamenext;

e->gamenext = data->list[e->gamegroup];
data->list[e->gamegroup] = e;
e->drawnext = data->list[e->drawgroup];
data->list[e->drawgroup] = e;
}

/* Tick objects for the game loop */
for (int i = Entity::GAMEGROUP_BEGIN; i < Entity::GAMEGROUP_END; i++)
for (Entity *e = data->list[i]; e; e = e->gamenext)
if (!e->destroy)
{
/* Tick objects for the game loop */
for (int i = Entity::GAMEGROUP_BEGIN; i < Entity::GAMEGROUP_END; i++)
for (Entity *e = data->list[i]; e; e = e->gamenext)
if (!e->destroy)
{
#if !LOL_RELEASE
if (e->state != Entity::STATE_IDLE)
Log::Error("entity not idle for game tick\n");
e->state = Entity::STATE_PRETICK_GAME;
if (e->state != Entity::STATE_IDLE)
Log::Error("entity not idle for game tick\n");
e->state = Entity::STATE_PRETICK_GAME;
#endif
e->TickGame(data->deltams);
e->TickGame(data->deltams);
#if !LOL_RELEASE
if (e->state != Entity::STATE_POSTTICK_GAME)
Log::Error("entity missed super game tick\n");
e->state = Entity::STATE_IDLE;
if (e->state != Entity::STATE_POSTTICK_GAME)
Log::Error("entity missed super game tick\n");
e->state = Entity::STATE_IDLE;
#endif
}
}

Profiler::Stop(Profiler::STAT_TICK_GAME);

data->drawtick.Push(1);
}

data->drawtick.Push(0);

return NULL;
}

void *TickerData::DrawThreadMain(void *p)
{
for (;;)
{
int tick = data->drawtick.Pop();
if (!tick)
break;

data->gametick.Push(1);
}

Profiler::Stop(Profiler::STAT_TICK_GAME);
return NULL;
}

void Ticker::SetState(Entity *entity, uint32_t state)
{

}

void Ticker::SetStateWhenMatch(Entity *entity, uint32_t state,
Entity *other_entity, uint32_t other_state)
{

}

void Ticker::Setup(float fps)
{
data->fps = fps;

data->gamethread = new Thread(TickerData::GameThreadMain, NULL);
data->gametick.Push(1);
}

void Ticker::TickDraw()
{
data->drawtick.Pop();

Profiler::Start(Profiler::STAT_TICK_DRAW);

Video::Clear();
@@ -322,10 +371,11 @@ void Ticker::TickDraw()

Profiler::Stop(Profiler::STAT_TICK_DRAW);
Profiler::Start(Profiler::STAT_TICK_BLIT);
}

void Ticker::ClampFps()
{
/* Signal game thread that it can carry on */
data->gametick.Push(1);

/* Clamp FPS */
Profiler::Stop(Profiler::STAT_TICK_BLIT);

/* If framerate is fixed, force wait time to 1/FPS. Otherwise, set wait
@@ -368,6 +418,9 @@ void Ticker::Shutdown()

data->quit = 1;
data->quitframe = data->frame;

data->gametick.Push(0);
delete data->gamethread;
}

int Ticker::Finished()


+ 4
- 2
src/ticker.h Bestand weergeven

@@ -32,15 +32,17 @@ public:
static int Unref(Entity *entity);

static void Setup(float fps);
static void TickGame();
static void TickDraw();
static void ClampFps();
static void StartBenchmark();
static void StopBenchmark();
static void StartRecording();
static void StopRecording();
static int GetFrameNum();

static void SetState(Entity *entity, uint32_t state);
static void SetStateWhenMatch(Entity *entity, uint32_t state,
Entity *other_entity, uint32_t other_state);

static void Shutdown();
static int Finished();
};


Laden…
Annuleren
Opslaan