Empty-string anim queues are now allowed

This commit is contained in:
2026-02-25 02:54:54 -05:00
parent 4b81a0768a
commit 95cd378dc0
6 changed files with 34 additions and 51 deletions

View File

@@ -14,23 +14,24 @@ the `.cpp` file (not the `.hpp`), it is marked **(cpp-only)**.
- **debugcollector** → util
- **streambuffer** → eng-malloc, luastack, util
- **table** → luastack
- **pprint** → luastack, table, util
- **drivenengine** → enginewrapper, invocation, streambuffer, util
- **keywords** → luastack, util(cpp-only)
- **pprint** → luastack, table(cpp-only), util(cpp-only)
- **json** → luastack, util
- **http** → drivenengine, json(cpp-only), luastack, streambuffer
- **planemap** → luastack, util
- **invocation** → enginewrapper, streambuffer
- **drivenengine** → enginewrapper, invocation, streambuffer, util, animqueue(cpp-only)
- **luasnap** → luastack, streambuffer
- **serializelua** → luastack, streambuffer
- **sched** → luastack, streambuffer
- **idalloc** → debugcollector, luastack, streambuffer
- **invocation** → enginewrapper, streambuffer
- **source** → debugcollector, luastack, luasnap, streambuffer, table(cpp-only), traceback, util
- **animqueue** → debugcollector, luastack, streambuffer, util
- **printbuffer** → debugcollector, invocation, streambuffer, util
- **world** → animqueue, debugcollector, http, idalloc, invocation, luasnap, luastack, planemap, printbuffer, pprint, sched, serializelua, source, streambuffer, table, traceback
- **source** → debugcollector, luastack, streambuffer, util, luasnap(cpp-only), table(cpp-only), traceback(cpp-only)
- **planemap** → luastack, util
- **http** → drivenengine, keywords, luastack, streambuffer, json(cpp-only), util(cpp-only)
- **world** → animqueue, debugcollector, http, idalloc, invocation, luasnap, luastack, planemap, printbuffer, pprint(cpp-only), sched, serializelua(cpp-only), source, streambuffer, table(cpp-only), traceback(cpp-only)
- **lpxclient** → drivenengine, invocation, printbuffer, util, world
- **lpxserver** → drivenengine, luastack, printbuffer, util, world
- **eng-tests** → drivenengine, streambuffer, world
- **unit-testing** → drivenengine(cpp-only), streambuffer(cpp-only), traceback(cpp-only), world(cpp-only)
## Observations
@@ -38,20 +39,15 @@ the `.cpp` file (not the `.hpp`), it is marked **(cpp-only)**.
`http.hpp` includes `drivenengine.hpp` because it uses
`SharedChannel` (defined in drivenengine). Meanwhile, `world`
depends on both `http` and `drivenengine`, and `drivenengine`
depends on `world`. This creates a layering tangle:
depends on both `http` and `drivenengine`, but `drivenengine` no
longer depends on `world` (that circular dependency was broken).
The remaining concern is that `SharedChannel` is an I/O concept
from the driver boundary. Moving `SharedChannel` and `Channel`
into a smaller, lower-level header (perhaps `enginewrapper.hpp`
or a new `channel.hpp`) would let `http` drop its dependency on
`drivenengine` entirely.
```
world -> http -> drivenengine -> world
```
The `SharedChannel` type (`std::shared_ptr<Channel>`) is really an
I/O concept from the driver boundary. Moving `SharedChannel` and
`Channel` into a smaller, lower-level header (perhaps
`enginewrapper.hpp` or a new `channel.hpp`) would let `http` drop
its dependency on `drivenengine` entirely.
### world is a mega-consumer (16 dependencies)
### world is a mega-consumer
`world` depends on nearly every other module. This is expected for
the central game-state container, but it does make `world` hard to

View File

@@ -420,7 +420,15 @@ const FlxAnimationStep *FlxAnimTracker::FindAnimation(int64 hash) const
}
void FlxAnimTracker::Update(std::string_view encqueue) {
check(!encqueue.empty());
// An empty encqueue represents a blank queue: one step with hash=0, empty body.
//
if (encqueue.empty()) {
if (AQ.Num() == 1 && AQ[0].Hash == 0) return;
Changed = true;
AQ.Empty();
AQ.Emplace(0, std::string_view());
return;
}
// If the first hash matches, we don't bother updating at all.
//

View File

@@ -12,13 +12,6 @@
#include <cstdlib>
util::SharedStdString AnimQueue::blankqueue_;
void AnimQueue::initialize_module() {
AnimQueue queue;
blankqueue_ = queue.get_encoded_queue();
}
static int64_t hash_encstep(int64_t prev, std::string_view s) {
// We drop the most significant bit to ensure that the value
// can be represented as a nonnegative int64.

View File

@@ -364,17 +364,6 @@ public:
//
util::SharedStdString get_encoded_queue() const { return encqueue_; }
// Get a serialized representation of a blank queue.
//
// Since an animqueue must have at least one step, the blank queue
// contains a single default step.
//
static util::SharedStdString get_encoded_blank_queue() { return blankqueue_; }
// Initialize the animqueue module.
//
static void initialize_module();
private:
struct QueueRange {
int size;
@@ -425,9 +414,6 @@ private:
//
util::SharedStdString encqueue_;
// The blank animation queue.
//
static util::SharedStdString blankqueue_;
};

View File

@@ -852,10 +852,9 @@ static void default_get_tangibles_near(EngineWrapper *, uint64_t, double, double
}
static void default_get_animation_queues(EngineWrapper *, uint32_t count, const int64_t *, uint32_t *lengths, const char **strings) {
util::SharedStdString blank = AnimQueue::get_encoded_blank_queue();
for (int i = 0; i < int(count); i++) {
lengths[i] = blank->size();
strings[i] = blank->c_str();
lengths[i] = 0;
strings[i] = "";
}
}

View File

@@ -1264,7 +1264,6 @@ void World::rollback() {
//
void engine_initialization() {
SourceDB::register_lua_builtins();
AnimQueue::initialize_module();
}
static DrivenEngineInitializerReg eireg(engine_initialization);
@@ -1280,14 +1279,16 @@ void World::get_animation_queues(uint32_t count, const int64_t *ids, uint32_t *l
for (int i = 0; i < int(count); i++) {
Tangible *tan = tangible_get(ids[i]);
if (tan == nullptr) {
wrapper_anim_queues_[i] = AnimQueue::get_encoded_blank_queue();
wrapper_anim_queues_[i] = nullptr;
lengths[i] = 0;
strings[i] = "";
} else {
wrapper_anim_queues_[i] = tan->anim_queue_.get_encoded_queue();
}
lengths[i] = wrapper_anim_queues_[i]->size();
strings[i] = wrapper_anim_queues_[i]->c_str();
}
}
}
void World::get_tangibles_near(uint64_t tanid, double rx, double ry, double rz, uint32_t *count, int64_t **ids) {
uint32_t hash1 = eng::memhash();