Browse Source

engine: continue deprecating the entity stuff.

legacy
Sam Hocevar 6 years ago
parent
commit
e01d92f384
5 changed files with 112 additions and 75 deletions
  1. +1
    -1
      src/debug/fps.cpp
  2. +16
    -0
      src/engine/tickable.cpp
  3. +74
    -55
      src/engine/ticker.cpp
  4. +14
    -8
      src/engine/ticker.h
  5. +7
    -11
      src/lol/engine/tickable.h

+ 1
- 1
src/debug/fps.cpp View File

@@ -45,7 +45,7 @@ DebugFps::DebugFps(int x, int y)
} }
#else #else
data->lines[0] = new Text("", "data/font/ascii.png"); data->lines[0] = new Text("", "data/font/ascii.png");
data->lines[0]->SetPos(vec3(ivec3(x, y, 100)));
data->lines[0]->SetPos(vec3(ivec3(x, y, 1)));
Ticker::Ref(data->lines[0]); Ticker::Ref(data->lines[0]);
#endif #endif
} }


+ 16
- 0
src/engine/tickable.cpp View File

@@ -29,5 +29,21 @@ tickable::~tickable()
{ {
} }


void tickable::init()
{
}

void tickable::fini()
{
}

void tickable::tick_game(float seconds)
{
}

void tickable::tick_draw(float seconds, class Scene &scene)
{
}

} /* namespace lol */ } /* namespace lol */



+ 74
- 55
src/engine/ticker.cpp View File

@@ -29,7 +29,7 @@ static class TickerData


public: public:
TickerData() : TickerData() :
nentities(0),
DEPRECATED_nentities(0),
frame(0), recording(0), deltatime(0), bias(0), fps(0), frame(0), recording(0), deltatime(0), bias(0), fps(0),
#if LOL_BUILD_DEBUG #if LOL_BUILD_DEBUG
keepalive(0), keepalive(0),
@@ -40,26 +40,29 @@ public:


~TickerData() ~TickerData()
{ {
ASSERT(nentities == 0,
"still %d entities in ticker\n", nentities);
ASSERT(m_autolist.count() == 0,
"still %d autoreleased entities\n", m_autolist.count());
ASSERT(DEPRECATED_nentities == 0,
"still %d entities in ticker\n", DEPRECATED_nentities);
ASSERT(DEPRECATED_m_autolist.count() == 0,
"still %d autoreleased entities\n", DEPRECATED_m_autolist.count());
msg::debug("%d frames required to quit\n", frame - quitframe); msg::debug("%d frames required to quit\n", frame - quitframe);


#if LOL_FEATURE_THREADS #if LOL_FEATURE_THREADS
gametick.push(0); gametick.push(0);
disktick.push(0); disktick.push(0);
delete gamethread;
delete diskthread;
#endif #endif
} }


private: private:
// Tickables waiting to be inserted
queue<std::shared_ptr<tickable>> m_todo;

std::unordered_set<std::shared_ptr<tickable>> m_tickables;

/* Entity management */ /* Entity management */
array<Entity *> m_todolist, m_todolist_delayed, m_autolist;
array<Entity *> m_list[(int)tickable::group::all::end];
array<int> m_scenes[(int)tickable::group::all::end];
int nentities;
array<Entity *> DEPRECATED_m_todolist, DEPRECATED_m_todolist_delayed, DEPRECATED_m_autolist;
array<Entity *> DEPRECATED_m_list[(int)tickable::group::all::end];
array<int> DEPRECATED_m_scenes[(int)tickable::group::all::end];
int DEPRECATED_nentities;


/* Fixed framerate management */ /* Fixed framerate management */
int frame, recording; int frame, recording;
@@ -77,9 +80,10 @@ private:
#if LOL_FEATURE_THREADS #if LOL_FEATURE_THREADS
/* The associated background threads */ /* The associated background threads */
void GameThreadMain(); void GameThreadMain();
void DrawThreadMain(); /* unused */
void DrawThreadMain(); /* unused for now */
void DiskThreadMain(); void DiskThreadMain();
thread *gamethread, *drawthread, *diskthread;
thread *drawthread;
std::unique_ptr<thread> gamethread, diskthread;
queue<int> gametick, drawtick, disktick; queue<int> gametick, drawtick, disktick;
#endif #endif


