Refactored the ansi_parser into a class that can be reused between render calls.

main
Zed A. Shaw 3 weeks ago
parent e864e14eab
commit fd8180bc61
  1. 35
      ansi_parser.cpp
  2. 16
      ansi_parser.hpp
  3. 23
      ansi_parser.rl
  4. 10
      render.cpp
  5. 4
      render.hpp
  6. 7
      tests/ansi_parser.cpp

@ -87,26 +87,39 @@ static const int foo_en_main = 19;
#line 84 "ansi_parser.rl" #line 84 "ansi_parser.rl"
bool parse_ansi(std::wstring_view codes, sf::Color default_fg, sf::Color default_bg, WriteCB write) {
ANSIParser::ANSIParser(sf::Color default_fg, sf::Color default_bg) :
$default_fg(default_fg),
$default_bg(default_bg)
{
}
bool ANSIParser::parse(const std::string &screen, WriteCB write) {
std::wstring screen_utf8 = $converter.from_bytes(screen);
return parse(screen_utf8, write);
}
bool ANSIParser::parse(std::wstring_view codes, WriteCB write) {
const wchar_t *start = NULL; const wchar_t *start = NULL;
int cs = 0; int cs = 0;
unsigned int value = 0; unsigned int value = 0;
const wchar_t *p = codes.data(); const wchar_t *p = codes.data();
const wchar_t *pe = p + codes.size(); const wchar_t *pe = p + codes.size();
const wchar_t *eof = pe; const wchar_t *eof = pe;
sf::Color bgcolor(default_bg); sf::Color bgcolor($default_bg);
sf::Color color(default_fg); sf::Color color($default_fg);
sf::Color &target = color; sf::Color &target = color;
#line 94 "ansi_parser.cpp" #line 107 "ansi_parser.cpp"
{ {
cs = foo_start; cs = foo_start;
} }
#line 97 "ansi_parser.rl" #line 110 "ansi_parser.rl"
#line 97 "ansi_parser.cpp" #line 110 "ansi_parser.cpp"
{ {
int _klen; int _klen;
unsigned int _trans; unsigned int _trans;
@ -233,11 +246,11 @@ _match:
break; break;
case 6: case 6:
#line 52 "ansi_parser.rl" #line 52 "ansi_parser.rl"
{ color = default_fg; } { color = $default_fg; }
break; break;
case 7: case 7:
#line 53 "ansi_parser.rl" #line 53 "ansi_parser.rl"
{ bgcolor = default_bg; } { bgcolor = $default_bg; }
break; break;
case 8: case 8:
#line 55 "ansi_parser.rl" #line 55 "ansi_parser.rl"
@ -259,7 +272,7 @@ _match:
#line 59 "ansi_parser.rl" #line 59 "ansi_parser.rl"
{ } { }
break; break;
#line 236 "ansi_parser.cpp" #line 249 "ansi_parser.cpp"
} }
} }
@ -279,7 +292,7 @@ _again:
#line 59 "ansi_parser.rl" #line 59 "ansi_parser.rl"
{ } { }
break; break;
#line 254 "ansi_parser.cpp" #line 267 "ansi_parser.cpp"
} }
} }
} }
@ -287,7 +300,7 @@ _again:
_out: {} _out: {}
} }
#line 98 "ansi_parser.rl" #line 111 "ansi_parser.rl"
return p - pe == 0; return p - pe == 0;
} }

@ -1,7 +1,21 @@
#pragma once #pragma once
#include <string_view> #include <string_view>
#include <SFML/Graphics.hpp> #include <SFML/Graphics.hpp>
#include <codecvt>
typedef std::function<void(sf::Color bgcolor, sf::Color color, wchar_t ch)> WriteCB; typedef std::function<void(sf::Color bgcolor, sf::Color color, wchar_t ch)> WriteCB;
bool parse_ansi(std::wstring_view codes, sf::Color default_fg, sf::Color default_bg, WriteCB write); class ANSIParser {
sf::Color $default_fg;
sf::Color $default_bg;
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> $converter;
public:
ANSIParser(sf::Color default_fg, sf::Color default_bg);
// disable copying
ANSIParser(ANSIParser& ap) = delete;
bool parse(const std::string &screen, WriteCB write);
bool parse(std::wstring_view codes, WriteCB write);
};

