Got rid of AnimView, added Gui

This commit is contained in:
2021-02-07 13:38:29 -05:00
parent 0721d29c72
commit 1ff94e2591
13 changed files with 118 additions and 123 deletions

View File

@@ -78,43 +78,6 @@ const util::XYZ &AnimQueue::get_xyz() const {
return last.xyz_;
}
void AnimView::update_from(const AnimQueue &queue) {
id_ = queue.get_id();
graphic_ = queue.get_graphic();
plane_ = queue.get_plane();
xyz_ = queue.get_xyz();
updated_ = true;
}
AnimView *AnimViewMap::get_one(int64_t id) {
auto iter = find(id);
if (iter == end()) {
return nullptr;
} else {
return &iter->second;
}
}
void AnimViewMap::clear_updated_bits() {
for (auto pair : *this) {
pair.second.updated_ = false;
}
}
void AnimViewMap::delete_non_updated() {
for (auto iter = begin(); iter != end(); ) {
if (iter->second.updated_) {
iter++;
} else {
iter = erase(iter);
}
}
}
void AnimViewMap::update_one(const AnimQueue &queue) {
operator[](queue.get_id()).update_from(queue);
}
LuaDefine(unittests_animqueue, "c") {
// Check initial state.
AnimQueue aq;

View File

@@ -77,7 +77,7 @@ private:
int64_t id_;
int size_limit_;
std::deque<AnimStep> steps_;
public:
public:
AnimQueue();
int64_t get_id() const { return id_; }
void set_id(int64_t id) { id_ = id; }
@@ -100,35 +100,5 @@ public:
void set_size_limit(int n);
};
class AnimView {
friend class AnimViewMap;
private:
int64_t id_;
std::string graphic_;
std::string plane_;
util::XYZ xyz_;
bool updated_; // Used by AnimViewMap.
public:
AnimView() : id_(0), updated_(true) {}
int64_t get_id() const { return id_; }
const std::string &get_graphic() const { return graphic_; }
const std::string &get_plane() const { return plane_; }
const util::XYZ &get_xyz() const { return xyz_; }
void update_from(const AnimQueue &queue);
};
// AnimViewMap: a unordered_map from tangible ID to AnimView. Adds a few
// methods for garbage collection and updating.
//
class AnimViewMap : public std::unordered_map<int64_t, AnimView> {
public:
AnimView *get_one(int64_t id);
void clear_updated_bits();
void delete_non_updated();
void update_one(const AnimQueue &queue);
};
#endif // ANIMQUEUE_HPP

12
luprex/cpp/gui.cpp Normal file
View File

@@ -0,0 +1,12 @@
#include "gui.hpp"
LuaDefineType(Gui);
void Gui::add_menu_item(const std::string &id, const std::string &label) {
GuiElt elt;
elt.type_ = GuiElt::TYPE_MENU_ITEM;
elt.id_ = id;
elt.label_ = label;
elts_.push_back(elt);
}

39
luprex/cpp/gui.hpp Normal file
View File

@@ -0,0 +1,39 @@
#ifndef GUI_HPP
#define GUI_HPP
#include <string>
#include <vector>
#include "luastack.hpp"
class GuiElt {
friend class Gui;
public:
enum Type {
TYPE_MENU_ITEM,
};
private:
Type type_;
std::string id_;
std::string label_;
GuiElt() {}
public:
~GuiElt() {}
Type type() const { return type_; }
const std::string &id() const { return id_; }
const std::string &label() const { return label_; }
};
class Gui {
public:
using EltVec = std::vector<GuiElt>;
private:
EltVec elts_;
public:
const EltVec &elts() const { return elts_; }
void clear() { elts_.clear(); }
void add_menu_item(const std::string &id, const std::string &label);
};
#endif // GUI_HPP

View File