@@ -90,23 +94,38 @@ tickerdata;


static TickerData * const data = &tickerdata; static TickerData * const data = &tickerdata;


/*
* Ticker public class
*/
//
// Add/remove tickable objects
//

void ticker::add(std::shared_ptr<tickable> entity)
{
data->m_tickables.insert(entity);
}

void ticker::remove(std::shared_ptr<tickable> entity)
{
//weak_ptr<tickable> p = entity;
data->m_tickables.erase(entity);
}

//
// Old API for entities
//


void Ticker::Register(Entity *entity) void Ticker::Register(Entity *entity)
{ {
/* If we are called from its constructor, the object's vtable is not /* If we are called from its constructor, the object's vtable is not
* ready yet, so we do not know which group this entity belongs to. Wait * ready yet, so we do not know which group this entity belongs to. Wait
* until the first tick. */ * until the first tick. */
data->m_todolist_delayed.push(entity);
data->DEPRECATED_m_todolist_delayed.push(entity);


/* Objects are autoreleased by default. Put them in a list. */ /* Objects are autoreleased by default. Put them in a list. */
data->m_autolist.push(entity);
data->DEPRECATED_m_autolist.push(entity);
entity->m_autorelease = 1; entity->m_autorelease = 1;
entity->m_ref = 1; entity->m_ref = 1;


data->nentities++;
data->DEPRECATED_nentities++;
} }


void Ticker::Ref(Entity *entity) void Ticker::Ref(Entity *entity)
@@ -121,11 +140,11 @@ void Ticker::Ref(Entity *entity)
/* Get the entity out of the m_autorelease list. This is usually /* Get the entity out of the m_autorelease list. This is usually
* very fast since the last entry in autolist is the last * very fast since the last entry in autolist is the last
* registered entity. */ * registered entity. */
for (int i = data->m_autolist.count(); i--; )
for (int i = data->DEPRECATED_m_autolist.count(); i--; )
{ {
if (data->m_autolist[i] == entity)
if (data->DEPRECATED_m_autolist[i] == entity)
{ {
data->m_autolist.remove_swap(i);
data->DEPRECATED_m_autolist.remove_swap(i);
break; break;
} }
} }
@@ -219,9 +238,9 @@ void TickerData::GameThreadTick()
msg::debug("%s Group %d\n", msg::debug("%s Group %d\n",
(g < (int)tickable::group::game::end) ? "Game" : "Draw", g); (g < (int)tickable::group::game::end) ? "Game" : "Draw", g);


for (int i = 0; i < data->m_list[g].count(); ++i)
for (int i = 0; i < data->DEPRECATED_m_list[g].count(); ++i)
{ {
Entity *e = data->m_list[g][i];
Entity *e = data->DEPRECATED_m_list[g][i];
msg::debug(" \\-- [%p] %s (m_ref %d, destroy %d)\n", msg::debug(" \\-- [%p] %s (m_ref %d, destroy %d)\n",
e, e->GetName().c_str(), e->m_ref, e->m_destroy); e, e->GetName().c_str(), e->m_ref, e->m_destroy);
} }
@@ -270,9 +289,9 @@ void TickerData::GameThreadTick()
data->panic = 2 * (data->panic + 1); data->panic = 2 * (data->panic + 1);


