Add a pass-through renderer plugin
t5deRenderEngine.dll implements IMVU Classic's renderer plugin interface by wrapping IMVU's own OpenGL renderer, and logs what each frame calls, to prove our declarations of the interface. Built with CMake presets for 32-bit MSVC; docs/interface.md has the findings. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
commit
dc643d271b
16 files changed
+1037
No files matched your search
@@ -0,0 +1,74 @@
|
||||
// SharedPtr's reference counting, and its layout: IMVU's DLLs read and write these fields directly.
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
|
||||
#include "t5de/imvu/shared_ptr.hpp"
|
||||
|
||||
using t5de::imvu::SharedPtr;
|
||||
|
||||
namespace {
|
||||
|
||||
int failures = 0;
|
||||
|
||||
void check(bool ok, const char* what)
|
||||
{
|
||||
if (!ok) {
|
||||
std::printf("FAIL: %s\n", what);
|
||||
++failures;
|
||||
}
|
||||
}
|
||||
|
||||
struct Base {
|
||||
virtual ~Base() = default;
|
||||
};
|
||||
|
||||
struct Tracked : Base {
|
||||
explicit Tracked(int& alive) : alive_(alive) { ++alive_; }
|
||||
~Tracked() override { --alive_; }
|
||||
int& alive_;
|
||||
};
|
||||
|
||||
// What boost's control block looks like from IMVU's side: a vtable pointer, then the counts.
|
||||
struct BoostCounts {
|
||||
void* vtable;
|
||||
long use;
|
||||
long weak;
|
||||
};
|
||||
|
||||
const BoostCounts& counts_of(const void* shared)
|
||||
{
|
||||
return **static_cast<BoostCounts* const*>(static_cast<const void*>(static_cast<const char*>(shared) + 4));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main()
|
||||
{
|
||||
int alive = 0;
|
||||
{
|
||||
SharedPtr<Tracked> a(std::make_unique<Tracked>(alive));
|
||||
check(alive == 1 && a.use_count() == 1, "created");
|
||||
check(counts_of(&a).use == 1 && counts_of(&a).weak == 1, "boost layout: counts after the vtable pointer");
|
||||
{
|
||||
SharedPtr<Tracked> b = a;
|
||||
check(a.use_count() == 2 && counts_of(&a).use == 2, "copy shares");
|
||||
SharedPtr<Base> base = b;
|
||||
check(a.use_count() == 3, "converted copy shares");
|
||||
SharedPtr<Base> moved = std::move(base);
|
||||
check(a.use_count() == 3 && !base, "move transfers");
|
||||
}
|
||||
check(alive == 1 && a.use_count() == 1, "copies released");
|
||||
}
|
||||
check(alive == 0, "last owner deletes");
|
||||
|
||||
SharedPtr<Tracked> empty;
|
||||
check(!empty && empty.use_count() == 0, "empty");
|
||||
check(sizeof(SharedPtr<Tracked>) == 8, "two pointers");
|
||||
|
||||
if (failures == 0) {
|
||||
std::printf("ok\n");
|
||||
}
|
||||
return failures == 0 ? 0 : 1;
|
||||
}
|
||||
Reference in new issue
Block a user