First round of cleanup. dnd_loot.

master
Zed A. Shaw 11 hours ago
parent 689bb150c6
commit f668ff6b7a
  1. 2
      dinkyecs.hpp
  2. 87
      gui/dnd_loot.cpp
  3. 2
      gui/dnd_loot.hpp
  4. 3
      meson.build
  5. 97
      scratchpad/corostate.cpp
  6. 2
      scripts/coverage_report.ps1
  7. 2
      tests/components.cpp
  8. 8
      tests/config.cpp
  9. 4
      tests/config_test.json

@ -62,12 +62,10 @@ namespace DinkyECS
} }
void make_constant(DinkyECS::Entity entity) { void make_constant(DinkyECS::Entity entity) {
fmt::println(">>> Entity {} is now constant", entity);
$constants.try_emplace(entity, true); $constants.try_emplace(entity, true);
} }
void not_constant(DinkyECS::Entity entity) { void not_constant(DinkyECS::Entity entity) {
fmt::println("<<< Entity {} is NOT constant", entity);
$constants.erase(entity); $constants.erase(entity);
} }

@ -29,8 +29,9 @@ namespace gui {
} }
void DNDLoot::START(Event ev) { void DNDLoot::START(Event ev) {
dbc::check(ev == Event::STARTED, "START not given a STARTED event."); using enum Event;
END(Event::CLOSE); dbc::check(ev == STARTED, "START not given a STARTED event.");
END(CLOSE);
} }
void DNDLoot::LOOTING(Event ev, std::any data) { void DNDLoot::LOOTING(Event ev, std::any data) {
@ -38,7 +39,7 @@ namespace gui {
switch(ev) { switch(ev) {
case LOOT_OPEN: case LOOT_OPEN:
END(Event::CLOSE); END(CLOSE);
break; break;
case LOOT_SELECT: case LOOT_SELECT:
$grab_source = start_grab($loot_ui.$gui, data); $grab_source = start_grab($loot_ui.$gui, data);
@ -49,7 +50,7 @@ namespace gui {
if($grab_source) state(DNDState::INV_GRAB); if($grab_source) state(DNDState::INV_GRAB);
break; break;
default: default:
state(DNDState::LOOTING); break; // ignore
} }
} }
@ -58,7 +59,7 @@ namespace gui {
switch(ev) { switch(ev) {
case LOOT_OPEN: case LOOT_OPEN:
END(Event::CLOSE); END(CLOSE);
break; break;
case LOOT_SELECT: case LOOT_SELECT:
commit_move($loot_ui.$gui, $grab_source, data); commit_move($loot_ui.$gui, $grab_source, data);
@ -81,7 +82,7 @@ namespace gui {
switch(ev) { switch(ev) {
case LOOT_OPEN: case LOOT_OPEN:
END(Event::CLOSE); END(CLOSE);
break; break;
case LOOT_SELECT: case LOOT_SELECT:
if(commit_drop($status_ui.$gui, if(commit_drop($status_ui.$gui,
@ -107,12 +108,12 @@ namespace gui {
case AIM_CLICK: { case AIM_CLICK: {
bool worked = throw_on_floor(); bool worked = throw_on_floor();
dbc::check(worked, "Need to fix this, should be able to abort."); dbc::check(worked, "Need to fix this, should be able to abort.");
END(Event::CLOSE); END(CLOSE);
} break; } break;
case INV_SELECT: case INV_SELECT:
// BUG: should I do a bool here and not transition? // BUG: should I do a bool here and not transition?
commit_move($status_ui.$gui, $grab_source, data); commit_move($status_ui.$gui, $grab_source, data);
END(Event::CLOSE); END(CLOSE);
break; break;
default: default:
handle_mouse(ev, $status_ui.$gui); handle_mouse(ev, $status_ui.$gui);
@ -126,13 +127,17 @@ namespace gui {
case INV_SELECT: case INV_SELECT:
if(commit_drop($loot_ui.$gui, $status_ui.$gui, $grab_source, data)) if(commit_drop($loot_ui.$gui, $status_ui.$gui, $grab_source, data))
{ {
END(Event::CLOSE); END(CLOSE);
} }
break; break;
case LOOT_ITEM: case AIM_CLICK:
// BUG: because I put things into fake loot containers it's actually
// hard to put things back. It's probably a System::remove from the
// loot container combined with a System::drop_item
dbc::log("Put it back?");
break; break;
default: default:
handle_mouse(ev, $loot_ui.$gui); handle_mouse(ev, $loot_ui.$gui);
} }
} }
@ -140,30 +145,14 @@ namespace gui {
using enum Event; using enum Event;
switch(ev) { switch(ev) {
case LOOT_ITEM: { case LOOT_ITEM:
// NOTE: if > 1 items, go to LOOT_OPEN instead hold_world_item();
auto gui_id = $loot_ui.$gui.entity("item_0"); state(DNDState::ITEM_PICKUP);
$grab_source = start_grab($loot_ui.$gui, gui_id); break;
case INV_SELECT:
if($grab_source) { hold_inv_item(data);
auto& source = $loot_ui.$gui.get<guecs::GrabSource>(*$grab_source); state(DNDState::INV_PICKUP);
$grab_sprite = source.sprite; break;
// call this once to properly position the sprite
handle_mouse(Event::MOUSE_MOVE, $loot_ui.$gui);
state(DNDState::ITEM_PICKUP);
}
} break;
case INV_SELECT: {
$grab_source = start_grab($status_ui.$gui, data);
if($grab_source) {
auto& source = $status_ui.$gui.get<guecs::GrabSource>(*$grab_source);
$grab_sprite = source.sprite;
state(DNDState::INV_PICKUP);
} else {
dbc::log("inv slot empty");
}
} break;
case LOOT_OPEN: case LOOT_OPEN:
open(); open();
state(DNDState::LOOTING); state(DNDState::LOOTING);
@ -268,14 +257,42 @@ namespace gui {
// Or, maybe save the commit? // Or, maybe save the commit?
} }
void DNDLoot::hold_world_item() {
// NOTE: if > 1 items, go to LOOT_OPEN instead
auto gui_id = $loot_ui.$gui.entity("item_0");
$grab_source = start_grab($loot_ui.$gui, gui_id);
if($grab_source) {
auto& source = $loot_ui.$gui.get<guecs::GrabSource>(*$grab_source);
$grab_sprite = source.sprite;
// call this once to properly position the sprite
handle_mouse(Event::MOUSE_MOVE, $loot_ui.$gui);
}
}
void DNDLoot::hold_inv_item(std::any& data) {
$grab_source = start_grab($status_ui.$gui, data);
if($grab_source) {
auto& source = $status_ui.$gui.get<guecs::GrabSource>(*$grab_source);
$grab_sprite = source.sprite;
} else {
dbc::log("inv slot empty");
}
}
/* /*
* Dropping on the ground is only possible from the * Dropping on the ground is only possible from the
* status_ui for now. * status_ui for now.
*/ */
bool DNDLoot::throw_on_floor() { bool DNDLoot::throw_on_floor() {
dbc::check($grab_source != std::nullopt, "attempt to commit_drop but no grab_source set"); dbc::check($grab_source != std::nullopt, "attempt to commit_drop but no grab_source set");
dbc::check($status_ui.$gui.has<guecs::GrabSource>(*$grab_source),
"StatusUI doesn't actually have that GrabSource in the gui.");
auto& grab = $status_ui.$gui.get<guecs::GrabSource>(*$grab_source); auto& grab = $status_ui.$gui.get<guecs::GrabSource>(*$grab_source);
grab.commit(); grab.commit();
bool result = $status_ui.drop_item(grab.world_entity); bool result = $status_ui.drop_item(grab.world_entity);
clear_grab(); clear_grab();
return result; return result;

@ -52,6 +52,8 @@ namespace gui {
void commit_move(guecs::UI& gui, void commit_move(guecs::UI& gui,
std::optional<guecs::Entity> source_id, std::any data); std::optional<guecs::Entity> source_id, std::any data);
void hold_world_item();
void hold_inv_item(std::any& data);
bool throw_on_floor(); bool throw_on_floor();
void clear_grab(); void clear_grab();

@ -159,6 +159,9 @@ executable('runtests', sources + [
override_options: exe_defaults, override_options: exe_defaults,
dependencies: dependencies + [catch2]) dependencies: dependencies + [catch2])
executable('corostate',
['scratchpad/corostate.cpp'],
dependencies: [fmt])
executable('zedcaster', executable('zedcaster',
sources + [ 'main.cpp' ], sources + [ 'main.cpp' ],

@ -0,0 +1,97 @@
#include <coroutine>
#include <cstdint>
#include <exception>
#include <fmt/core.h>
template<typename T>
struct Generator {
struct promise_type;
using handle_type = std::coroutine_handle<promise_type>;
struct promise_type {
T value_;
std::exception_ptr exception_;
Generator get_return_object() {
return Generator(handle_type::from_promise(*this));
}
std::suspend_always initial_suspend() { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
void unhandled_exception() { exception_ = std::current_exception(); }
template<std::convertible_to<T> From>
std::suspend_always yield_value(From&& from) {
value_ = std::forward<From>(from);
return {};
}
void return_void() {}
};
handle_type h_;
Generator(handle_type h) : h_(h) {}
~Generator() { h_.destroy(); }
explicit operator bool() {
fill();
return !h_.done();
}
T operator()() {
fill();
full_ = false;
return std::move(h_.promise().value_);
}
private:
bool full_ = false;
void fill() {
if(!full_) {
h_();
if(h_.promise().exception_) {
std::rethrow_exception(h_.promise().exception_);
}
full_ = true;
}
}
};
Generator<std::uint64_t>
fib(unsigned n) {
if(n == 0) co_return;
if(n > 94) {
throw std::runtime_error("Too big");
}
if(n == 1) co_return;
co_yield 1;
if(n == 2) co_return;
std::uint64_t a = 0;
std::uint64_t b = 1;
for(unsigned i = 2; i < n; ++i) {
std::uint64_t s = a + b;
co_yield s;
a = b;
b = s;
}
}
int main() {
try {
auto gen = fib(50);
for(int j = 0; gen; ++j) {
fmt::println("fib({})={}", j, gen());
}
} catch(const std::exception& ex) {
fmt::println("Exception: {}", ex.what());
} catch(...) {
fmt::println("Unknown exception");
}
return 0;
}

@ -6,7 +6,7 @@ cp *.cpp,*.hpp,*.rl builddir
rm -recurse -force coverage rm -recurse -force coverage
cp scripts\gcovr_patched_coverage.py .venv\Lib\site-packages\gcovr\coverage.py cp scripts\gcovr_patched_coverage.py .venv\Lib\site-packages\gcovr\coverage.py
gcovr -o coverage/ --html --html-details --html-theme github.dark-blue --gcov-ignore-errors all --gcov-ignore-parse-errors negative_hits.warn_once_per_file -e builddir/subprojects -e builddir -e subprojects -j 10 . gcovr -o coverage/ --html --html-details --html-theme github.dark-blue --gcov-ignore-errors all --gcov-ignore-parse-errors negative_hits.warn_once_per_file -e builddir/subprojects -e builddir -e subprojects -e scratchpad -e tools -j 10 .
rm *.gcov.json.gz rm *.gcov.json.gz

@ -24,6 +24,8 @@ TEST_CASE("confirm component loading works", "[components]") {
fmt::println("TEST COMPONENT: {} from file {}", key, test_data); fmt::println("TEST COMPONENT: {} from file {}", key, test_data);
auto ent = world.entity(); auto ent = world.entity();
components::configure_entity(world, ent, components); components::configure_entity(world, ent, components);
auto tile = components::get<Tile>(components[0]);
REQUIRE(tile.display != L' ');
} }
} }
} }

@ -3,6 +3,7 @@
#include <iostream> #include <iostream>
TEST_CASE("confirm basic config loader ops", "[config]") { TEST_CASE("confirm basic config loader ops", "[config]") {
Config::set_base_dir("./");
Config config("assets/devices.json"); Config config("assets/devices.json");
auto data_list = config.json(); auto data_list = config.json();
auto the_keys = config.keys(); auto the_keys = config.keys();
@ -17,4 +18,11 @@ TEST_CASE("confirm basic config loader ops", "[config]") {
REQUIRE(comp_data.contains("_type")); REQUIRE(comp_data.contains("_type"));
} }
} }
Config indexed("tests/config_test.json");
auto& test_0 = indexed[0];
REQUIRE(test_0["test"] == 0);
auto& test_1 = indexed[1];
REQUIRE(test_1["test"] == 1);
} }

@ -0,0 +1,4 @@
[
{"test": 0},
{"test": 1}
]
Loading…
Cancel
Save