@@ -176,8 +176,11 @@ int PlaneMap::total_cells() const {
return total;
}
PlaneMap::IdVec PlaneMap::scan_radius(const std::string &plane, double x, double y, double radius) const {
PlaneMap::IdVec PlaneMap::scan_radius(const std::string &plane, double x, double y, double radius, int64_t prepend) const {
PlaneMap::IdVec result;
if (prepend != 0) {
result.push_back(prepend);
}
auto piter = planes_.find(plane);
if (piter != planes_.end()) {
const Plane &p = piter->second;
@@ -189,7 +192,9 @@ PlaneMap::IdVec PlaneMap::scan_radius(const std::string &plane, double x, double
if (liter != p.end()) {
for (PlaneItem *client : liter->second) {
if (util::distance_squared(client->x(), client->y(), x, y) <= radsq) {
result.push_back(client->id());
if (client->id() != prepend) {
result.push_back(client->id());
}
}
}
}
@@ -310,13 +315,13 @@ LuaDefine(unittests_planemap, "c") {
pia.set_id(123);
pib.set_id(456);
pib.set_pos("bar", 1100.0, 1000.0, 0.0);
ids = pm.scan_radius("bar", 1000.0, 1000.0, 1.0);
ids = pm.scan_radius("bar", 1000.0, 1000.0, 1.0, 0);
LuaAssert(L, ids.size() == 1);
LuaAssert(L, ids[0] == 123);
ids = pm.scan_radius("bar", 1000.0, 1000.0, 99.9);
ids = pm.scan_radius("bar", 1000.0, 1000.0, 99.9, 0);
LuaAssert(L, ids.size() == 1);
LuaAssert(L, ids[0] == 123);
ids = pm.scan_radius("bar", 1000.0, 1000.0, 100.0);
ids = pm.scan_radius("bar", 1000.0, 1000.0, 100.0, 0);
LuaAssert(L, ids.size() == 2);
LuaAssert(L, ids[0] == 123);
LuaAssert(L, ids[1] == 456);

View File

@@ -120,7 +120,7 @@ public:
PlaneMap();
~PlaneMap();
void track(PlaneItem *item);
IdVec scan_radius(const std::string &plane, double x, double y, double radius) const;
IdVec scan_radius(const std::string &plane, double x, double y, double radius, int64_t prepend) const;
private:
// unit testing stuff.

View File

@@ -8,6 +8,7 @@
#include <iostream>
#include "luastack.hpp"
#include "util.hpp"
#include "gui.hpp"
#include "viewer.hpp"
#include "traceback.hpp"
#include "textgame.hpp"
@@ -81,11 +82,10 @@ void TextGame::do_view_command(const StringVec &cmd) {
std::cerr << "v command (view) takes no arguments" << std::endl;
return;
}
viewer_.update_view_map();
for (auto viewpair : viewer_.get_view_map()) {
int64_t id = viewpair.first;
AnimView &view = viewpair.second;
std::cerr << id << ": " << view.get_graphic() << " " << view.get_xyz() << std::endl;
for (int64_t id : viewer_.get_near()) {
const Tangible *tan = viewer_.tangible_get(id);
const AnimQueue &aq = tan->anim_queue_;
std::cerr << id << ": " << aq.get_graphic() << " " << aq.get_plane() << " " << aq.get_xyz() << std::endl;
}
}
@@ -99,8 +99,13 @@ void TextGame::do_menu_command(const StringVec &cmd) {
std::cerr << "m command (menu) expects a tangible ID or defaults to 1" << std::endl;
return;
}
std::cerr << "Menu command (id " << id << ") not implemented yet." << std::endl;
gui_id_ = id;
viewer_.update_gui(id, &gui_);
int index = 0;
for (const GuiElt &elt : gui_.elts()) {
std::cerr << index << " " << elt.label() << std::endl;
index += 1;
}
}
void TextGame::do_choose_command(const StringVec &cmd) {
@@ -114,11 +119,20 @@ void TextGame::do_choose_command(const StringVec &cmd) {
std::cerr << "Choose command (index " << index << ") not implemented yet." << std::endl;
}
void TextGame::do_quit_command(const StringVec &cmd) {
if (cmd.size() != 1) {
std::cerr << "q command (quit) takes no arguments" << std::endl;
return;
}
exit(0);
}
void TextGame::do_command(const StringVec &words) {
switch (words[0][0]) {
case 'v': do_view_command(words); break;
case 'm': do_menu_command(words); break;
case 'c': do_choose_command(words); break;
case 'q': do_quit_command(words); break;
default:
std::cerr << "Unknown command: " << words[0] << std::endl;
}

View File

@@ -10,13 +10,13 @@ private:
using StringVec = LuaConsole::StringVec;
Viewer viewer_;
LuaConsole console_;
int64_t menu_id_;
std::vector<std::string> menu_;
Gui gui_;
int64_t gui_id_;
void do_view_command(const StringVec &cmd);
void do_menu_command(const StringVec &cmd);
void do_choose_command(const StringVec &cmd);
void do_quit_command(const StringVec &cmd);
void do_lua(const std::string &exp);
void do_command(const StringVec &exp);

View File

@@ -13,15 +13,12 @@ int64_t Viewer::get_player_id() {
return 1;
}
// Get the menu of the specified tangible.
//
std::vector<std::string> Viewer::get_menu(int64_t id) {
std::vector<std::string> result;
result.push_back("north");
result.push_back("south");
result.push_back("east");
result.push_back("west");
result.push_back("build");
result.push_back("destroy");
return result;
void Viewer::update_gui(int64_t id, Gui *gui) {
gui->add_menu_item("north", "north");
gui->add_menu_item("south", "south");
gui->add_menu_item("east", "east");
gui->add_menu_item("west", "west");
gui->add_menu_item("build", "build");
gui->add_menu_item("destroy", "destroy");
}

View File

@@ -3,6 +3,7 @@
#include "world.hpp"
#include "animqueue.hpp"
#include "gui.hpp"
#include <vector>
#include <string>
#include <memory>
@@ -10,7 +11,6 @@
class Viewer {
private:
std::unique_ptr<World> world_;
AnimViewMap view_map_;
public:
Viewer();
@@ -24,17 +24,21 @@ public:
//
int64_t get_player_id();
// Update the view map.
// Get the list of tangibles near the player.
//
void update_view_map() { world_->update_view_map(&view_map_, 1, 100); }
std::vector<int64_t> get_near() { return world_->get_near(1, 100); }
// Get the specified tangible.
//
const Tangible *tangible_get(int64_t id) { return world_->tangible_get(id); }
// Get the view map.
// Update the GUI for the specified sprite.
//
AnimViewMap &get_view_map() { return view_map_; }
// Get the menu of the specified tangible.
// The gui passed in can be either a newly-created empty GUI,
// which will be populated, or a GUI object retained from
// the previous frame, which will be updated.
//
std::vector<std::string> get_menu(int64_t id);
void update_gui(int64_t id, Gui *g);
};
#endif // VIEWER_HPP

View File

@@ -76,23 +76,14 @@ Tangible *World::tangible_get(int64_t id) {
}
}
void World::update_view_map(AnimViewMap *vm, int64_t player_id, float radius) {
vm->clear_updated_bits();
// Update the player's AnimView first.
vm->update_one(tangible_get(player_id)->anim_queue_);
const AnimView *player_view = vm->get_one(player_id);
std::vector<int64_t> World::get_near(int64_t player_id, float radius) {
Tangible *player = tangible_get(player_id);
// Find out where's the center of the world.
std::string plane = player_view->get_plane();
util::XYZ xyz = player_view->get_xyz();
// Update AnimViews for every tangible near the player.
for (int64_t id : plane_map_.scan_radius(plane, xyz.x, xyz.y, 100.0)) {
vm->update_one(tangible_get(id)->anim_queue_);
}
vm->delete_non_updated();
std::string plane = player->anim_queue_.get_plane();
util::XYZ xyz = player->anim_queue_.get_xyz();
return plane_map_.scan_radius(plane, xyz.x, xyz.y, radius, player_id);
}
Tangible *World::tangible_make(lua_State *L, int64_t id, bool pushdb) {

View File

@@ -82,12 +82,11 @@ public:
//
lua_State *get_lua_state() { return lua_state_; }
// update_view_map
// get_near
//
// Update the view map with information about all the tangibles near
// the specified player.
// Get a list of the tangibles that are near the player.
//
void update_view_map(AnimViewMap *vm, int64_t player_id, float radius);
std::vector<int64_t> get_near(int64_t player_id, float radius);
// Make a tangible.
//