Now have more test for the base functionality but need to push render tests and find a way to test the GUI. I've also brought in sol2 for lua integration but not sure what to do with it.

main
Zed A. Shaw 11 months ago
parent d0d62836e3
commit e86d474c7c
  1. 19
      meson.build
  2. 2
      panel.cpp
  3. 2
      panel.hpp
  4. 17
      scratchpad/luatest.cpp
  5. 1
      status.txt
  6. 2
      systems.cpp
  7. 3
      tests/ansi_parser.cpp
  8. 2
      tests/collider.cpp
  9. 6
      tests/map.cpp
  10. 75
      tests/panel.cpp
  11. 38
      tests/render.cpp
  12. 4
      tests/save.cpp
  13. 14
      wraps/lua.wrap
  14. 11
      wraps/sol2.wrap

@ -8,10 +8,15 @@ ftxui_screen = dependency('ftxui-screen')
ftxui_dom = dependency('ftxui-dom') ftxui_dom = dependency('ftxui-dom')
ftxui_component = dependency('ftxui-component') ftxui_component = dependency('ftxui-component')
sfml = dependency('sfml') sfml = dependency('sfml')
lua = dependency('lua')
sol2 = dependency('sol2')
dependencies = [catch2, fmt, dependencies = [
ftxui_screen, ftxui_dom, ftxui_component, catch2, fmt,
json, sfml] ftxui_screen, ftxui_dom,
ftxui_component, json,
sfml, lua, sol2
]
runtests = executable('runtests', [ runtests = executable('runtests', [
'dbc.cpp', 'dbc.cpp',
@ -24,6 +29,7 @@ runtests = executable('runtests', [
'config.cpp', 'config.cpp',
'save.cpp', 'save.cpp',
'panel.cpp', 'panel.cpp',
'render.cpp',
'tests/fsm.cpp', 'tests/fsm.cpp',
'tests/dbc.cpp', 'tests/dbc.cpp',
'tests/map.cpp', 'tests/map.cpp',
@ -34,6 +40,8 @@ runtests = executable('runtests', [
'tests/ansi_parser.cpp', 'tests/ansi_parser.cpp',
'tests/config.cpp', 'tests/config.cpp',
'tests/save.cpp', 'tests/save.cpp',
'tests/render.cpp',
'tests/panel.cpp',
], ],
dependencies: dependencies) dependencies: dependencies)
@ -64,4 +72,9 @@ img2ansi = executable('img2ansi', [
], ],
dependencies: dependencies) dependencies: dependencies)
luatest = executable('luatest', [
'scratchpad/luatest.cpp'
],
dependencies: dependencies)
test('tests', runtests) test('tests', runtests)

@ -1,4 +1,5 @@
#include "panel.hpp" #include "panel.hpp"
#include "dbc.hpp"
void Panel::resize(int w, int h) { void Panel::resize(int w, int h) {
$dirty = true; $dirty = true;
@ -13,6 +14,7 @@ void Panel::set_renderer(Component renderer) {
} }
void Panel::add(Component child) { void Panel::add(Component child) {
dbc::pre("must set_renderer first", $component != nullptr);
$dirty = true; $dirty = true;
$component->Add(child); $component->Add(child);
} }

@ -29,7 +29,7 @@ struct Panel {
int border_px = UI_PANEL_BORDER_PX; int border_px = UI_PANEL_BORDER_PX;
bool $dirty = true; bool $dirty = true;
Component $component; Component $component = nullptr;
Screen $screen; Screen $screen;
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> $converter; std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> $converter;
std::wstring $screenout; std::wstring $screenout;

@ -0,0 +1,17 @@
#define SOL_ALL_SAFETIES_ON 1
#include <sol/sol.hpp>
#include <iostream>
int main(int, char*[]) {
std::cout << "=== opening a state ===" << std::endl;
sol::state lua;
// open some common libraries
lua.open_libraries(sol::lib::base, sol::lib::package);
lua.script("print('bark bark bark!')");
std::cout << std::endl;
return 0;
}

@ -5,6 +5,7 @@ TODAY'S GOAL:
* Better tests and more coverage. * Better tests and more coverage.
* Clean up and document as much code as possible. * Clean up and document as much code as possible.
* Doxygen? Other docs tool? * Doxygen? Other docs tool?
* Add a method to render.cpp that sets terminal true color.
TODO: TODO:
* I can do headless windows in renderer for testing. * I can do headless windows in renderer for testing.

@ -149,7 +149,7 @@ void System::collision(DinkyECS::World &world, Player &player) {
} }
void System::draw_entities(DinkyECS::World &world, Map &game_map, ftxui::Canvas &canvas, const Point &cam_orig, size_t view_x, size_t view_y) { void System::draw_entities(DinkyECS::World &world, Map &game_map, ftxui::Canvas &canvas, const Point &cam_orig, size_t view_x, size_t view_y) {
auto &lighting = game_map.lighting(); const auto &lighting = game_map.lighting();
world.query<Position, Tile>([&](const auto &ent, auto &pos, auto &tile) { world.query<Position, Tile>([&](const auto &ent, auto &pos, auto &tile) {
if(pos.location.x >= cam_orig.x && pos.location.x <= cam_orig.x + view_x if(pos.location.x >= cam_orig.x && pos.location.x <= cam_orig.x + view_x

@ -60,9 +60,6 @@ TEST_CASE("test out ragel parser", "[gui]") {
std::string colors = generate_colors(); std::string colors = generate_colors();
std::wstring colors_utf = $converter.from_bytes(colors); std::wstring colors_utf = $converter.from_bytes(colors);
std::cout << colors;
bool good = ansi.parse(colors_utf, bool good = ansi.parse(colors_utf,
[&](sf::Color color, sf::Color bgcolor){ [&](sf::Color color, sf::Color bgcolor){
// ignore color // ignore color

@ -58,6 +58,8 @@ TEST_CASE("confirm basic collision operations", "[collision]") {
REQUIRE(collider.occupied({12,12})); REQUIRE(collider.occupied({12,12}));
REQUIRE(collider.occupied({21,21})); REQUIRE(collider.occupied({21,21}));
REQUIRE(!collider.occupied({1,10})); REQUIRE(!collider.occupied({1,10}));
REQUIRE(collider.get({12,12}) == player);
} }

@ -68,6 +68,12 @@ TEST_CASE("lighting test", "[map]") {
map.clear_light_target(light1); map.clear_light_target(light1);
map.clear_light_target(light2); map.clear_light_target(light2);
const auto &lighting = map.lighting();
// confirm light is set at least at and around the two points
REQUIRE(lighting[light1.y][light1.x] == lighting::LEVELS[source1.strength]);
REQUIRE(lighting[light2.y][light2.x] == lighting::LEVELS[source2.strength]);
} }
TEST_CASE("camera control", "[map]") { TEST_CASE("camera control", "[map]") {

@ -0,0 +1,75 @@
#include <catch2/catch_test_macros.hpp>
#include <fmt/core.h>
#include <ftxui/screen/terminal.hpp> // for ColorSupport, Color, Palette16, Palette256, TrueColor
#include <ftxui/dom/elements.hpp> // for hflow, paragraph, separator, hbox, vbox, filler, operator|, border, Element
#include "panel.hpp"
#include "ansi_parser.hpp"
using namespace ftxui;
using namespace fmt;
using std::string;
void test_ansi_parsing(Panel &panel) {
sf::Color default_fg(0,0,0);
sf::Color default_bg(100,100,100);
// this sets the Truecolor so need to do it first
ANSIParser ansi(default_fg, default_bg);
bool good = ansi.parse(panel.to_string(),
[&](sf::Color color, sf::Color bgcolor){
// ignore color
},
[&](wchar_t ch) {
// ignore char
});
REQUIRE(good == true);
}
TEST_CASE("can render a simple text panel", "[panel]") {
ftxui::Terminal::SetColorSupport(ftxui::Terminal::Color::TrueColor);
Panel text_panel(0, 0, 20, 5);
bool show_modal = false;
auto buttons = Container::Horizontal({
Button("OK", [&]{ show_modal = false; }),
Button("CANCEL", [&]{ show_modal = false; }),
});
auto text_box = Renderer([buttons]{
return hbox({
hflow(
vbox(text("I AM TEXT")),
buttons->Render()
)});
});
text_panel.set_renderer(text_box);
text_panel.add(buttons);
text_panel.resize(10,10);
text_panel.render();
test_ansi_parsing(text_panel);
const Screen &screen = text_panel.screen();
REQUIRE(screen.dimx() == 10);
REQUIRE(screen.dimx() == 10);
}
TEST_CASE("can render a simple grid panel", "[panel]") {
Terminal::SetColorSupport(Terminal::Color::TrueColor);
Panel grid_panel(20, 20, 20, 5, true);
auto text_box = Renderer([]{
return hbox({
hflow(vbox(text("I AM TEXT")))});
});
grid_panel.set_renderer(text_box);
grid_panel.resize(10,10);
grid_panel.render();
test_ansi_parsing(grid_panel);
}

@ -0,0 +1,38 @@
#include <catch2/catch_test_macros.hpp>
#include <fmt/core.h>
#include "render.hpp"
#include "panel.hpp"
using namespace ftxui;
using namespace fmt;
using std::string;
void run_renderer(SFMLRender &renderer, Panel &panel) {
panel.render();
renderer.display();
REQUIRE(renderer.is_open() == true);
renderer.clear();
renderer.draw(panel);
}
TEST_CASE("can render a text or grid panel", "[render]") {
SFMLRender renderer;
Panel panel(0, 0, 20, 5);
Panel grid(200, 200, 20, 5, true);
auto text_box = Renderer([]{
return hbox({
hflow(
vbox(text("I AM TEXT"))
)});
});
panel.set_renderer(text_box);
grid.set_renderer(text_box);
run_renderer(renderer, panel);
run_renderer(renderer, grid);
renderer.close();
}

@ -66,6 +66,7 @@ TEST_CASE("basic save a world", "[save]") {
world.set<Motion>(player.entity, {0, 0}); world.set<Motion>(player.entity, {0, 0});
world.set<Combat>(player.entity, {100, 10}); world.set<Combat>(player.entity, {100, 10});
world.set<Tile>(player.entity, {"@"}); world.set<Tile>(player.entity, {"@"});
world.set<Inventory>(player.entity, {102});
save::to_file("./savetest.world", world, map); save::to_file("./savetest.world", world, map);
@ -95,4 +96,7 @@ TEST_CASE("basic save a world", "[save]") {
REQUIRE(map.height() == in_map.height()); REQUIRE(map.height() == in_map.height());
REQUIRE(map.$walls == in_map.$walls); REQUIRE(map.$walls == in_map.$walls);
REQUIRE(map.$input_map == in_map.$input_map); REQUIRE(map.$input_map == in_map.$input_map);
Inventory &inv = world.get<Inventory>(player.entity);
REQUIRE(inv.gold == 102);
} }

@ -0,0 +1,14 @@
[wrap-file]
directory = lua-5.4.6
source_url = https://www.lua.org/ftp/lua-5.4.6.tar.gz
source_filename = lua-5.4.6.tar.gz
source_hash = 7d5ea1b9cb6aa0b59ca3dde1c6adcb57ef83a1ba8e5432c0ecd06bf439b3ad88
patch_filename = lua_5.4.6-5_patch.zip
patch_url = https://wrapdb.mesonbuild.com/v2/lua_5.4.6-5/get_patch
patch_hash = 755ec591b6b4739650ba6bb11b4feca2d221ab7f80f024dd625f50c8932ad76f
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/lua_5.4.6-5/lua-5.4.6.tar.gz
wrapdb_version = 5.4.6-5
[provide]
lua-5.4 = lua_dep
lua = lua_dep

@ -0,0 +1,11 @@
[wrap-git]
url = https://github.com/ThePhD/sol2.git
revision = v3.3.1
depth = 1
method = meson
# patch_filename =
# patch_hash =
[provide]
sol2 = sol2_dep