233 lines
6.7 KiB
C++
233 lines
6.7 KiB
C++
#include <limits>
|
|
#include "luastack.hpp"
|
|
#include "animqueue.hpp"
|
|
|
|
AnimStep::AnimStep() {}
|
|
AnimStep::~AnimStep() {}
|
|
|
|
AnimQueue::AnimQueue() {
|
|
size_limit_ = 10; // Default size limit.
|
|
steps_.emplace_back();
|
|
AnimStep &init = steps_.back();
|
|
init.id_ = 0;
|
|
init.facing_ = 0;
|
|
init.xyz_ = util::XYZ(0,0,0);
|
|
init.graphic_ = "nothing";
|
|
init.plane_ = "nowhere";
|
|
init.bits_ = AnimStep::HAS_EVERYTHING;
|
|
}
|
|
|
|
void AnimQueue::set_size_limit(int n) {
|
|
assert(n >= 2);
|
|
size_limit_ = n;
|
|
}
|
|
|
|
void AnimQueue::add(int64_t id, lua_State *L, int idx) {
|
|
LuaSpecial tab(idx);
|
|
LuaVar value;
|
|
LuaStack LS(L, value);
|
|
if (!LS.istable(tab)) {
|
|
luaL_error(L, "animation spec must be a table");
|
|
}
|
|
|
|
AnimStep step = steps_.back();
|
|
step.id_ = id;
|
|
step.bits_ = 0;
|
|
step.action_ = "";
|
|
|
|
LS.rawget(value, tab, "action");
|
|
if (!LS.isstring(value)) {
|
|
luaL_error(L, "animation action is not optional and must be a string");
|
|
}
|
|
step.action_ = LS.ckstring(value);
|
|
|
|
LS.rawget(value, tab, "facing");
|
|
if (LS.isnumber(value)) {
|
|
step.facing_ = LS.cknumber(value);
|
|
step.bits_ |= AnimStep::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)) {
|
|
step.xyz_.x = LS.cknumber(value);
|
|
step.bits_ |= AnimStep::HAS_XYZ;
|
|
} else if (!LS.isnil(value)) {
|
|
luaL_error(L, "animation X coordinate must be a number");
|
|
}
|
|
|
|
LS.rawget(value, tab, "y");
|
|
if (LS.isnumber(value)) {
|
|
step.xyz_.y = LS.cknumber(value);
|
|
step.bits_ |= AnimStep::HAS_XYZ;
|
|
} else if (!LS.isnil(value)) {
|
|
luaL_error(L, "animation Y coordinate must be a number");
|
|
}
|
|
|
|
LS.rawget(value, tab, "z");
|
|
if (LS.isnumber(value)) {
|
|
step.xyz_.z = LS.cknumber(value);
|
|
step.bits_ |= AnimStep::HAS_XYZ;
|
|
} else if (!LS.isnil(value)) {
|
|
luaL_error(L, "animation Z coordinate must be a number");
|
|
}
|
|
|
|
LS.rawget(value, tab, "dx");
|
|
if (LS.isnumber(value)) {
|
|
step.xyz_.x += LS.cknumber(value);
|
|
step.bits_ |= AnimStep::HAS_XYZ;
|
|
} else if (!LS.isnil(value)) {
|
|
luaL_error(L, "animation DX offset must be a number");
|
|
}
|
|
|
|
LS.rawget(value, tab, "dy");
|
|
if (LS.isnumber(value)) {
|
|
step.xyz_.y += LS.cknumber(value);
|
|
step.bits_ |= AnimStep::HAS_XYZ;
|
|
} else if (!LS.isnil(value)) {
|
|
luaL_error(L, "animation DY offset must be a number");
|
|
}
|
|
|
|
LS.rawget(value, tab, "dz");
|
|
if (LS.isnumber(value)) {
|
|
step.xyz_.z += LS.cknumber(value);
|
|
step.bits_ |= AnimStep::HAS_XYZ;
|
|
} else if (!LS.isnil(value)) {
|
|
luaL_error(L, "animation DZ offset must be a number");
|
|
}
|
|
|
|
LS.rawget(value, tab, "graphic");
|
|
if (LS.isstring(value)) {
|
|
step.graphic_ = LS.ckstring(value);
|
|
step.bits_ |= AnimStep::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)) {
|
|
step.plane_ = LS.ckstring(value);
|
|
step.bits_ |= AnimStep::HAS_PLANE;
|
|
} else if (!LS.isnil(value)) {
|
|
luaL_error(L, "animation plane must be a string");
|
|
}
|
|
|
|
steps_.push_back(step);
|
|
while (int(steps_.size()) > size_limit_) {
|
|
steps_.pop_front();
|
|
}
|
|
AnimStep &init = steps_.front();
|
|
init.id_ = 0;
|
|
init.action_ = "";
|
|
init.bits_ = AnimStep::HAS_EVERYTHING;
|
|
}
|
|
|
|
void AnimQueue::add(int64_t id, const std::string &action) {
|
|
AnimStep step = steps_.back();
|
|
step.id_ = id;
|
|
step.action_ = action;
|
|
step.bits_ = 0;
|
|
|
|
steps_.push_back(step);
|
|
while (int(steps_.size()) > size_limit_) {
|
|
steps_.pop_front();
|
|
}
|
|
AnimStep &init = steps_.front();
|
|
init.id_ = 0;
|
|
init.action_ = "";
|
|
init.bits_ = AnimStep::HAS_EVERYTHING;
|
|
}
|
|
|
|
void AnimQueue::set_facing(float f) {
|
|
AnimStep &last = steps_.back();
|
|
last.bits_ |= AnimStep::HAS_FACING;
|
|
last.facing_ = f;
|
|
}
|
|
|
|
void AnimQueue::set_xyz(util::XYZ xyz) {
|
|
AnimStep &last = steps_.back();
|
|
last.bits_ |= AnimStep::HAS_XYZ;
|
|
last.xyz_ = xyz;
|
|
}
|
|
|
|
void AnimQueue::set_graphic(const std::string &g) {
|
|
AnimStep &last = steps_.back();
|
|
last.bits_ |= AnimStep::HAS_GRAPHIC;
|
|
last.graphic_ = g;
|
|
}
|
|
|
|
void AnimQueue::set_plane(const std::string &p) {
|
|
AnimStep &last = steps_.back();
|
|
last.bits_ |= AnimStep::HAS_PLANE;
|
|
last.plane_ = p;
|
|
}
|
|
|
|
const std::string &AnimQueue::get_graphic() const {
|
|
const AnimStep &last = steps_.back();
|
|
return last.graphic_;
|
|
}
|
|
|
|
const std::string &AnimQueue::get_plane() const {
|
|
const AnimStep &last = steps_.back();
|
|
return last.plane_;
|
|
}
|
|
|
|
const util::XYZ &AnimQueue::get_xyz() const {
|
|
const AnimStep &last = steps_.back();
|
|
return last.xyz_;
|
|
}
|
|
|
|
LuaDefine(unittests_animqueue, "c") {
|
|
// Check initial state.
|
|
AnimQueue aq;
|
|
aq.set_size_limit(3);
|
|
|
|
LuaAssert(L, aq.size() == 1);
|
|
const AnimStep *st = &aq.nth(0);
|
|
LuaAssert(L, st->id() == 0);
|
|
LuaAssert(L, st->action() == "");
|
|
LuaAssert(L, st->bits() == AnimStep::HAS_EVERYTHING);
|
|
LuaAssert(L, st->facing() == 0.0);
|
|
LuaAssert(L, st->xyz() == util::XYZ(0,0,0));
|
|
LuaAssert(L, st->graphic() == "nothing");
|
|
LuaAssert(L, st->plane() == "nowhere");
|
|
|
|
// Add a step.
|
|
aq.add(12345, "walk");
|
|
LuaAssert(L, aq.size() == 2);
|
|
st = &aq.nth(1);
|
|
LuaAssert(L, st->id() == 12345);
|
|
LuaAssert(L, st->action() == "walk");
|
|
LuaAssert(L, st->bits() == 0);
|
|
LuaAssert(L, st->facing() == 0.0);
|
|
LuaAssert(L, st->xyz() == util::XYZ(0,0,0));
|
|
LuaAssert(L, st->graphic() == "nothing");
|
|
LuaAssert(L, st->plane() == "nowhere");
|
|
|
|
// Test the setters.
|
|
aq.set_facing(180);
|
|
LuaAssert(L, st->facing() == 180);
|
|
LuaAssert(L, st->bits() == AnimStep::HAS_FACING);
|
|
aq.set_xyz(util::XYZ(3,4,5));
|
|
LuaAssert(L, st->xyz() == util::XYZ(3, 4, 5));
|
|
LuaAssert(L, st->bits() == (AnimStep::HAS_FACING | AnimStep::HAS_XYZ));
|
|
aq.set_plane("somewhere");
|
|
LuaAssert(L, st->plane() == "somewhere");
|
|
LuaAssert(L, st->bits() == (AnimStep::HAS_FACING | AnimStep::HAS_XYZ | AnimStep::HAS_PLANE));
|
|
aq.set_graphic("something");
|
|
LuaAssert(L, st->graphic() == "something");
|
|
LuaAssert(L, st->bits() == (AnimStep::HAS_FACING | AnimStep::HAS_XYZ | AnimStep::HAS_PLANE | AnimStep::HAS_GRAPHIC));
|
|
|
|
// Exceed the length limit, dropping first element.
|
|
aq.add(12346, "walk");
|
|
aq.add(12347, "walk");
|
|
LuaAssert(L, aq.size() == 3);
|
|
LuaAssert(L, aq.nth(0).id() == 0);
|
|
LuaAssert(L, aq.nth(0).action() == "");
|
|
LuaAssert(L, aq.nth(0).bits() == AnimStep::HAS_EVERYTHING);
|
|
LuaAssert(L, aq.nth(1).id() == 12346);
|
|
LuaAssert(L, aq.nth(2).id() == 12347);
|
|
return 0;
|
|
}
|