for (int g = 0; g < (int)tickable::group::all::end && n < data->panic; ++g) for (int g = 0; g < (int)tickable::group::all::end && n < data->panic; ++g)
for (int i = 0; i < data->m_list[g].count() && n < data->panic; ++i)
for (int i = 0; i < data->DEPRECATED_m_list[g].count() && n < data->panic; ++i)
{ {
Entity * e = data->m_list[g][i];
Entity * e = data->DEPRECATED_m_list[g][i];
if (e->m_ref) if (e->m_ref)
{ {
#if !LOL_BUILD_RELEASE #if !LOL_BUILD_RELEASE
@@ -286,7 +305,7 @@ void TickerData::GameThreadTick()
#if !LOL_BUILD_RELEASE #if !LOL_BUILD_RELEASE
if (n) if (n)
msg::error("%d entities stuck after %d frames, poked %d\n", msg::error("%d entities stuck after %d frames, poked %d\n",
data->nentities, data->quitdelay, n);
data->DEPRECATED_nentities, data->quitdelay, n);
#endif #endif


data->quitdelay = data->quitdelay > 1 ? data->quitdelay / 2 : 1; data->quitdelay = data->quitdelay > 1 ? data->quitdelay / 2 : 1;
@@ -299,19 +318,19 @@ void TickerData::GameThreadTick()
bool do_reserve = true; bool do_reserve = true;
for (int g = 0; g < (int)tickable::group::all::end; ++g) for (int g = 0; g < (int)tickable::group::all::end; ++g)
{ {
for (int i = data->m_list[g].count(); i--;)
for (int i = data->DEPRECATED_m_list[g].count(); i--;)
{ {
Entity *e = data->m_list[g][i];
Entity *e = data->DEPRECATED_m_list[g][i];


if (e->m_destroy && g < (int)tickable::group::game::end) if (e->m_destroy && g < (int)tickable::group::game::end)
{ {
/* Game tick list: /* Game tick list:
* If entity is to be destroyed, remove it */ * If entity is to be destroyed, remove it */
data->m_list[g].remove_swap(i);
data->DEPRECATED_m_list[g].remove_swap(i);
if (do_reserve) if (do_reserve)
{ {
do_reserve = false; do_reserve = false;
destroy_list.reserve(data->nentities); //Should it be less ?
destroy_list.reserve(data->DEPRECATED_nentities); //Should it be less ?
} }
destroy_list.push_unique(e); destroy_list.push_unique(e);
} }
@@ -320,7 +339,7 @@ void TickerData::GameThreadTick()
/* Draw tick list: /* Draw tick list:
* If entity is to be destroyed, * If entity is to be destroyed,
* remove it and store it. */ * remove it and store it. */
data->m_list[g].remove_swap(i);
data->DEPRECATED_m_list[g].remove_swap(i);
int removal_count = 0; int removal_count = 0;
for (int j = 0; j < Scene::GetCount(); j++) for (int j = 0; j < Scene::GetCount(); j++)
{ {
@@ -328,12 +347,12 @@ void TickerData::GameThreadTick()
if (Scene::GetScene(j).IsRelevant(e)) if (Scene::GetScene(j).IsRelevant(e))
removal_count++; removal_count++;
//Update scene index //Update scene index
data->m_scenes[(int)e->m_drawgroup][j] -= removal_count;
data->DEPRECATED_m_scenes[(int)e->m_drawgroup][j] -= removal_count;
} }
if (do_reserve) if (do_reserve)
{ {
do_reserve = false; do_reserve = false;
destroy_list.reserve(data->nentities); //Should it be less ?
destroy_list.reserve(data->DEPRECATED_nentities); //Should it be less ?
} }
destroy_list.push_unique(e); destroy_list.push_unique(e);
} }
@@ -346,15 +365,15 @@ void TickerData::GameThreadTick()
} }
if (!!destroy_list.count()) if (!!destroy_list.count())
{ {
data->nentities -= destroy_list.count();
data->DEPRECATED_nentities -= destroy_list.count();
for (Entity* e : destroy_list) for (Entity* e : destroy_list)
delete e; delete e;
} }


/* Insert waiting objects into the appropriate lists */ /* Insert waiting objects into the appropriate lists */
while (data->m_todolist.count())
while (data->DEPRECATED_m_todolist.count())
{ {
Entity *e = data->m_todolist.last();
Entity *e = data->DEPRECATED_m_todolist.last();


//If the entity has no mask, default it //If the entity has no mask, default it
if (e->m_scene_mask == 0) if (e->m_scene_mask == 0)
@@ -362,12 +381,12 @@ void TickerData::GameThreadTick()
Scene::GetScene().Link(e); Scene::GetScene().Link(e);
} }


data->m_todolist.remove(-1);
data->m_list[(int)e->m_gamegroup].push(e);
data->DEPRECATED_m_todolist.remove(-1);
data->DEPRECATED_m_list[(int)e->m_gamegroup].push(e);
if (e->m_drawgroup != tickable::group::draw::none) if (e->m_drawgroup != tickable::group::draw::none)
{ {
if (data->m_scenes[(int)e->m_drawgroup].count() < Scene::GetCount())
data->m_scenes[(int)e->m_drawgroup].resize(Scene::GetCount());
if (data->DEPRECATED_m_scenes[(int)e->m_drawgroup].count() < Scene::GetCount())
data->DEPRECATED_m_scenes[(int)e->m_drawgroup].resize(Scene::GetCount());


int added_count = 0; int added_count = 0;
for (int i = 0; i < Scene::GetCount(); i++) for (int i = 0; i < Scene::GetCount(); i++)
@@ -375,11 +394,11 @@ void TickerData::GameThreadTick()
//If entity is concerned by this scene, add it in the list //If entity is concerned by this scene, add it in the list
if (Scene::GetScene(i).IsRelevant(e)) if (Scene::GetScene(i).IsRelevant(e))
{ {
data->m_list[(int)e->m_drawgroup].insert(e, data->m_scenes[(int)e->m_drawgroup][i]);
data->DEPRECATED_m_list[(int)e->m_drawgroup].insert(e, data->DEPRECATED_m_scenes[(int)e->m_drawgroup][i]);
added_count++; added_count++;
} }
//Update scene index //Update scene index
data->m_scenes[(int)e->m_drawgroup][i] += added_count;
data->DEPRECATED_m_scenes[(int)e->m_drawgroup][i] += added_count;
} }
} }


@@ -387,15 +406,15 @@ void TickerData::GameThreadTick()
e->InitGame(); e->InitGame();
} }


