Files
integration/luprex/core/cpp/textgame.cpp

137 lines
4.2 KiB
C++

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <vector>
#include <string>
#include "luastack.hpp"
#include "util.hpp"
#include "gui.hpp"
#include "invocation.hpp"
#include "world.hpp"
#include "traceback.hpp"
#include "textgame.hpp"
#include "luaconsole.hpp"
#include "pprint.hpp"
#include "printbuffer.hpp"
#include <memory>
#include <algorithm>
class TextGame : public DrivenEngine {
private:
using StringVec = LuaConsole::StringVec;
UniqueWorld world_;
LuaConsole console_;
PrintChanneler print_channeler_;
Gui gui_;
int64_t actor_id_;
void do_lua_command(const StringVec &words) {
world_->invoke(Invocation(Invocation::KIND_LUA, actor_id_, actor_id_, words[1]));
}
void do_syntax_command(const StringVec &words) {
stdostream() << "Syntax Error: " << words[1] << std::endl;
}
void do_view_command(const StringVec &cmd) {
stdostream() << world_->tangibles_near_debug_string(actor_id_, 100);
}
void do_menu_command(const StringVec &cmd) {
int64_t place = util::strtoint(cmd[1], actor_id_);
world_->update_gui(actor_id_, place, &gui_);
stdostream() << gui_.menu_debug_string();
}
void do_choose_command(const StringVec &cmd) {
std::string action = gui_.get_action(util::strtoint(cmd[1], -1));
if (action == "") {
stdostream() << "Invalid menu item #" << std::endl;
return;
}
Invocation inv(Invocation::KIND_PLAN, actor_id_, gui_.place(), action);
stdostream() << "Invoking: " << inv.debug_string() << std::endl;
world_->invoke(inv);
}
void do_snapshot_command(const StringVec &cmd) {
world_->snapshot();
}
void do_rollback_command(const StringVec &cmd) {
world_->rollback();
}
void do_tick_command(const StringVec &cmd) {
world_->run_scheduled_threads(util::strtoint(cmd[1], -1));
}
void do_quit_command(const StringVec &cmd) {
actor_id_ = 0;
}
void do_command(const StringVec &words) {
if (words.empty()) return;
else if (words[0] == "lua") do_lua_command(words);
else if (words[0] == "syntax") do_syntax_command(words);
else if (words[0] == "view") do_view_command(words);
else if (words[0] == "menu") do_menu_command(words);
else if (words[0] == "quit") do_quit_command(words);
else if (words[0] == "snap") do_snapshot_command(words);
else if (words[0] == "roll") do_rollback_command(words);
else if (words[0] == "tick") do_tick_command(words);
else if (words[0] == "choose") do_choose_command(words);
else {
stdostream() << "Unsupported command: " << words[0] << std::endl;
}
}
void check_redirects() {
World::Redirects redir = world_->fetch_redirects();
for (const auto &p : redir) {
if (p.first == actor_id_) {
actor_id_ = p.second;
stdostream() << "Login actor ID: " << actor_id_ << std::endl;
gui_.clear(0);
}
}
}
void event_init(int argc, char *argv[])
{
world_.reset(new World(util::WORLD_TYPE_STANDALONE));
world_->update_source(get_lua_source());
world_->run_unittests();
actor_id_ = world_->create_login_actor();
stdostream() << "Login actor ID: " << actor_id_ << std::endl;
get_stdio_channel()->set_prompt(console_.get_prompt());
}
void event_update()
{
world_->update_source(get_lua_source());
while (true) {
std::string line = get_stdio_channel()->in()->readline();
if (line == "") break;
console_.add(line);
get_stdio_channel()->set_prompt(console_.get_prompt());
do_command(console_.get_command());
if (print_channeler_.channel(world_->get_printbuffer(actor_id_), stdostream())) {
world_->invoke(print_channeler_.invocation(actor_id_));
}
check_redirects();
if (actor_id_ == 0) {
stop_driver();
break;
}
}
}
};
UniqueDrivenEngine make_TextGame() {
return UniqueDrivenEngine(new TextGame);
}