From ed32f515a36405bd07d48216bef76f10d4ab7c96 Mon Sep 17 00:00:00 2001 From: Andreas Ortmann Date: Mon, 3 Oct 2016 22:58:52 +0200 Subject: [PATCH] adding developer console connect with 'dev bl bla bla lb' command. --- game/CMakeLists.txt | 2 + game/developer_console.cpp | 69 +++++++++++++++++++ game/developer_console.hpp | 47 +++++++++++++ game/network/session.cpp | 10 +-- game/renderer_polygon_3d/particle_batch.hpp | 65 ++++++++++++----- .../renderer_polygon_3d.cpp | 3 +- game/state/commands.cpp | 19 ++++- game/state/state.cpp | 3 +- game/state/state.hpp | 2 +- game/util.cpp | 17 +++++ game/util.hpp | 6 ++ 11 files changed, 211 insertions(+), 32 deletions(-) create mode 100644 game/developer_console.cpp create mode 100644 game/developer_console.hpp diff --git a/game/CMakeLists.txt b/game/CMakeLists.txt index b572f5c..0d249ac 100644 --- a/game/CMakeLists.txt +++ b/game/CMakeLists.txt @@ -13,6 +13,8 @@ set(GAME_SRC game_window.cpp renderer.cpp + developer_console.cpp + renderer_polygon_2d/renderer_polygon_2d.cpp renderer_polygon_3d/renderer_polygon_3d.cpp diff --git a/game/developer_console.cpp b/game/developer_console.cpp new file mode 100644 index 0000000..248f616 --- /dev/null +++ b/game/developer_console.cpp @@ -0,0 +1,69 @@ +#include "developer_console.hpp" + +#include + +#include "util.hpp" + +namespace developer { + DeveloperConsole s_instance; + + DeveloperConsole::CallbackResult DeveloperConsole::CallbackResult::createError(const std::string &answer) + { + return CallbackResult(false, answer); + } + + DeveloperConsole::CallbackResult DeveloperConsole::CallbackResult::createOkay(const std::string &answer) + { + return CallbackResult(true, answer); + } + + DeveloperConsole::CallbackResult::CallbackResult(bool okay, const std::string &answer) + : okay(okay), answer(answer) + { + } + + DeveloperConsole::DeveloperConsole() + { + } + + // static thing. + DeveloperConsole &DeveloperConsole::instance() { + return s_instance; + } + + bool DeveloperConsole::addCallback(const std::string &token, callback_t cb) + { + bool hasWhitespace = false; + for (size_t i=0; i::iterator it = m_callbacks.find(token); + if (it == m_callbacks.end()) { + return DeveloperConsole::CallbackResult::createError("unknown command with token: '" + token + "'"); + } + + return it->second(payload); + } +} diff --git a/game/developer_console.hpp b/game/developer_console.hpp new file mode 100644 index 0000000..150ecaf --- /dev/null +++ b/game/developer_console.hpp @@ -0,0 +1,47 @@ +#pragma once + +#include +#include +#include + +// TODO +// stuff in namespace "developer" can be disabled and the game must function in +// exact the same way just without cool debug features. +namespace developer { + class DeveloperConsole { + public: + class CallbackResult { + private: + CallbackResult(bool okay, const std::string &answer); + + public: + static CallbackResult createError(const std::string &answer); + static CallbackResult createOkay(const std::string &answer); + + public: + // read-only interface to result data + const bool okay; + const std::string answer; + }; + + typedef std::function callback_t; + + DeveloperConsole(); + + // access functionality over this static singleton attribute to make + // it really easy and fast to use + static DeveloperConsole &instance(); + + // register callback for a token. + // token must not have whitespace in it and not be empty. + // old callback will be overridden if any + // return true on succes, false if not saved. + bool addCallback(const std::string &token, callback_t cb); + + // dispatch input received over a communication channel. + CallbackResult dispatchInput(const std::string &token, const std::string &payload); + + private: + std::map m_callbacks; + }; +} diff --git a/game/network/session.cpp b/game/network/session.cpp index f44d3e6..91886d1 100644 --- a/game/network/session.cpp +++ b/game/network/session.cpp @@ -3,11 +3,10 @@ #include "session.hpp" #include "game.hpp" #include "state/commands.hpp" +#include "util.hpp" #include -#include - void trim(std::string &str) { const std::string ws = " \t\r\n"; @@ -28,13 +27,10 @@ bool Session::parse(std::string s) // strip leading/trailing whitespace/newlines as they are always unintional trim(s); - std::istringstream iss(s); - std::string token; - iss >> token; + std::string rest; - // skip token + next whitespace - std::string rest = s.substr(std::min(s.size(), token.size()+1)); + util::splitIntoTokenAndRest(s, token, rest); //std::cout<<"[session] token='" << token << "' rest='" << rest << "'" << std::endl; diff --git a/game/renderer_polygon_3d/particle_batch.hpp b/game/renderer_polygon_3d/particle_batch.hpp index 648e0f7..f906319 100644 --- a/game/renderer_polygon_3d/particle_batch.hpp +++ b/game/renderer_polygon_3d/particle_batch.hpp @@ -7,15 +7,40 @@ #include "glclasses.hpp" -//class VertexAttribute { -// std::string nameInShader; -// Guint attributeIndex; -// Type type; -// modifictaion -// void *dataSource; -//}; - namespace endofthejedi { +#if 0 + class VertexAttribute { + public: + class Data { + public: + enum class Type { + Integer, Float, Float2, Float3, Float4, Matrix3, Matrix4 + }; + + void setDataInteger(int index, int v) + { + } + + Data(Type type, int size) : m_type(type), m_size(size) + { + if (type == + } + + private: + int m_size; + Type m_type; + std::vector m_sourceInteger; + std::vector m_sourceFloat; + }; + + public: + Data data; + std::string variableName; + int divisor; + GLint index; + }; +#endif + class ParticleBatch { public: ParticleBatch(size_t id, size_t numParticles, float particleRadius, float halfAge); @@ -23,28 +48,32 @@ namespace endofthejedi { // deallocate opengl stuff on destroy ~ParticleBatch(); - size_t numParticles() const { return m_numParticles; } - + // set particle data void setParticle(size_t index, const glm::vec3 &p, const glm::vec3 &v, float maxDistance); - void setCenter(const glm::vec3 ¢er); - void setMaxVelocity(float maxVelocity); - + // stuff for setup/rendering usage void setup(Shader *shader); void bind(); void upload(); void render(Shader *shader); + // advance internal state (mostly age) void tick(float dt); - float ageNormalized() const { return m_age / (m_maxNumHalfAges*m_halfAge); } - float age() const { return m_age; } + + // check if the lifetime is over and whether it can be deleted. bool done() const; - size_t id() const { return m_id; } - - + // access attributes + size_t numParticles() const { return m_numParticles; } + float ageNormalized() const { return m_age / (m_maxNumHalfAges*m_halfAge); } + float age() const { return m_age; } + size_t id() const { return m_id; } const glm::vec3 &explosionCenter() const { return m_center; } + // set attributes + void setCenter(const glm::vec3 ¢er); + void setMaxVelocity(float maxVelocity); + private: size_t dataSizeForIndex(size_t index); void *dataSourceForIndex(size_t index); diff --git a/game/renderer_polygon_3d/renderer_polygon_3d.cpp b/game/renderer_polygon_3d/renderer_polygon_3d.cpp index 1caa06c..a43ab2e 100644 --- a/game/renderer_polygon_3d/renderer_polygon_3d.cpp +++ b/game/renderer_polygon_3d/renderer_polygon_3d.cpp @@ -39,7 +39,8 @@ namespace endofthejedi { addModel("../data/mesh/planet_128.stl", &m_planetModel); addModel("../data/mesh/ship_ufo.stl", &m_shipModel); - m_texture = new ImageTexture("../data/img/test.png"); + //m_texture = new ImageTexture("../data/img/test.png"); + m_texture = new ImageTexture("../data/img/stars_nebular.png"); glActiveTexture(GL_TEXTURE0); m_texture->loadPng(); diff --git a/game/state/commands.cpp b/game/state/commands.cpp index dd47870..0b2f709 100644 --- a/game/state/commands.cpp +++ b/game/state/commands.cpp @@ -5,6 +5,8 @@ #include "trace.hpp" #include "util.hpp" +#include "developer_console.hpp" + namespace game { void ShootCommand::apply(Player *player, State *state) const { @@ -91,9 +93,20 @@ namespace game { std::cout << "got developer command: '" << m_payload << "'" << std::endl; - if (m_payload == "reload shader") { - // TODO: really do that ;) - } else if (m_payload == "reload models") { + std::string nextToken; + std::string nextPayload; + + if (util::splitIntoTokenAndRest(m_payload, nextToken, nextPayload)) { + developer::DeveloperConsole::CallbackResult result = + developer::DeveloperConsole::instance().dispatchInput( + nextToken, + nextPayload); + + if (result.okay) { + std::cout<<"[commands] developer callback success: " << result.answer << std::endl; + } else { + std::cout<<"[commands] developer callback failure: " << result.answer << std::endl; + } } } diff --git a/game/state/state.cpp b/game/state/state.cpp index 70debcb..af4a2f7 100644 --- a/game/state/state.cpp +++ b/game/state/state.cpp @@ -22,7 +22,7 @@ #include "util.hpp" namespace game { - void State::init(int numPlanets, bool devMode) + void State::init(int numPlanets) { // clear for (Planet *planet : planets) { @@ -38,7 +38,6 @@ namespace game { m_playerRespawnTime = 2.0; m_defaultEnergy = 10.0; m_maxNumTraces = 10; - m_developerMode = devMode; setPlayingFieldCenter(0, 0); diff --git a/game/state/state.hpp b/game/state/state.hpp index 052fd8b..51a9ab7 100644 --- a/game/state/state.hpp +++ b/game/state/state.hpp @@ -62,7 +62,7 @@ namespace game { // called to setup the state (randomize planets, kill // traces/missiles/ships etc.) - void init(int numPlanets=15, bool devMode=false); + void init(int numPlanets=15); // main method to advance the simulation by the given timestamp in // seconds. diff --git a/game/util.cpp b/game/util.cpp index b1e86e0..edf0263 100644 --- a/game/util.cpp +++ b/game/util.cpp @@ -3,6 +3,8 @@ #include #include +#include + namespace util { float randf_m1_1() { @@ -115,4 +117,19 @@ namespace util { } #endif } + + bool splitIntoTokenAndRest(const std::string &str, std::string &token, std::string &rest) + { + std::istringstream iss(str); + iss >> token; + + if (token.size() == 0) { + return false; + } + + // skip token + next whitespace + rest = str.substr(std::min(str.size(), token.size()+1)); + + return true; + } } diff --git a/game/util.hpp b/game/util.hpp index 1bd7bd3..6ec068b 100644 --- a/game/util.hpp +++ b/game/util.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include #include @@ -14,6 +16,10 @@ namespace util { float deg2rad(float deg); float rad2deg(float rad); + // split on whitespace into first token and the rest. + // return true if whitespace was found or just the token. + bool splitIntoTokenAndRest(const std::string &str, std::string &token, std::string &rest); + /** * Test for intersection in positive direction of a ray. * TODO: support inside?