Fix name reuse issues for actors, and make luprex IDs more readable

This commit is contained in:
2025-08-04 17:13:34 -04:00
parent 13f8d2669c
commit 9b304985e3
6 changed files with 46 additions and 39 deletions

View File

@@ -38,6 +38,8 @@ void UlxTangible::DeleteCurrentActor()
// Now destroy the actor itself. According to various // Now destroy the actor itself. According to various
// documents I've read online, it may be necessary to take // documents I've read online, it may be necessary to take
// further steps to delete the object. Not clear. // further steps to delete the object. Not clear.
UE_LOG(LogLuprexIntegration, Display, TEXT("Deleting actor: %s"), *CurrentActor->GetName());
CurrentActor->Rename(nullptr);
CurrentActor->Destroy(); CurrentActor->Destroy();
// If this actor previously was posessed by a player controller, // If this actor previously was posessed by a player controller,
@@ -75,7 +77,7 @@ void UlxTangible::SetActorBlueprint(const FString &XName) {
FActorSpawnParameters params; FActorSpawnParameters params;
// Give the new actor a reasonable name. // Give the new actor a reasonable name.
params.Name = FName(*FString::Printf(TEXT("%s_%ld"), *Name, TangibleId)); params.Name = FName(*FString::Printf(TEXT("Tan:%s_%ld"), *Name, TangibleId));
// Currently, the actor is spawned at (0,0,0), which is not good. // Currently, the actor is spawned at (0,0,0), which is not good.
// We should spawn at the actor's current location. I'll get to it // We should spawn at the actor's current location. I'll get to it
@@ -91,6 +93,8 @@ void UlxTangible::SetActorBlueprint(const FString &XName) {
// want to delay that until after we've had a chance to set // want to delay that until after we've had a chance to set
// up the TangibleComponent. // up the TangibleComponent.
params.bDeferConstruction = true; params.bDeferConstruction = true;
params.bNoFail = true;
UE_LOG(LogLuprexIntegration, Display, TEXT("Creating Actor: %s"), *params.Name.ToString());
AActor* a = w->SpawnActor(blueprint, &transform, params); AActor* a = w->SpawnActor(blueprint, &transform, params);
check(a != nullptr); check(a != nullptr);

View File

@@ -107,7 +107,6 @@ public:
RunUnitTests() { RunUnitTests() {
world_.reset(new World(WORLD_TYPE_MASTER)); world_.reset(new World(WORLD_TYPE_MASTER));
stop_driver();
rescan_lua_source(true); rescan_lua_source(true);
} }
@@ -116,6 +115,7 @@ public:
case AccessKind::INVOKE_LUA_SOURCE: { case AccessKind::INVOKE_LUA_SOURCE: {
world_->update_source(datapk); world_->update_source(datapk);
world_->run_unittests(); world_->run_unittests();
stop_driver();
break; break;
} }
default: break; default: break;

View File

@@ -7,6 +7,7 @@
#include <ostream> #include <ostream>
// This is used in some unit tests to make sure that the deque contains the expected values.
static bool ranges_equal(const eng::deque<int64_t> &dq, int64_t a, int64_t b, int64_t c) { static bool ranges_equal(const eng::deque<int64_t> &dq, int64_t a, int64_t b, int64_t c) {
if (dq.size() != 3) return false; if (dq.size() != 3) return false;
if (dq[0] != a) return false; if (dq[0] != a) return false;
@@ -27,14 +28,14 @@ IdGlobalPool::~IdGlobalPool() {
void IdGlobalPool::init_master() { void IdGlobalPool::init_master() {
salvaged_.clear(); salvaged_.clear();
next_batch_ = 0x0001000000000000; next_batch_ = 1000000000000000;
next_id_ = 0x0010000000000000; next_id_ = 5000000000000000;
} }
void IdGlobalPool::init_synch() { void IdGlobalPool::init_synch() {
salvaged_.clear(); salvaged_.clear();
next_batch_ = 0; next_batch_ = 0;
next_id_ = 0x001E000000000000; next_id_ = 8000000000000000;
} }
int64_t IdGlobalPool::get_one() { int64_t IdGlobalPool::get_one() {
@@ -260,7 +261,7 @@ eng::string IdPlayerPool::debug_string() const {
} }
static int64_t nthbatch(int64_t n) { static int64_t nthbatch(int64_t n) {
return int64_t(0x0001000000000000) + n*256; return int64_t(1000000000000000) + n*256;
} }
LuaDefine(unittests_idalloc, "", "some unit tests") { LuaDefine(unittests_idalloc, "", "some unit tests") {
@@ -272,15 +273,15 @@ LuaDefine(unittests_idalloc, "", "some unit tests") {
// Synchronous pools produce IDs starting at 0x001E000000000000 // Synchronous pools produce IDs starting at 0x001E000000000000
gp.init_synch(); gp.init_synch();
LuaAssert(L, gp.get_one() == 0x001E000000000000); LuaAssert(L, gp.get_one() == 8000000000000000);
LuaAssert(L, gp.get_one() == 0x001E000000000001); LuaAssert(L, gp.get_one() == 8000000000000001);
LuaAssert(L, gp.get_one() == 0x001E000000000002); LuaAssert(L, gp.get_one() == 8000000000000002);
// Master pools produce IDs starting at 0x0010000000000000 // Master pools produce IDs starting at 0x0010000000000000
gp.init_master(); gp.init_master();
LuaAssert(L, gp.get_one() == 0x0010000000000000); LuaAssert(L, gp.get_one() == 5000000000000000);
LuaAssert(L, gp.get_one() == 0x0010000000000001); LuaAssert(L, gp.get_one() == 5000000000000001);
LuaAssert(L, gp.get_one() == 0x0010000000000002); LuaAssert(L, gp.get_one() == 5000000000000002);
// Synchronous pools produce only null batches. // Synchronous pools produce only null batches.
gp.init_synch(); gp.init_synch();
@@ -329,7 +330,7 @@ LuaDefine(unittests_idalloc, "", "some unit tests") {
pp.set_fifo_capacity(3); pp.set_fifo_capacity(3);
pp.refill(); pp.refill();
LuaAssert(L, pp.size() == 0); LuaAssert(L, pp.size() == 0);
LuaAssert(L, pp.get_one() == 0x001E000000000000); LuaAssert(L, pp.get_one() == 8000000000000000);
LuaAssert(L, pp.size() == 0); LuaAssert(L, pp.size() == 0);
// In the master model, with fifo disabled. Fifo should remain // In the master model, with fifo disabled. Fifo should remain
@@ -339,7 +340,7 @@ LuaDefine(unittests_idalloc, "", "some unit tests") {
pp.set_fifo_capacity(0); pp.set_fifo_capacity(0);
pp.refill(); pp.refill();
LuaAssert(L, pp.size() == 0); LuaAssert(L, pp.size() == 0);
LuaAssert(L, pp.get_one() == 0x0010000000000000); LuaAssert(L, pp.get_one() == 5000000000000000);
LuaAssert(L, pp.size() == 0); LuaAssert(L, pp.size() == 0);
// Test refill from master (with enabled fifo). // Test refill from master (with enabled fifo).
@@ -370,13 +371,13 @@ LuaDefine(unittests_idalloc, "", "some unit tests") {
// Serialize and deserialize a global pool. // Serialize and deserialize a global pool.
gp.init_master(); gp.init_master();
gpds.init_master(); gpds.init_master();
LuaAssert(L, gp.get_one() == 0x0010000000000000); LuaAssert(L, gp.get_one() == 5000000000000000);
LuaAssert(L, gp.get_batch() == nthbatch(0)); LuaAssert(L, gp.get_batch() == nthbatch(0));
gp.salvage(nthbatch(182)); gp.salvage(nthbatch(182));
gp.salvage(nthbatch(183)); gp.salvage(nthbatch(183));
gp.serialize(&sb); gp.serialize(&sb);
gpds.deserialize(&sb); gpds.deserialize(&sb);
LuaAssert(L, gpds.get_one() == 0x0010000000000001); LuaAssert(L, gpds.get_one() == 5000000000000001);
LuaAssert(L, gpds.get_batch() == nthbatch(183)); LuaAssert(L, gpds.get_batch() == nthbatch(183));
LuaAssert(L, gpds.get_batch() == nthbatch(182)); LuaAssert(L, gpds.get_batch() == nthbatch(182));
LuaAssert(L, gpds.get_batch() == nthbatch(1)); LuaAssert(L, gpds.get_batch() == nthbatch(1));

View File

@@ -37,17 +37,19 @@
// //
// THE NUMERIC RANGES // THE NUMERIC RANGES
// //
// The largest integer that can be stored losslessly in a lua_Number is: // Any 53-bit number can be losslessly stored in a lua_Number. In other
// words, the largest integer that can be stored losslessly is:
// //
// * 0x0020000000000000 // * 0x001FFFFFFFFFFFFF
// //
// In other words, any 53-bit number can be stored. We subdivide the range as // As it turns out, that's just barely larger than 9 quadrillion. We are
// follows: // going to use IDs that are between 0 and 9 quadrillion. We divide the
// range of possible IDs into several subsections:
// //
// * 0x0000+ : manually created IDs. // 0 quadrillion + : manually created IDs.
// * 0x0001+ : used by master model's IdGlobalPool to create batches. // 1 quadrillion + : used by master model's IdGlobalPool to create batches.
// * 0x0010+ : used by master model's IdGlobalPool to create individual IDs. // 5 quadrillion + : used by master model's IdGlobalPool to create individual IDs.
// * 0x001E+ : used by sync model's IdGlobalPool to create individual IDs. // 8 quadrillion + : used by sync model's IdGlobalPool to create individual IDs.
// //
// If you exhaust the Master Model's invididual pool at a rate of 10,000,000 IDs // If you exhaust the Master Model's invididual pool at a rate of 10,000,000 IDs
// per second, the individual pool will last for 12 years. // per second, the individual pool will last for 12 years.

View File

@@ -393,7 +393,7 @@ LuaDefine(unittests_world3diffluatab, "", "some unit tests") {
// The data in the master model should now look like this: // The data in the master model should now look like this:
const char *expect_123 = const char *expect_123 =
"<tangible 123>{ " "<tan 123>{ "
"bacon='crispy', " "bacon='crispy', "
"inventory={ gold='wealthy' }, " "inventory={ gold='wealthy' }, "
"skills={ " "skills={ "
@@ -402,7 +402,7 @@ LuaDefine(unittests_world3diffluatab, "", "some unit tests") {
"} " "} "
"}"; "}";
const char *expect_345 = const char *expect_345 =
"<tangible 345>{ " "<tan 345>{ "
"inventory={ gold='poor' }, " "inventory={ gold='poor' }, "
"phone='867-5309' " "phone='867-5309' "
"}"; "}";

View File

@@ -35,38 +35,38 @@ function unittests.tables()
end end
function unittests.vectors() function unittests.vectors()
assert(true == table.isvector{1,2,3}) assert(true == table.isarray{1,2,3})
assert(false == table.isvector{1,2,nil,3}) assert(false == table.isarray{1,2,nil,3})
-- check vector.removeall -- check vector.removeall
t = {1,2,3,4,5,1,2,3,4,5} t = {1,2,3,4,5,1,2,3,4,5}
assert(true == vector.removeall(t, 2)) assert(true == array.removeall(t, 2))
assert(table.equal(t, {1,3,4,5,1,3,4,5})) assert(table.equal(t, {1,3,4,5,1,3,4,5}))
assert(false == vector.removeall(t, 7)) assert(false == array.removeall(t, 7))
assert(table.equal(t, {1,3,4,5,1,3,4,5})) assert(table.equal(t, {1,3,4,5,1,3,4,5}))
assert(true == vector.removeall(t, 5)) assert(true == array.removeall(t, 5))
assert(table.equal(t, {1,3,4,1,3,4})) assert(table.equal(t, {1,3,4,1,3,4}))
assert(true == vector.removeall(t, 1)) assert(true == array.removeall(t, 1))
assert(table.equal(t, {3,4,3,4})) assert(table.equal(t, {3,4,3,4}))
-- check vector.push -- check vector.push
t = {} t = {}
vector.push(t, 1) array.push(t, 1)
assert(table.equal(t, {1})) assert(table.equal(t, {1}))
vector.push(t, 2) array.push(t, 2)
assert(table.equal(t, {1,2})) assert(table.equal(t, {1,2}))
vector.push(t, 3) array.push(t, 3)
assert(table.equal(t, {1,2,3})) assert(table.equal(t, {1,2,3}))
-- check vector.pop -- check vector.pop
t = {1,2,3} t = {1,2,3}
assert(3 == vector.pop(t)) assert(3 == array.pop(t))
assert(table.equal(t, {1,2})) assert(table.equal(t, {1,2}))
assert(2 == vector.pop(t)) assert(2 == array.pop(t))
assert(table.equal(t, {1})) assert(table.equal(t, {1}))
assert(1 == vector.pop(t)) assert(1 == array.pop(t))
assert(table.equal(t, {})) assert(table.equal(t, {}))
assert(nil == vector.pop(t)) assert(nil == array.pop(t))
assert(table.equal(t, {})) assert(table.equal(t, {}))
end end