Fixed traceback issue, improved animqueue primitives

This commit is contained in:
2021-06-03 13:29:19 -04:00
parent 427c82ea8b
commit 5b19d407fb
7 changed files with 79 additions and 91 deletions

View File

@@ -62,67 +62,64 @@ AnimQueue::AnimQueue() {
clear_steps();
}
void AnimStep::from_lua(lua_State *L, int idx) {
void AnimStep::from_lua_store_string(lua_State *L, int idx, std::string *target, int16_t bits, const char *name) {
if ((bits_ & bits)||(*target != "")) {
luaL_error(L, "specified %s twice", name);
}
if (lua_type(L, idx) != LUA_TSTRING) {
luaL_error(L, "Expected %s to be a string", name);
}
*target = lua_tostring(L, idx);
bits_ |= bits;
}
void AnimStep::from_lua_store_number(lua_State *L, int idx, float *target, float offset, int16_t bits, const char *name) {
if (bits_ & bits) {
luaL_error(L, "specified %s twice", name);
}
if (lua_type(L, idx) != LUA_TNUMBER) {
luaL_error(L, "Expected %s to be a number", name);
}
*target = lua_tonumber(L, idx) + offset;
bits_ |= bits;
}
void AnimStep::from_lua(lua_State *L, int idx, const AnimStep &qback) {
LuaSpecial tab(idx);
LuaVar value;
LuaStack LS(L, value);
LuaVar key, value;
LuaStack LS(L, key, value);
if (!LS.istable(tab)) {
luaL_error(L, "animation spec must be a table");
}
LS.rawget(value, tab, "action");
if (LS.isstring(value)) {
action_ = LS.ckstring(value);
} else if (!LS.isnil(value)) {
luaL_error(L, "animation action must be a string");
}
LS.rawget(value, tab, "facing");
if (LS.isnumber(value)) {
facing_ = LS.cknumber(value);
bits_ |= HAS_FACING;
} else if (!LS.isnil(value)) {
luaL_error(L, "animation facing must be a number");
}
LS.rawget(value, tab, "x");
if (LS.isnumber(value)) {
xyz_.x = LS.cknumber(value);
bits_ |= HAS_X;
} else if (!LS.isnil(value)) {
luaL_error(L, "animation X coordinate must be a number");
}
LS.rawget(value, tab, "y");
if (LS.isnumber(value)) {
xyz_.y = LS.cknumber(value);
bits_ |= HAS_Y;
} else if (!LS.isnil(value)) {
luaL_error(L, "animation Y coordinate must be a number");
}
LS.rawget(value, tab, "z");
if (LS.isnumber(value)) {
xyz_.z = LS.cknumber(value);
bits_ |= HAS_Z;
} else if (!LS.isnil(value)) {
luaL_error(L, "animation Z coordinate must be a number");
}
LS.rawget(value, tab, "graphic");
if (LS.isstring(value)) {
graphic_ = LS.ckstring(value);
bits_ |= HAS_GRAPHIC;
} else if (!LS.isnil(value)) {
luaL_error(L, "animation graphic must be a string");
}
LS.rawget(value, tab, "plane");
if (LS.isstring(value)) {
plane_ = LS.ckstring(value);
bits_ |= HAS_PLANE;
} else if (!LS.isnil(value)) {
luaL_error(L, "animation plane must be a string");
LS.set(key, LuaNil);
while (LS.next(tab, key, value)) {
if (!LS.isstring(key)) {
luaL_error(L, "animation specs must be key/value where key is a string");
}
std::string skey = LS.ckstring(key);
if (skey == "action") {
from_lua_store_string(L, value.index(), &action_, 0, "action");
} else if (skey == "graphic") {
from_lua_store_string(L, value.index(), &graphic_, HAS_GRAPHIC, "graphic");
} else if (skey == "plane") {
from_lua_store_string(L, value.index(), &plane_, HAS_PLANE, "plane");
} else if (skey == "x") {
from_lua_store_number(L, value.index(), &xyz_.x, 0.0, HAS_X, "X coordinate");
} else if (skey == "y") {
from_lua_store_number(L, value.index(), &xyz_.y, 0.0, HAS_Y, "Z coordinate");
} else if (skey == "z") {
from_lua_store_number(L, value.index(), &xyz_.z, 0.0, HAS_Z, "Z coordinate");
} else if (skey == "dx") {
from_lua_store_number(L, value.index(), &xyz_.x, qback.xyz().x, HAS_X, "X coordinate");
} else if (skey == "dy") {
from_lua_store_number(L, value.index(), &xyz_.y, qback.xyz().y, HAS_Y, "Y coordinate");
} else if (skey == "dz") {
from_lua_store_number(L, value.index(), &xyz_.z, qback.xyz().z, HAS_Z, "Z coordinate");
} else if (skey == "facing") {
from_lua_store_number(L, value.index(), &facing_, 0.0, HAS_FACING, "facing");
} else {
luaL_error(L, "Unrecognized animation spec: %s", skey.c_str());
}
}
}

View File

@@ -57,6 +57,9 @@ private:
std::string graphic_;
std::string plane_;
void from_lua_store_string(lua_State *L, int idx, std::string *target, int16_t bits, const char *name);
void from_lua_store_number(lua_State *L, int idx, float *target, float offset, int16_t bits, const char *name);
public:
AnimStep();
~AnimStep();
@@ -103,7 +106,10 @@ public:
// graphic: "graphic"
// plane: "plane"
//
void from_lua(lua_State *L, int idx);
// qback: the animation queue back, from which relative
// moves are computed.
//
void from_lua(lua_State *L, int idx, const AnimStep &qback);
// For any values that are unchanged in this step,
// echo the values of the previous step.

View File

@@ -9,6 +9,7 @@
// The error message is replaced with a traceback.
//
int traceback_coroutine(lua_State *L) {
lua_checkstack(L, 20);
int top = lua_gettop(L);
// Convert message to a string

View File

@@ -22,8 +22,8 @@ int traceback_coroutine(lua_State *L);
// traceback_pcall
//
// same as lua_pcall, except that it automatically supplies traceback_handler as
// a message handler.
// same as lua_pcall, except that it automatically supplies
// traceback_coroutine as a message handler.
//
int traceback_pcall(lua_State *L, int narg, int nret);

View File

@@ -194,28 +194,6 @@ World::Redirects World::fetch_redirects() {
return std::move(result);
}
// void Tangible::be_a_player() {
// if (!id_player_pool_.fifo_enabled()) {
// id_player_pool_.enable_fifo();
// AnimStep asinit;
// asinit.set_graphic("player");
// anim_queue_.add(world_->id_global_pool_.get_one(), asinit);
// anim_queue_.keep_only(1);
// update_plane_item();
// LuaVar classtab, mt, place, tangibles;
// LuaStack LS(world_->state(), classtab, mt, place, tangibles);
// LS.makeclass(classtab, "player");
// LS.rawget(tangibles, LuaRegistry, "tangibles");
// LS.rawget(place, tangibles, id());
// LS.getmetatable(mt, place);
// LS.rawset(mt, "__index", classtab);
// LS.result();
// }
// }
int64_t World::create_login_actor() {
Tangible *tan = tangible_make(state(), 0, true);
LuaArg database;
@@ -414,7 +392,7 @@ void World::run_scheduled_threads(int64_t clk) {
thread_sched_.add(sched.clock() + int64_t(delay), sched.thread_id(), sched.place_id());
std::cerr << "Added to schedule." << std::endl;
}
} else if (status == 0) {
} else if (status == LUA_OK) {
// Successfully ran to completion. Remove from thread table.
std::cerr << "Thread ran to completion." << std::endl;
LS.rawset(threads, sched.thread_id(), LuaNil);
@@ -511,8 +489,9 @@ LuaDefine(tangible_animate, "c") {
World *w = World::fetch_global_pointer(L);
Tangible *tan = w->tangible_get(L, tanobj.index());
int64_t id = w->id_global_pool_.alloc_id_for_thread(L);
const AnimStep &prev = tan->anim_queue_.back();
AnimStep step;
step.from_lua(L, config.index());
step.from_lua(L, config.index(), prev);
if (step.action() == "") {
luaL_error(L, "animation action must be specified");
}
@@ -561,8 +540,8 @@ LuaDefine(tangible_build, "c") {
LS.getclass(classtab, classname);
// Parse the initial animation step.
AnimStep initstep;
initstep.from_lua(L, config.index());
AnimStep initstep, blank;
initstep.from_lua(L, config.index(), blank);
if (!initstep.has_xyz()) {
luaL_error(L, "You must specify (X,Y,Z) for new tangible");
}

View File

@@ -199,7 +199,7 @@ public:
void serialize(StreamBuffer *sb);
void deserialize(StreamBuffer *sb);
// Snapshot and rollback - temporary.
// Snapshot and rollback.
//
void snapshot();
void rollback();

View File

@@ -7,27 +7,32 @@ function player.interface(actor, place)
gui.menu_item("west", "Go West")
end
function player:printanimstate()
graphic,plane,x,y,z,facing = tangible.animstate(self)
print("Resulting state: ", graphic, plane, x, y, z, facing)
end
function player.action.north(actor, place, dialog)
print("Moving north")
x,y,z = tangible.xyz(place);
tangible.animate(place, {action="walk", dy=1})
actor:printanimstate()
end
function player.action.south(actor, place, dialog)
print("Moving south")
x,y,z = tangible.xyz(place);
tangible.animate(place, {action="walk", dy=-1})
actor:printanimstate()
end
function player.action.east(actor, place, dialog)
print("Moving east")
x,y,z = tangible.xyz(place);
tangible.animate(place, {action="walk", dx=1})
actor:printanimstate()
end
function player.action.west(actor, place, dialog)
print("Moving west")
x,y,z = tangible.xyz(place)
tangible.animate(place, {action="walk", dx=-1})
actor:printanimstate()
end