sdl_runtime_compiler git · main
SDL3 game for running and compiling code at runtime
C++ 72.3% C 26.2%git clone https://git.christianimmanuel.de/sdl-graphics/sdl_runtime_compiler.gitwget https://git.christianimmanuel.de/sdl-graphics/sdl_runtime_compiler/archive/sdl_runtime_compiler.tar.gzAdd Glyph cash for infowall With Claude
src/levels/director.cpp | 39 ++++++++++++++++++++-------------- src/levels/director.hpp | 6 +++--- src/states/game_state.cpp | 14 +++++++------ src/states/game_state.hpp | 5 +++-- src/text/handler.cpp | 7 +++++++ src/text/handler.hpp | 5 ++++- src/text/mesh.cpp | 4 +++- src/wall/wall.cpp | 53 ++++++++++++++++++++++++++++++++++------------- src/wall/wall.hpp | 2 +- 9 files changed, 92 insertions(+), 43 deletions(-) diff --git a/src/levels/director.cpp b/src/levels/director.cpp index 4e90f73..c83c65c 100644 --- a/src/levels/director.cpp +++ b/src/levels/director.cpp @@ -144,31 +144,40 @@ Director::teardown_Scene(GameContext& ctx) } -void -Director::show_Details(GameContext& ctx) const +void Director::show_Details(GameContext& ctx) const { if (!ctx.info_wall) return; Text::Handler& info = *ctx.info_wall; - if (_runner->is_Complete()) { info.clear(); return; } + if (_runner->is_Complete()) { info.clear(); _detail_built_for = nullptr; return; } const Level::Step* step = &_runner->get_Current(); - const size_t tag = std::hash<const void*>{}(step) | 1; - if (info.view_Is(tag)) return; - - info.clear(); - const Scene::Data* key = &step->scene; - if (key != _detail_key) { + if (_detail_built_for != step) { + _detail_tokens.clear(); const std::string& details = step->details; - _detail_lines = details.empty() ? DynArray<std::string>{} - : Text::wrap_String(details, 92); - _detail_key = key; + DynArray<std::string> lines = + details.empty() ? DynArray<std::string>{} : Text::wrap_String(details, 92); + + float y = World::get_FloorY<float>() + 1.0f; + const Wall::Transform tf = Wall::get_Transform(Wall::Role::Info, World::get_BoxScale()); + for (const std::string& line : lines) { + if (line.empty()) { y += ConfigWall::text_line_spacing; continue; } + Text::TokenPtr t = Text::make_Token(line, Text::Token::depth_wall, 0.003f, + tf.position, ConfigColor::white); + t->yaw = tf.yaw; + t->pos = tf.position; + t->pos.y = y; + t->set_ColorSource(Text::ColorSource::Static); + t->set_Color(ConfigColor::white); + _detail_tokens.push_back(std::move(t)); + y += ConfigWall::text_line_spacing; + } + _detail_built_for = step; } - for (const std::string& line : _detail_lines) - if (!line.empty()) info.append_Line(line); - info.set_View(tag); + info.clear(); + info.set_Borrowed(&_detail_tokens); } diff --git a/src/levels/director.hpp b/src/levels/director.hpp index ad883f3..5ae42ee 100644 --- a/src/levels/director.hpp +++ b/src/levels/director.hpp @@ -58,9 +58,9 @@ class Director StepLedger _ledger; DynArray<StepPlate> _step_plates; DynArray<GameObject*> _step_scenery; - mutable const Level::Step* _detail_shown_for { nullptr }; - mutable const Scene::Data* _detail_key { nullptr }; - mutable DynArray<std::string> _detail_lines; + + mutable const Level::Step* _detail_built_for { nullptr }; + mutable DynArray<Text::TokenPtr> _detail_tokens; void spawn_Grants (GameContext& ctx); void setup_Scene (GameContext& ctx, const Scene::Data& scene); diff --git a/src/states/game_state.cpp b/src/states/game_state.cpp index 96482cc..9b0c08b 100644 --- a/src/states/game_state.cpp +++ b/src/states/game_state.cpp @@ -244,7 +244,7 @@ GameState::on_DropLast() if (!word) return; revert_ToSingle(word.get()); - infowall_Clear(); + //infowall_Clear(); word->body.mode = PhysicsMode::Dynamic; word->body.vel = { _ctx.camera->fwd.x * 1.5, 0.8, _ctx.camera->fwd.z * 1.5 }; @@ -254,7 +254,6 @@ GameState::on_DropLast() _anims_drop.push_back(std::move(drop)); if (!_carried.empty()) { - lex_CarriedLine(_carried); Wall::show_TokenInfo(_info, _carried.last->word->text); } else _level_director->show_Details(_ctx); @@ -272,7 +271,7 @@ GameState::on_ShootOne() if (!word) return false; revert_ToSingle(word.get()); - infowall_Clear(); + //infowall_Clear(); _freelook_sys->state.active = false; _freelook_sys->state.lerping = false; @@ -287,7 +286,6 @@ GameState::on_ShootOne() if (!_carried.empty() && _carried.last && _carried.last->word) { Wall::show_TokenInfo(_info, _carried.last->word->text); - lex_CarriedLine(_carried); } else _level_director->show_Details(_ctx); @@ -301,7 +299,7 @@ GameState::on_ShootAll() { if (_carried.empty()) return; - infowall_Clear(); + //infowall_Clear(); _freelook_sys->state.active = false; _freelook_sys->state.lerping = false; @@ -680,7 +678,11 @@ GameState::update(double dt, const GlRenderer* gl) carriedline_Update(); _word_anim_sys->update(_anims_add, _anims_drop, _carried, _ctx.words, dt); - lex_CarriedLine(_carried); + if (_carried.size != _carried_last_size) { + if (_carried.size > 0) + lex_CarriedLine(_carried); + _carried_last_size = _carried.size; + } _pult_sys-> update(dt, *_ctx.camera); _plate_sys-> update(dt, *_ctx.player, _level_director->get_StepPlates()); diff --git a/src/states/game_state.hpp b/src/states/game_state.hpp index 1edad80..318d00d 100644 --- a/src/states/game_state.hpp +++ b/src/states/game_state.hpp @@ -55,8 +55,9 @@ class GameState : public IState cpputils::unique_ptr<WordAiSystem> _word_ai_sys; - double _pick_cooldown { 0.0 }; - double _shoot_cooldown { 0.0 }; + size_t _carried_last_size { 0 }; + double _pick_cooldown { 0.0 }; + double _shoot_cooldown { 0.0 }; std::string _typing_last; diff --git a/src/text/handler.cpp b/src/text/handler.cpp index 9ee98e3..33fb39a 100644 --- a/src/text/handler.cpp +++ b/src/text/handler.cpp @@ -110,6 +110,8 @@ void Handler::clear() _label_off .clear(); _label_text.clear(); _view_tag = 0; + _borrowed = nullptr; _view_tag = 0; + mark_Dirty(); } @@ -144,6 +146,7 @@ Handler::set_Lines(const DynArray<std::string>& lines) void Handler::append_Line(const std::string& text) { + //SPIKE("append_Line.detail"); for (Line& l : _lines) { l.y += _line_height; for (TokenPtr& t : l.tokens) if (t) t->pos.y += _line_height; @@ -160,6 +163,7 @@ Handler::append_Line(const std::string& text) ln.tokens.push_back(std::move(t)); _lines.push_back(std::move(ln)); + mark_Dirty(); } @@ -864,6 +868,9 @@ Handler::render(GlRenderer& gl, const Camera& cam, const Light& light) const if (l.num_right) l.num_right->draw(gl, cam, light); } } + if (_borrowed) + for (const TokenPtr& t : *_borrowed) + if (t) t->draw(gl, cam, light); } diff --git a/src/text/handler.hpp b/src/text/handler.hpp index 7658791..58697be 100644 --- a/src/text/handler.hpp +++ b/src/text/handler.hpp @@ -116,6 +116,8 @@ public: void kick (size_t word_index, const Vec3& projectile_vel, const Vec3& normal); bool view_Is (size_t tag) const { return tag != 0 && tag == _view_tag; } void set_View (size_t tag) { _view_tag = tag; } + void set_Borrowed (const DynArray<TokenPtr>* borrowed) { _borrowed = borrowed; } + void clear_Borrowed() { _borrowed = nullptr; } bool is_Empty () const { return _lines.empty() || _lines[0].tokens.empty(); } const DynArray<TokenPtr>& get_Words () const; @@ -136,7 +138,8 @@ private: double _append_y { 0.0 }; SDL_FColor _append_color { 0.45f, 0.45f, 0.45f, 1.0f }; - DynArray<std::string> _status; + DynArray<std::string> _status; + const DynArray<TokenPtr>* _borrowed { nullptr }; size_t _view_tag { 0 }; // identity of currently-materialised info-wall content; 0 = none diff --git a/src/text/mesh.cpp b/src/text/mesh.cpp index 0a09299..5dfb2b6 100644 --- a/src/text/mesh.cpp +++ b/src/text/mesh.cpp @@ -328,6 +328,8 @@ acquire_Glyph(FT_Face face, uint32_t ch, float scale) GlyphKey key{ ch, (int)SDL_lround((double)scale * 1e7) }; auto it = g_glyphs.find(key); if (it != g_glyphs.end()) return &it->second; + // SDL_Log("GLYPH MISS '%c' scale_q=%d (cache=%zu)", (char)ch, key.scale_q, g_glyphs.size()); + GlyphMesh gm; FT_UInt gi = FT_Get_Char_Index(face, (FT_ULong)ch); @@ -359,7 +361,7 @@ bool TextMesh::build(const std::string& font_path, const std::string& text, int size, float /*depth*/, float scale) { - // SPIKE("mesh.build"); + SPIKE("mesh.build"); verts.clear(); tris.clear(); is_front.clear(); vertex_normals.clear(); FT_Face face = acquire_Face(font_path, size); diff --git a/src/wall/wall.cpp b/src/wall/wall.cpp index e7b0696..d26c0d0 100644 --- a/src/wall/wall.cpp +++ b/src/wall/wall.cpp @@ -1,6 +1,9 @@ +#include <unordered_map> + #include "text/token.hpp" #include "entities/world.hpp" #include "text/handler.hpp" +#include "text/text.hpp" #include "wall.hpp" namespace Wall @@ -107,25 +110,47 @@ namespace Wall } + static std::unordered_map<std::string, DynArray<Text::TokenPtr>> g_info_cache; + void show_TokenInfo(::Text::Handler& info, const std::string& token_text) { - const size_t tag = std::hash<std::string>{}(token_text) | 1; - if (info.view_Is(tag)) return; + auto it = g_info_cache.find(token_text); + if (it == g_info_cache.end()) { + Text::Token::Type tt = Text::CppHighlight::classify_Word(token_text); + Text::Token::Description d = Text::Token::get_Description(token_text, tt); + + const std::string line1 = token_text + " [" + Text::Token::get_TypeName(tt) + "]"; + + DynArray<std::string> lines; + lines.push_back(line1); + for (const std::string& w : Text::wrap_String(d.short_desc, 92)) + if (!w.empty()) lines.push_back(w); + for (const std::string& w : Text::wrap_String(d.long_desc, 92)) + if (!w.empty()) lines.push_back(w); + + const Wall::Transform tf = + Wall::get_Transform(Wall::Role::Info, World::get_BoxScale()); + float y = World::get_FloorY<float>() + 1.0f; + + DynArray<Text::TokenPtr> toks; + for (const std::string& line : lines) { + Text::TokenPtr t = Text::make_Token(line, Text::Token::depth_wall, 0.003f, + tf.position, ConfigColor::white); + t->yaw = tf.yaw; + t->pos = tf.position; + t->pos.y = y; + t->set_ColorSource(Text::ColorSource::Static); + t->set_Color(ConfigColor::white); + toks.push_back(std::move(t)); + y += ConfigWall::text_line_spacing; + } + + it = g_info_cache.emplace(token_text, std::move(toks)).first; + } info.clear(); - - Text::Token::Type tt = Text::CppHighlight::classify_Word(token_text); - Text::Token::Description d = Text::Token::get_Description(token_text, tt); - - const std::string line1 = token_text + " [" + Text::Token::get_TypeName(tt) + "]"; - const std::string line2 = d.short_desc; - const std::string line3 = d.long_desc; - - for (const std::string& line : { line1, line2, line3 }) - if (!line.empty()) info.append_Line(line); - - info.set_View(tag); + info.set_Borrowed(&it->second); } diff --git a/src/wall/wall.hpp b/src/wall/wall.hpp index 0d22e68..4ca0c64 100644 --- a/src/wall/wall.hpp +++ b/src/wall/wall.hpp @@ -26,7 +26,7 @@ namespace Wall Vec3 inward_Normal (Wall::Position pos); Drop attach_ToNearestWall(Text::TokenPtr src); - void show_TokenInfo (::Text::Handler& info, const std::string& token_text); + void show_TokenInfo (Text::Handler& info, const std::string& token_text); float tilt_TwardEye (const Vec3& text_pos, const Vec3& eye_pos); struct Transform