data->m_todolist = data->m_todolist_delayed;
data->m_todolist_delayed.clear();
data->DEPRECATED_m_todolist = data->DEPRECATED_m_todolist_delayed;
data->DEPRECATED_m_todolist_delayed.clear();


/* Tick objects for the game loop */ /* Tick objects for the game loop */
for (int g = (int)tickable::group::game::begin; g < (int)tickable::group::game::end && !data->quit /* Stop as soon as required */; ++g) for (int g = (int)tickable::group::game::begin; g < (int)tickable::group::game::end && !data->quit /* Stop as soon as required */; ++g)
{ {
for (int i = 0; i < data->m_list[g].count() && !data->quit /* Stop as soon as required */; ++i)
for (int i = 0; i < data->DEPRECATED_m_list[g].count() && !data->quit /* Stop as soon as required */; ++i)
{ {
Entity *e = data->m_list[g][i];
Entity *e = data->DEPRECATED_m_list[g][i];
if (!e->m_destroy) if (!e->m_destroy)
{ {
#if !LOL_BUILD_RELEASE #if !LOL_BUILD_RELEASE
@@ -446,9 +465,9 @@ void TickerData::DrawThreadTick()
break; break;
} }


for (int i = 0; i < data->m_list[g].count() && !data->quit /* Stop as soon as required */; ++i)
for (int i = 0; i < data->DEPRECATED_m_list[g].count() && !data->quit /* Stop as soon as required */; ++i)
{ {
Entity *e = data->m_list[g][i];
Entity *e = data->DEPRECATED_m_list[g][i];


if (!e->m_destroy) if (!e->m_destroy)
{ {
@@ -503,10 +522,10 @@ void Ticker::Setup(float fps)
data->fps = fps; data->fps = fps;


#if LOL_FEATURE_THREADS #if LOL_FEATURE_THREADS
data->gamethread = new thread(std::bind(&TickerData::GameThreadMain, data));
data->gamethread = std::make_unique<thread>(std::bind(&TickerData::GameThreadMain, data));
data->drawtick.push(1); data->drawtick.push(1);


data->diskthread = new thread(std::bind(&TickerData::DiskThreadMain, data));
data->diskthread = std::make_unique<thread>(std::bind(&TickerData::DiskThreadMain, data));
#endif #endif
} }


@@ -566,10 +585,10 @@ int Ticker::GetFrameNum()
void Ticker::Shutdown() void Ticker::Shutdown()
{ {
/* We're bailing out. Release all m_autorelease objects. */ /* We're bailing out. Release all m_autorelease objects. */
while (data->m_autolist.count())
while (data->DEPRECATED_m_autolist.count())
{ {
data->m_autolist.last()->m_ref--;
data->m_autolist.remove(-1);
data->DEPRECATED_m_autolist.last()->m_ref--;
data->DEPRECATED_m_autolist.remove(-1);
} }


data->quit = 1; data->quit = 1;
@@ -578,7 +597,7 @@ void Ticker::Shutdown()


int Ticker::Finished() int Ticker::Finished()
{ {
return !data->nentities;
return !data->DEPRECATED_nentities;
} }


} /* namespace lol */ } /* namespace lol */


+ 14
- 8
src/engine/ticker.h View File

@@ -18,9 +18,10 @@
// The ticker is a static class that registers entities and ticks them. // The ticker is a static class that registers entities and ticks them.
// //


#include <cstdint>
#include <lol/engine/tickable.h>


#include "engine/entity.h"
#include <cstdint>
#include <memory>


namespace lol namespace lol
{ {
@@ -28,9 +29,13 @@ namespace lol
class ticker class ticker
{ {
public: public:
static void Register(Entity *entity);
static void Ref(Entity *entity);
static int Unref(Entity *entity);
static void add(std::shared_ptr<tickable> entity);
static void remove(std::shared_ptr<tickable> entity);

// The old API
static void Register(class Entity *entity);
static void Ref(class Entity *entity);
static int Unref(class Entity *entity);


static void Setup(float fps); static void Setup(float fps);
static void tick_draw(); static void tick_draw();
@@ -40,9 +45,9 @@ public:
static void StopRecording(); static void StopRecording();
static int GetFrameNum(); 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 SetState(class Entity *entity, uint32_t state);
static void SetStateWhenMatch(class Entity *entity, uint32_t state,
class Entity *other_entity, uint32_t other_state);


static void Shutdown(); static void Shutdown();
static int Finished(); static int Finished();
@@ -51,6 +56,7 @@ private:
ticker() {} ticker() {}
}; };


// The old API
typedef ticker Ticker; typedef ticker Ticker;


} /* namespace lol */ } /* namespace lol */


+ 7
- 11
src/lol/engine/tickable.h View File

@@ -20,26 +20,22 @@
// //


#include <cstdint> #include <cstdint>
#include <memory>


namespace lol namespace lol
{ {


class game_tickable
{
virtual void tick_game(float seconds) = 0;
};

class draw_tickable
{
virtual void tick_draw(float seconds, class Scene &scene) = 0;
};

class tickable : public std::enable_shared_from_this<tickable>
class tickable
{ {
public: public:
tickable(); tickable();
virtual ~tickable(); virtual ~tickable();


virtual void init();
virtual void fini();
virtual void tick_game(float seconds);
virtual void tick_draw(float seconds, class Scene &scene);

// Auto-registering factory // Auto-registering factory
template<typename T> template<typename T>
static typename std::enable_if<std::is_base_of<tickable, T>::value, std::shared_ptr<T>>::type static typename std::enable_if<std::is_base_of<tickable, T>::value, std::shared_ptr<T>>::type


Loading…
Cancel
Save