From 615c968e2d97d4d7b5bfa7e5df38f0774cd65df2 Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Thu, 7 Mar 2019 00:35:24 +0100 Subject: [PATCH] engine: minor changes in ticker. --- src/application/sdl-app.cpp | 3 +- src/engine/entity.cpp | 21 +++--------- src/engine/entity.h | 26 ++------------ src/engine/ticker.cpp | 67 ++++++++++++++++++++----------------- src/engine/ticker.h | 6 ++-- src/lol/engine/tickable.h | 9 +++++ src/lol/sys/thread.h | 7 ++-- 7 files changed, 63 insertions(+), 76 deletions(-) diff --git a/src/application/sdl-app.cpp b/src/application/sdl-app.cpp index a2c005b7..01736fda 100644 --- a/src/application/sdl-app.cpp +++ b/src/application/sdl-app.cpp @@ -177,7 +177,7 @@ SdlApp::SdlApp(char const *title, ivec2 res, float fps) : ivec2 screen_size = res; /* Initialise everything */ - Ticker::Setup(fps); + ticker::setup(fps); audio::init(); /* Autoreleased objects */ @@ -210,6 +210,7 @@ SdlApp::~SdlApp() SDL_Quit(); #endif delete data; + ticker::teardown(); } } /* namespace lol */ diff --git a/src/engine/entity.cpp b/src/engine/entity.cpp index 14c86432..dac9bc3b 100644 --- a/src/engine/entity.cpp +++ b/src/engine/entity.cpp @@ -27,7 +27,7 @@ Entity::Entity() : m_destroy(0) { #if !LOL_BUILD_RELEASE - m_tickstate = STATE_IDLE; + m_tickstate = tickable::state::idle; #endif m_gamegroup = tickable::group::game::entity; m_drawgroup = tickable::group::draw::entity; @@ -61,9 +61,9 @@ void Entity::tick_game(float seconds) { UNUSED(seconds); #if !LOL_BUILD_RELEASE - if (m_tickstate != STATE_PRETICK_GAME) + if (m_tickstate != tickable::state::pre_game) msg::error("invalid entity game tick\n"); - m_tickstate = STATE_POSTTICK_GAME; + m_tickstate = tickable::state::post_game; #endif } @@ -71,22 +71,11 @@ void Entity::tick_draw(float seconds, Scene &scene) { UNUSED(seconds, scene); #if !LOL_BUILD_RELEASE - if (m_tickstate != STATE_PRETICK_DRAW) + if (m_tickstate != tickable::state::pre_draw) msg::error("invalid entity draw tick\n"); - m_tickstate = STATE_POSTTICK_DRAW; + m_tickstate = tickable::state::post_draw; #endif } -void Entity::SetState(uint32_t state) -{ - Ticker::SetState(this, state); -} - -void Entity::SetStateWhenMatch(uint32_t state, - Entity *other_entity, uint32_t other_state) -{ - Ticker::SetStateWhenMatch(this, state, other_entity, other_state); -} - } /* namespace lol */ diff --git a/src/engine/entity.h b/src/engine/entity.h index 816ad519..de6c2297 100644 --- a/src/engine/entity.h +++ b/src/engine/entity.h @@ -47,8 +47,7 @@ class Entity { friend class Scene; friend class ticker; - friend class TickerData; - friend class Emcee; + friend class ticker_data; public: virtual std::string GetName() const; @@ -70,33 +69,12 @@ protected: InitState m_initstate; #if !LOL_BUILD_RELEASE - enum - { - STATE_IDLE = 0, - STATE_PRETICK_GAME, - STATE_POSTTICK_GAME, - STATE_PRETICK_DRAW, - STATE_POSTTICK_DRAW, - } - m_tickstate; + tickable::state m_tickstate; #endif tickable::group::game m_gamegroup; tickable::group::draw m_drawgroup; - // Emcee begin -private: - void SetState(uint32_t newstate); - void SetStateWhenMatch(uint32_t newstate, - Entity *other_entity, uint32_t other_state); - virtual uint32_t OnStateChanged(uint32_t newstate) - { - return LOLm_state = newstate; - } - - uint32_t LOLm_state; - // Emcee end - private: int m_ref, m_autorelease, m_destroy; uint64_t m_scene_mask = 0; diff --git a/src/engine/ticker.cpp b/src/engine/ticker.cpp index cea13b5a..1951388a 100644 --- a/src/engine/ticker.cpp +++ b/src/engine/ticker.cpp @@ -23,13 +23,13 @@ namespace lol * Ticker implementation class */ -static class TickerData +class ticker_data { friend class ticker; public: - TickerData() : - DEPRECATED_nentities(0), + ticker_data() + : DEPRECATED_nentities(0), frame(0), recording(0), deltatime(0), bias(0), fps(0), #if LOL_BUILD_DEBUG keepalive(0), @@ -38,7 +38,7 @@ public: { } - ~TickerData() + ~ticker_data() { ASSERT(DEPRECATED_nentities == 0, "still %d entities in ticker\n", DEPRECATED_nentities); @@ -51,6 +51,7 @@ public: disktick.push(0); gamethread.release(); diskthread.release(); + ASSERT(drawtick.size() == 0); #endif } @@ -90,10 +91,9 @@ private: /* Shutdown management */ int quit, quitframe, quitdelay, panic; -} -tickerdata; +}; -static TickerData * const data = &tickerdata; +static std::unique_ptr data; // // Add/remove tickable objects @@ -167,7 +167,7 @@ int Ticker::Unref(Entity *entity) } #if LOL_FEATURE_THREADS -void TickerData::GameThreadMain() +void ticker_data::GameThreadMain() { #if LOL_BUILD_DEBUG msg::debug("ticker game thread initialised\n"); @@ -193,7 +193,7 @@ void TickerData::GameThreadMain() #endif /* LOL_FEATURE_THREADS */ #if LOL_FEATURE_THREADS -void TickerData::DrawThreadMain() /* unused */ +void ticker_data::DrawThreadMain() /* unused */ { #if LOL_BUILD_DEBUG msg::debug("ticker draw thread initialised\n"); @@ -217,7 +217,7 @@ void TickerData::DrawThreadMain() /* unused */ #endif /* LOL_FEATURE_THREADS */ #if LOL_FEATURE_THREADS -void TickerData::DiskThreadMain() +void ticker_data::DiskThreadMain() { /* FIXME: temporary hack to avoid crashes on the PS3 */ disktick.pop(); @@ -225,7 +225,7 @@ void TickerData::DiskThreadMain() #endif /* LOL_FEATURE_THREADS */ //----------------------------------------------------------------------------- -void TickerData::GameThreadTick() +void ticker_data::GameThreadTick() { Profiler::Stop(Profiler::STAT_TICK_FRAME); Profiler::Start(Profiler::STAT_TICK_FRAME); @@ -419,17 +419,17 @@ void TickerData::GameThreadTick() if (!e->m_destroy) { #if !LOL_BUILD_RELEASE - if (e->m_tickstate != Entity::STATE_IDLE) + if (e->m_tickstate != tickable::state::idle) msg::error("entity %s [%p] not idle for game tick\n", e->GetName().c_str(), e); - e->m_tickstate = Entity::STATE_PRETICK_GAME; + e->m_tickstate = tickable::state::pre_game; #endif e->tick_game(data->deltatime); #if !LOL_BUILD_RELEASE - if (e->m_tickstate != Entity::STATE_POSTTICK_GAME) + if (e->m_tickstate != tickable::state::post_game) msg::error("entity %s [%p] missed super game tick\n", e->GetName().c_str(), e); - e->m_tickstate = Entity::STATE_IDLE; + e->m_tickstate = tickable::state::idle; #endif } } @@ -439,7 +439,7 @@ void TickerData::GameThreadTick() } //----------------------------------------------------------------------------- -void TickerData::DrawThreadTick() +void ticker_data::DrawThreadTick() { Profiler::Start(Profiler::STAT_TICK_DRAW); @@ -473,17 +473,17 @@ void TickerData::DrawThreadTick() if (!e->m_destroy) { #if !LOL_BUILD_RELEASE - if (e->m_tickstate != Entity::STATE_IDLE) + if (e->m_tickstate != tickable::state::idle) msg::error("entity %s [%p] not idle for draw tick\n", e->GetName().c_str(), e); - e->m_tickstate = Entity::STATE_PRETICK_DRAW; + e->m_tickstate = tickable::state::pre_draw; #endif e->tick_draw(data->deltatime, scene); #if !LOL_BUILD_RELEASE - if (e->m_tickstate != Entity::STATE_POSTTICK_DRAW) + if (e->m_tickstate != tickable::state::post_draw) msg::error("entity %s [%p] missed super draw tick\n", e->GetName().c_str(), e); - e->m_tickstate = Entity::STATE_IDLE; + e->m_tickstate = tickable::state::idle; #endif } } @@ -501,7 +501,7 @@ void TickerData::DrawThreadTick() Profiler::Stop(Profiler::STAT_TICK_DRAW); } -void TickerData::DiskThreadTick() +void ticker_data::DiskThreadTick() { ; } @@ -517,28 +517,35 @@ void Ticker::SetStateWhenMatch(Entity * /* entity */, uint32_t /* state */, } -//----------------------------------------------------------------------------- -void Ticker::Setup(float fps) +void ticker::setup(float fps) { + data = std::make_unique(); data->fps = fps; #if LOL_FEATURE_THREADS - data->gamethread = std::make_unique(std::bind(&TickerData::GameThreadMain, data)); + data->gamethread = std::make_unique(std::bind(&ticker_data::GameThreadMain, data.get())); data->drawtick.push(1); - data->diskthread = std::make_unique(std::bind(&TickerData::DiskThreadMain, data)); + data->diskthread = std::make_unique(std::bind(&ticker_data::DiskThreadMain, data.get())); #endif } -void Ticker::tick_draw() +void ticker::teardown() +{ + data.release(); +} + +void ticker::tick_draw() { #if LOL_FEATURE_THREADS - data->drawtick.pop(); + int n = data->drawtick.pop(); + if (n == 0) + return; #else - TickerData::GameThreadTick(); + ticker_data::GameThreadTick(); #endif - TickerData::DrawThreadTick(); + ticker_data::DrawThreadTick(); Profiler::Start(Profiler::STAT_TICK_BLIT); @@ -546,7 +553,7 @@ void Ticker::tick_draw() #if LOL_FEATURE_THREADS data->gametick.push(1); #else - TickerData::DiskThreadTick(); + ticker_data::DiskThreadTick(); #endif /* Clamp FPS */ diff --git a/src/engine/ticker.h b/src/engine/ticker.h index 92438d17..84eca0a7 100644 --- a/src/engine/ticker.h +++ b/src/engine/ticker.h @@ -29,6 +29,10 @@ namespace lol class ticker { public: + static void setup(float fps); + static void tick_draw(); + static void teardown(); + static void add(std::shared_ptr entity); static void remove(std::shared_ptr entity); @@ -37,8 +41,6 @@ public: static void Ref(class Entity *entity); static int Unref(class Entity *entity); - static void Setup(float fps); - static void tick_draw(); static void StartBenchmark(); static void StopBenchmark(); static void StartRecording(); diff --git a/src/lol/engine/tickable.h b/src/lol/engine/tickable.h index 8888134c..ec832764 100644 --- a/src/lol/engine/tickable.h +++ b/src/lol/engine/tickable.h @@ -45,6 +45,15 @@ public: return p; } + enum class state + { + idle, + pre_game, + post_game, + pre_draw, + post_draw, + }; + // Tick groups struct group { diff --git a/src/lol/sys/thread.h b/src/lol/sys/thread.h index 2a9e1ac2..501edefc 100644 --- a/src/lol/sys/thread.h +++ b/src/lol/sys/thread.h @@ -1,7 +1,7 @@ // // Lol Engine // -// Copyright © 2010—2017 Sam Hocevar +// Copyright © 2010—2019 Sam Hocevar // // Lol Engine is free software. It comes without any warranty, to // the extent permitted by applicable law. You can redistribute it @@ -94,8 +94,9 @@ public: queue() : m_start(0), m_count(0) - { - } + {} + + int size() const { return m_count; } // Will block the thread if another has already locked void push(T value)