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
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]);
#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 */


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

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

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

~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);

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

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

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

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

@@ -90,23 +94,38 @@ 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)
{
/* 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
* 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. */
data->m_autolist.push(entity);
data->DEPRECATED_m_autolist.push(entity);
entity->m_autorelease = 1;
entity->m_ref = 1;

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

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
* very fast since the last entry in autolist is the last
* 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;
}
}
@@ -219,9 +238,9 @@ void TickerData::GameThreadTick()
msg::debug("%s Group %d\n",
(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",
e, e->GetName().c_str(), e->m_ref, e->m_destroy);
}
@@ -270,9 +289,9 @@ void TickerData::GameThreadTick()
data->panic = 2 * (data->panic + 1);

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 !LOL_BUILD_RELEASE
@@ -286,7 +305,7 @@ void TickerData::GameThreadTick()
#if !LOL_BUILD_RELEASE
if (n)
msg::error("%d entities stuck after %d frames, poked %d\n",
data->nentities, data->quitdelay, n);
data->DEPRECATED_nentities, data->quitdelay, n);
#endif

data->quitdelay = data->quitdelay > 1 ? data->quitdelay / 2 : 1;
@@ -299,19 +318,19 @@ void TickerData::GameThreadTick()
bool do_reserve = true;
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)
{
/* Game tick list:
* 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)
{
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);
}
@@ -320,7 +339,7 @@ void TickerData::GameThreadTick()
/* Draw tick list:
* If entity is to be destroyed,
* remove it and store it. */
data->m_list[g].remove_swap(i);
data->DEPRECATED_m_list[g].remove_swap(i);
int removal_count = 0;
for (int j = 0; j < Scene::GetCount(); j++)
{
@@ -328,12 +347,12 @@ void TickerData::GameThreadTick()
if (Scene::GetScene(j).IsRelevant(e))
removal_count++;
//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)
{
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);
}
@@ -346,15 +365,15 @@ void TickerData::GameThreadTick()
}
if (!!destroy_list.count())
{
data->nentities -= destroy_list.count();
data->DEPRECATED_nentities -= destroy_list.count();
for (Entity* e : destroy_list)
delete e;
}

/* 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 (e->m_scene_mask == 0)
@@ -362,12 +381,12 @@ void TickerData::GameThreadTick()
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 (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;
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 (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++;
}
//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();
}

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 */
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 !LOL_BUILD_RELEASE
@@ -446,9 +465,9 @@ void TickerData::DrawThreadTick()
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)
{
@@ -503,10 +522,10 @@ void Ticker::Setup(float fps)
data->fps = fps;

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

@@ -566,10 +585,10 @@ int Ticker::GetFrameNum()
void Ticker::Shutdown()
{
/* 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;
@@ -578,7 +597,7 @@ void Ticker::Shutdown()

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

} /* 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.
//

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

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

namespace lol
{
@@ -28,9 +29,13 @@ namespace lol
class ticker
{
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 tick_draw();
@@ -40,9 +45,9 @@ public:
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 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 int Finished();
@@ -51,6 +56,7 @@ private:
ticker() {}
};

// The old API
typedef ticker Ticker;

} /* namespace lol */


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

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

#include <cstdint>
#include <memory>

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:
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
template<typename T>
static typename std::enable_if<std::is_base_of<tickable, T>::value, std::shared_ptr<T>>::type


Loading…
Cancel
Save