Reworking the keyword parser, also fixed some dynamic linking issues

This commit is contained in:
2025-01-20 18:54:05 -05:00
parent a01f6f4e7b
commit 2d531b28b3
9 changed files with 243 additions and 118 deletions

View File

@@ -183,7 +183,7 @@ LuaDefine(tangible_animate, "tan,options,config",
bool replace = false;
if (!LS.isnil(options)) {
LuaKeywordParser kp(LS, options);
if (kp.parse(option, "replace")) {
if (kp.optional(option, "replace")) {
replace = LS.ckboolean(option);
}
kp.final_check_throw();
@@ -274,27 +274,48 @@ LuaDefine(tangible_delete, "tan",
return LS.result();
}
LuaDefine(tangible_build, "config",
LuaDefine(tangible_build, "config",
"|Build a new tangible object."
"|"
"|The config table must contain: class,animstate."
"|" ){
"|The configuration table must contain the keyword 'class', which"
"|must be the name of a class created with 'makeclass'. It may also"
"|contain the following values:"
"|"
"| bp - the unreal blueprint, defaults to class name."
"| plane - the plane, defaults to actor.plane"
"| xyz - the xyz coordinate, defaults to actor.xyz"
"| facing - the rotation, defaults to actor.facing"
"|"
"|Tangible.build will create an initial animstate containing only"
"|bp, plane, xyz, and facing."
"|"
"|After creating the tangible and setting up the initial animation"
"|state, build will call the constructor for the tangible."
"|The constructor must have this prototype:"
"|"
"| function myclass.init(place, actor, config)"
"|"
"|The configuration table passed to tangible.build is then passed"
"|directly to the init function. The constructor should use the keywords"
"|module to parse the keyword arguments."
"|"
"|The constructor is not allowed to block."
){
LuaArg config;
LuaVar classname, classtab, mt, animstate;
LuaVar classname, classtab, bp, plane, xyz, facing, mt;
LuaRet database;
LuaDefStack LS(L, config, classname, classtab, database, mt, animstate);
LuaDefStack LS(L, config, classname, classtab, bp, plane, xyz, facing, mt, database);
World *w = World::fetch_global_pointer(L);
LuaKeywordParser kp(LS, config);
kp.required(classname, "class");
kp.optional(bp, "bp");
kp.optional(plane, "plane");
kp.optional(xyz, "xyz");
kp.optional(facing, "facing");
kp.check_throw();
// Get the keyword arguments.
if (!kp.parse(classname, "class")) {
luaL_error(L, "You must specify a class for the tangible");
}
if (!kp.parse(animstate, "animstate")) {
luaL_error(L, "You must specify an animstate table");
}
kp.final_check_throw();
// Find the class.
// Verify the class.
eng::string err = LS.getclass(classtab, classname);
if (err != "") {
luaL_error(L, "%s", err.c_str());
@@ -302,19 +323,29 @@ LuaDefine(tangible_build, "config",
// Calculate the initial animation state.
AnimState state;
err = state.from_lua(LS, animstate, true, false);
if (err != "") {
luaL_error(L, "%s", err.c_str());
if (!LS.isnil(bp)) {
state.set_string("bp", LS.ckstring(bp));
} else {
state.set_string("bp", LS.ckstring(classname));
}
if (!state.contains("xyz") || !state.contains("plane")) {
luaL_error(L, "You must specify both xyz and plane in animstate");
if (!LS.isnil(plane)) {
state.set_string("plane", LS.ckstring(plane));
}
err = state.add_defaults(nullptr);
if (!LS.isnil(xyz)) {
state.set_dxyz("xyz", LS.ckxyz(xyz));
}
if (!LS.isnil(facing)) {
state.set_number("facing", LS.cknumber(facing));
}
// Add default values from the actor. Set persistent flags.
Tangible *actor = w->tangible_get(w->lthread_actor_id_);
AnimState actorstate = actor->anim_queue_.get_final_persistent();
err = state.add_defaults(&actorstate);
if (err != "") {
luaL_error(L, "%s", err.c_str());
}
World *w = World::fetch_global_pointer(L);
int64_t new_id = w->alloc_id_predictable();
Tangible *tan = w->tangible_make(LS, database, new_id);
@@ -322,9 +353,12 @@ LuaDefine(tangible_build, "config",
LS.getmetatable(mt, database);
LS.rawset(mt, "__index", classtab);
// Initialize the animstate of the new tangible.
tan->anim_queue_.clear(state);
tan->update_plane_item();
// TODO: call the constructor.
return LS.result();
}
@@ -839,7 +873,7 @@ LuaDefine(pprintx, "options",
PrettyPrintOptions options;
LuaKeywordParser kp(LS, loptions);
options.parse(kp);
if (!kp.parse(value, "value")) {
if (!kp.optional(value, "value")) {
LS.set(value, LuaNil);
}
kp.final_check_throw();