@ -49,8 +49,8 @@ using namespace fmt;
write(bgcolor, color, fc); write(bgcolor, color, fc);
} }
action reset_fg { color = default_fg; } action reset_fg { color = $default_fg; }
action reset_bg { bgcolor = default_bg; } action reset_bg { bgcolor = $default_bg; }
action red { target.r = value; } action red { target.r = value; }
action blue { target.g = value; } action blue { target.g = value; }
@ -82,15 +82,28 @@ using namespace fmt;
%% write data; %% write data;
bool parse_ansi(std::wstring_view codes, sf::Color default_fg, sf::Color default_bg, WriteCB write) {
ANSIParser::ANSIParser(sf::Color default_fg, sf::Color default_bg) :
$default_fg(default_fg),
$default_bg(default_bg)
{
}
bool ANSIParser::parse(const std::string &screen, WriteCB write) {
std::wstring screen_utf8 = $converter.from_bytes(screen);
return parse(screen_utf8, write);
}
bool ANSIParser::parse(std::wstring_view codes, WriteCB write) {
const wchar_t *start = NULL; const wchar_t *start = NULL;
int cs = 0; int cs = 0;
unsigned int value = 0; unsigned int value = 0;
const wchar_t *p = codes.data(); const wchar_t *p = codes.data();
const wchar_t *pe = p + codes.size(); const wchar_t *pe = p + codes.size();
const wchar_t *eof = pe; const wchar_t *eof = pe;
sf::Color bgcolor(default_bg); sf::Color bgcolor($default_bg);
sf::Color color(default_fg); sf::Color color($default_fg);
sf::Color &target = color; sf::Color &target = color;
%% write init; %% write init;

@ -30,7 +30,10 @@ SFMLRender::SFMLRender(Canvas &canvas, Screen &map_screen, Screen &screen) :
$line_spacing(0), $line_spacing(0),
$canvas(canvas), $canvas(canvas),
$map_screen(map_screen), $map_screen(map_screen),
$screen(screen) $screen(screen),
$default_fg(color(Value::LIGHT_MID)),
$default_bg(color(Value::BLACK)),
$ansi($default_fg, $default_bg)
{ {
$font.loadFromFile("./assets/text.otf"); $font.loadFromFile("./assets/text.otf");
$ui_text.setFont($font); $ui_text.setFont($font);
@ -80,17 +83,14 @@ void SFMLRender::draw_screen(bool clear, float map_off_x, float map_off_y) {
draw_main_ui(); draw_main_ui();
std::string map_screenout = $map_screen.ToString(); std::string map_screenout = $map_screen.ToString();
std::wstring map_screen_utf8 = $converter.from_bytes(map_screenout);
float y = 0.0f; float y = 0.0f;
float x = GAME_MAP_POS; float x = GAME_MAP_POS;
// make a copy so we don't modify the cached one // make a copy so we don't modify the cached one
auto bg_sprite = get_text_sprite(BG_TILE); auto bg_sprite = get_text_sprite(BG_TILE);
auto bg_bounds = bg_sprite.getLocalBounds(); auto bg_bounds = bg_sprite.getLocalBounds();
sf::Color def_fg(color(Value::MID));
sf::Color def_bg(color(Value::BLACK));
parse_ansi(map_screen_utf8, def_fg, def_bg, [&](sf::Color bg, sf::Color fg, wchar_t tile) { $ansi.parse(map_screenout, [&](sf::Color bg, sf::Color fg, wchar_t tile) {
if(tile == '\n') { if(tile == '\n') {
// don't bother processing newlines, just skip // don't bother processing newlines, just skip
y += $line_spacing; y += $line_spacing;

@ -7,6 +7,7 @@
#include <SFML/Graphics.hpp> #include <SFML/Graphics.hpp>
#include "point.hpp" #include "point.hpp"
#include <codecvt> #include <codecvt>
#include "ansi_parser.hpp"
using ftxui::Canvas, ftxui::Screen; using ftxui::Canvas, ftxui::Screen;
@ -41,6 +42,9 @@ struct SFMLRender {
Screen& $screen; Screen& $screen;
sf::Text $ui_text; sf::Text $ui_text;
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> $converter; std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> $converter;
sf::Color $default_fg;
sf::Color $default_bg;
ANSIParser $ansi;
SFMLRender(Canvas &canvas, Screen &map_screen, Screen &screen); SFMLRender(Canvas &canvas, Screen &map_screen, Screen &screen);

@ -53,14 +53,11 @@ std::string generate_colors() {
TEST_CASE("test out ragel parser", "[gui]") { TEST_CASE("test out ragel parser", "[gui]") {
std::string colors = generate_colors(); std::string colors = generate_colors();
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::wstring colors_utf8 = converter.from_bytes(colors);
sf::Color default_fg(0,0,0); sf::Color default_fg(0,0,0);
sf::Color default_bg(100,100,100); sf::Color default_bg(100,100,100);
ANSIParser parser(default_fg, default_bg);
bool good = parse_ansi(colors_utf8, default_fg, default_bg, [&](sf::Color bgcolor, sf::Color color, wchar_t ch) { bool good = parser.parse(colors, [&](sf::Color bgcolor, sf::Color color, wchar_t ch) {
bool correct_char = ch == '#' || ch == ' ' || ch == '\n' || ch == '\r'; bool correct_char = ch == '#' || ch == ' ' || ch == '\n' || ch == '\r';
// println("FG: {},{},{},{}; BG: {},{},{},{}; ch: {}", // println("FG: {},{},{},{}; BG: {},{},{},{}; ch: {}",
// color.r, color.g, color.b, color.a, // color.r, color.g, color.b, color.a,

Loading…
Cancel
Save