Some output now going through PrintBuffer

This commit is contained in:
2021-10-21 13:15:04 -04:00
parent 458497956d
commit 1a25fed15f
9 changed files with 139 additions and 46 deletions

View File

@@ -4,7 +4,7 @@
#include "animqueue.hpp"
#include "gui.hpp"
#include "traceback.hpp"
#include "print.hpp"
#include "pprint.hpp"
#include <iostream>
void World::store_global_pointer(lua_State *L, World *v) {
@@ -49,7 +49,7 @@ World::World(util::WorldType wt) {
Gui::store_global_pointer(state(), nullptr);
// Clear the lthread state.
set_lthread_state(0, 0, false);
clear_lthread_state();
// Set the tabletype of the registry.
LS.settabletype(LuaRegistry, LUA_TT_REGISTRY);
@@ -262,6 +262,7 @@ int64_t World::create_login_actor() {
LS.rawset(mt, "__index", classtab);
LS.result();
tan->configure_id_pool_for_actor();
tan->print_buffer_.reset(new PrintBuffer(world_type_));
assert(stack_is_clear());
return tan->id();
}
@@ -305,9 +306,9 @@ void World::update_gui(int64_t actor_id, int64_t place_id, Gui *gui) {
lua_pushvalue(L, actor.index());
lua_pushvalue(L, place.index());
Gui::store_global_pointer(L, gui);
set_lthread_state(actor_id, place_id, false);
open_lthread_state(actor_id, place_id, false, false);
int status = traceback_pcall(L, 2, 0);
set_lthread_state(0, 0, false);
close_lthread_state();
Gui::store_global_pointer(L, nullptr);
if (status != 0) {
gui->clear();
@@ -372,25 +373,27 @@ void World::invoke_lua(int64_t actor_id, int64_t place_id, const std::string &ac
// Call the closure.
int top = lua_gettop(L);
lua_pushvalue(L, closure.index());
set_lthread_state(actor_id, place_id, false);
open_lthread_state(actor_id, place_id, false, true);
status = traceback_pcall(L, 0, LUA_MULTRET);
set_lthread_state(0, 0, false);
// If there's an error message, print it.
// Otherwise, pretty-print the results.
std::ostream *ostream = lthread_print_stream();
if (status == LUA_OK) {
for (int i = top + 1; i <= lua_gettop(L); i++) {
LuaSpecial root(i);
pprint(LS, root, true, &std::cout);
std::cout << std::endl;
pprint(LS, root, true, ostream);
(*ostream) << std::endl;
}
} else {
const char *msg = lua_tostring(L, top);
const char *msg = lua_tostring(L, -1);
if (msg == NULL) {
msg = "(error object is not a string)";
}
std::cerr << msg << std::endl;
(*ostream) << msg << std::endl;
}
close_lthread_state();
LS.result();
assert(stack_is_clear());
}
@@ -535,10 +538,10 @@ void World::run_scheduled_threads(int64_t clk) {
// Resume the coroutine.
lua_State *CO = LS.ckthread(thread);
set_lthread_state(LS.ckinteger(actorid), sched.place_id(), LS.ckboolean(useppool));
open_lthread_state(LS.ckinteger(actorid), sched.place_id(), LS.ckboolean(useppool), true);
int status = lua_resume(CO, nullptr, LS.ckboolean(isnew) ? 3 : 0);
set_lthread_state(0, 0, false);
close_lthread_state();
// Three possible outcomes: finished, yielded, or errored.
if (status == LUA_YIELD) {
// When the wait statement yields, it yields the desired timestamp.
@@ -580,10 +583,60 @@ int64_t World::alloc_id_predictable() {
return t->id_player_pool_.get_one();
}
void World::set_lthread_state(int64_t actor, int64_t place, bool ppool) {
const PrintBuffer *World::get_printbuffer(int64_t actor_id) {
Tangible *actor = tangible_get(actor_id);
if (actor != nullptr) {
return actor->print_buffer_.get();
}
return nullptr;
}
void World::clear_lthread_state() {
lthread_prints_.reset();
lthread_actor_id_ = 0;
lthread_place_id_ = 0;
lthread_use_ppool_ = false;
}
void World::open_lthread_state(int64_t actor, int64_t place, bool ppool, bool prints) {
lthread_actor_id_ = actor;
lthread_place_id_ = place;
lthread_use_ppool_ = ppool;
if (prints) {
lthread_prints_.reset(new std::ostringstream);
} else {
lthread_prints_.reset();
}
}
void World::close_lthread_state() {
// Copy prints from lthread_prints_ stringstream into
// the appropriate actor's PrintBuffer. If for some reason
// there isn't an actor, or if the actor doesn't have a PrintBuffer,
// send the output to std::cerr.
if (lthread_prints_ != nullptr) {
const std::string &output = lthread_prints_->str();
PrintBuffer *pbuffer = nullptr;
Tangible *actor = tangible_get(lthread_actor_id_);
if (actor != nullptr) {
pbuffer = actor->print_buffer_.get();
}
if (pbuffer != nullptr) {
pbuffer->add_string(output);
} else {
std::cerr << output;
}
}
// Now clean up everything.
clear_lthread_state();
}
std::ostream *World::lthread_print_stream() const {
if (lthread_prints_ != nullptr) {
return lthread_prints_.get();
} else {
return &std::cerr;
}
}
void World::serialize(StreamBuffer *sb) {