Work on SourceDB:rebuild
This commit is contained in:
@@ -302,17 +302,17 @@ static void source_load_cconstants(lua_State *L) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run all the closures from the source database.
|
eng::vector<eng::string> SourceDB::modules() {
|
||||||
//
|
eng::vector<eng::string> result;
|
||||||
static eng::string source_load_lfunctions(lua_State *L) {
|
LuaVar sourcedb, key, info, seq;
|
||||||
LuaVar sourcedb, key, info, seq, closure, err;
|
LuaExtStack LS(lua_state_, sourcedb, key, info, seq);
|
||||||
LuaExtStack LS(L, sourcedb, key, info, seq, closure, err);
|
|
||||||
|
result.push_back("CORE");
|
||||||
|
|
||||||
// Get the source database.
|
// Get the source database.
|
||||||
LS.rawget(sourcedb, LuaRegistry, "sourcedb");
|
LS.rawget(sourcedb, LuaRegistry, "sourcedb");
|
||||||
if (LS.type(sourcedb) != LUA_TTABLE) {
|
if (!LS.istable(sourcedb)) {
|
||||||
LS.newtable(sourcedb);
|
return result;
|
||||||
LS.rawset(LuaRegistry, "sourcedb", sourcedb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort the keys by sequence number.
|
// Sort the keys by sequence number.
|
||||||
@@ -323,38 +323,40 @@ static eng::string source_load_lfunctions(lua_State *L) {
|
|||||||
indices[LS.ckinteger(seq)] = LS.ckstring(key);
|
indices[LS.ckinteger(seq)] = LS.ckstring(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now call the closures in the proper order.
|
for (const auto &pair : indices) {
|
||||||
eng::ostringstream errss;
|
result.push_back(pair.second);
|
||||||
for (const auto &p : indices) {
|
|
||||||
LS.rawget(info, sourcedb, p.second);
|
|
||||||
LS.rawget(closure, info, "loadresult");
|
|
||||||
|
|
||||||
// If there's already an error in the sourcedb, collect it.
|
|
||||||
if (!LS.isfunction(closure)) {
|
|
||||||
errss << LS.ckstring(closure) << "\n";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call the closure. If there's an error, collect it.
|
|
||||||
lua_pushvalue(L, closure.index());
|
|
||||||
eng::string msg = traceback_pcall(L, 0, 0);
|
|
||||||
if (!msg.empty()) {
|
|
||||||
LS.set(err, msg);
|
|
||||||
errss << msg << std::endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return errss.str();
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SourceDB::rebuild_core() {
|
||||||
|
source_clear_globals(lua_state_);
|
||||||
|
source_load_cfunctions(lua_state_);
|
||||||
|
source_load_cconstants(lua_state_);
|
||||||
|
}
|
||||||
|
|
||||||
eng::string SourceDB::rebuild() {
|
eng::string SourceDB::rebuild_module(const eng::string &mod) {
|
||||||
lua_State *L = lua_state_;
|
if (mod == "CORE") {
|
||||||
LuaExtStack LS(L);
|
rebuild_core();
|
||||||
source_clear_globals(L);
|
return "";
|
||||||
source_load_cfunctions(L);
|
} else {
|
||||||
source_load_cconstants(L);
|
LuaVar sourcedb, info, closure;
|
||||||
eng::string errs = source_load_lfunctions(L);
|
LuaExtStack LS(lua_state_, sourcedb, info, closure);
|
||||||
return errs;
|
LS.rawget(sourcedb, LuaRegistry, "sourcedb");
|
||||||
|
if (!LS.istable(sourcedb)) {
|
||||||
|
return "SourceDB not initialized";
|
||||||
|
}
|
||||||
|
LS.rawget(info, sourcedb, mod);
|
||||||
|
if (!LS.istable(info)) {
|
||||||
|
return util::ss("No such module: ", mod);
|
||||||
|
}
|
||||||
|
LS.rawget(closure, info, "loadresult");
|
||||||
|
if (!LS.isfunction(closure)) {
|
||||||
|
return util::ss(mod, ":", LS.ckstring(closure));
|
||||||
|
}
|
||||||
|
lua_pushvalue(lua_state_, closure.index());
|
||||||
|
return traceback_pcall(lua_state_, 0, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SourceDB::run_unittests() {
|
void SourceDB::run_unittests() {
|
||||||
@@ -407,8 +409,8 @@ void SourceDB::init(lua_State *L) {
|
|||||||
LS.setmetatable(nullstring, classtab);
|
LS.setmetatable(nullstring, classtab);
|
||||||
|
|
||||||
// Rebuild the global environment.
|
// Rebuild the global environment.
|
||||||
rebuild();
|
rebuild_core();
|
||||||
|
|
||||||
// We need to register all C functions with the eris permanents tables.
|
// We need to register all C functions with the eris permanents tables.
|
||||||
LS.rawget(persist, LuaRegistry, "persist");
|
LS.rawget(persist, LuaRegistry, "persist");
|
||||||
LS.rawget(unpersist, LuaRegistry, "unpersist");
|
LS.rawget(unpersist, LuaRegistry, "unpersist");
|
||||||
|
|||||||
@@ -141,17 +141,33 @@ public:
|
|||||||
//
|
//
|
||||||
void update(const util::LuaSourceVec &source);
|
void update(const util::LuaSourceVec &source);
|
||||||
|
|
||||||
// Rebuild
|
// modules
|
||||||
//
|
//
|
||||||
// Rebuild the lua environment: clear it out, then reinstall all the
|
// Returns a list of all the modules. The first item in the list
|
||||||
// functions that should be there. See above for more information.
|
// is always the string "CORE" which represents the lua core
|
||||||
|
// functionality with all the builtins. This is then followed by
|
||||||
|
// all the lua sourcefiles in the correct order.
|
||||||
//
|
//
|
||||||
// Any error messages will be collected into a single long string
|
eng::vector<eng::string> modules();
|
||||||
// containing one error per line, and returned. If the return value
|
|
||||||
// is the empty string, there were no errors.
|
|
||||||
//
|
|
||||||
eng::string rebuild();
|
|
||||||
|
|
||||||
|
// rebuild_module
|
||||||
|
//
|
||||||
|
// To rebuild the lua environment, fetch the module list, then
|
||||||
|
// call rebuild_module on each module in turn. This will return
|
||||||
|
// an error message for the module, or empty string if no error.
|
||||||
|
//
|
||||||
|
// This is a thin wrapper around traceback_pcall. The return
|
||||||
|
// value is the return value of traceback_pcall.
|
||||||
|
//
|
||||||
|
eng::string rebuild_module(const eng::string &mod);
|
||||||
|
|
||||||
|
// rebuild_core
|
||||||
|
//
|
||||||
|
// This is equivalent to rebuild_module("CORE"). Clears the environment
|
||||||
|
// and installs all the builtins. No error conditions.
|
||||||
|
//
|
||||||
|
void rebuild_core();
|
||||||
|
|
||||||
// Difference transmission.
|
// Difference transmission.
|
||||||
//
|
//
|
||||||
// Note: The patch routine applies the differences to the source
|
// Note: The patch routine applies the differences to the source
|
||||||
|
|||||||
@@ -67,21 +67,15 @@ World::World(WorldType wt) {
|
|||||||
// Create the globaldb in the registry.
|
// Create the globaldb in the registry.
|
||||||
LS.rawset(LuaRegistry, "globaldb", LuaNewTable);
|
LS.rawset(LuaRegistry, "globaldb", LuaNewTable);
|
||||||
|
|
||||||
// Initialize the SourceDB. At this stage, the sourcedb is
|
// Initialize the SourceDB.
|
||||||
// empty, so it's just populating the lua builtins.
|
|
||||||
source_db_.init(state());
|
source_db_.init(state());
|
||||||
eng::string srcerrs = source_db_.rebuild();
|
|
||||||
|
|
||||||
// Clear the clock.
|
// Clear the clock.
|
||||||
clock_ = 0;
|
clock_ = 0;
|
||||||
|
|
||||||
// Initialize global variable state.
|
// Initialize global variable state.
|
||||||
assign_seqno_ = 1;
|
assign_seqno_ = 1;
|
||||||
|
|
||||||
// There shouldn't be any lua errors in the sourceDB at this
|
|
||||||
// point, since there's no lua code in the sourceDB.
|
|
||||||
assert(srcerrs == "");
|
|
||||||
|
|
||||||
LS.result();
|
LS.result();
|
||||||
assert (stack_is_clear());
|
assert (stack_is_clear());
|
||||||
}
|
}
|
||||||
@@ -372,12 +366,31 @@ void World::update_source(const util::LuaSourcePtr &source) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is called from World::update_source, and also
|
||||||
|
// from World::patch_source in the difference transmitter.
|
||||||
|
//
|
||||||
|
// For the moment, errors are channeled to util::dprint,
|
||||||
|
// and 'print' statements just go to std::cerr. Neither
|
||||||
|
// of these is ideal. We need to get serious about setting
|
||||||
|
// up error handling.
|
||||||
|
//
|
||||||
|
// We also need to figure out a solution for what happens if
|
||||||
|
// some lua source file tries to modify, say, tangible state
|
||||||
|
// in top-level code.
|
||||||
|
//
|
||||||
|
void World::rebuild_sourcedb() {
|
||||||
|
for (const eng::string &mod: source_db_.modules()) {
|
||||||
|
eng::string err = source_db_.rebuild_module(mod);
|
||||||
|
if (!err.empty()) {
|
||||||
|
util::dprint(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void World::update_source(const util::LuaSourceVec &source) {
|
void World::update_source(const util::LuaSourceVec &source) {
|
||||||
assert(stack_is_clear());
|
assert(stack_is_clear());
|
||||||
source_db_.update(source);
|
source_db_.update(source);
|
||||||
assert(stack_is_clear());
|
rebuild_sourcedb();
|
||||||
eng::string errs = source_db_.rebuild();
|
|
||||||
util::dprint(errs);
|
|
||||||
assert(stack_is_clear());
|
assert(stack_is_clear());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -292,9 +292,8 @@ void World::patch_source(StreamBuffer *sb, DebugCollector *dbc) {
|
|||||||
DebugBlock dbb(dbc, "patch_source");
|
DebugBlock dbb(dbc, "patch_source");
|
||||||
bool modified = source_db_.patch(sb, dbc);
|
bool modified = source_db_.patch(sb, dbc);
|
||||||
if (modified) {
|
if (modified) {
|
||||||
eng::string errs = source_db_.rebuild();
|
rebuild_sourcedb();
|
||||||
DebugLine(dbc) << "Source DB rebuilt";
|
DebugLine(dbc) << "Source DB rebuilt";
|
||||||
util::dprint(errs);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -209,6 +209,10 @@ public:
|
|||||||
void update_source(const util::LuaSourcePtr &source);
|
void update_source(const util::LuaSourcePtr &source);
|
||||||
void update_source(const util::LuaSourceVec &source);
|
void update_source(const util::LuaSourceVec &source);
|
||||||
|
|
||||||
|
// Rebuild the source database.
|
||||||
|
//
|
||||||
|
void rebuild_sourcedb();
|
||||||
|
|
||||||
// Supply an HTTP response to an outstanding HTTP request.
|
// Supply an HTTP response to an outstanding HTTP request.
|
||||||
//
|
//
|
||||||
void http_response(const HttpParser &response);
|
void http_response(const HttpParser &response);
|
||||||
@@ -416,7 +420,7 @@ public:
|
|||||||
// Get a global variable as json.
|
// Get a global variable as json.
|
||||||
//
|
//
|
||||||
eng::string get_global_json(const eng::string &gvar);
|
eng::string get_global_json(const eng::string &gvar);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
|||||||
Reference in New Issue
Block a user