33#include " HookSystem.h"
44
55LUA_FUNCTION (Lua_LootListConstructor) {
6- LootList* loot = nullptr ;
7- loot = lua::place<LootList>(L, lua::metatables::LootListMT);
8-
6+ // Initializes a new LootList (std::deque) under lua ownership and pushes a reference to the stack.
7+ lua::place<LootList>(L, lua::metatables::LootListMT);
98 return 1 ;
109}
1110
@@ -30,46 +29,46 @@ LUA_FUNCTION(Lua_PickupGetLootList) {
3029 Entity_Pickup* pickup = lua::GetLuabridgeUserdata<Entity_Pickup*>(L, 1 , lua::Metatables::ENTITY_PICKUP, " EntityPickup" );
3130 bool shouldAdvance = lua::luaL_optboolean (L, 2 , false );
3231
33- LootList loot = pickup->GetLootList (shouldAdvance, nullptr );
3432 LootList* toLua = (LootList*)lua_newuserdata (L, sizeof (LootList));
33+ luaL_setmetatable (L, lua::metatables::LootListMT);
34+ // Initialize a new LootList (std::deque) in the memory allocated for the userdata, using "placement new".
35+ // Using the move constructor, we can "steal" the contents of the deque returned by the function without having to copy everything.
36+ // If we just copied the raw bytes of the deque, the allocated contents would still be freed alongside the original deque.
37+ // This allows lua to properly take ownership of the deque. Destroying the deque later is handled by `Lua_LootList__gc`.
38+ new (toLua) LootList (std::move (pickup->GetLootList (shouldAdvance, nullptr )));
3539
36- luaL_setmetatable (L, lua::metatables::LootListMT);
37- memcpy (toLua, &loot, sizeof (LootList));
3840 return 1 ;
3941}
4042
4143LUA_FUNCTION (Lua_NPCGetFireplaceLoot) {
4244 auto * npc = lua::GetLuabridgeUserdata<Entity_NPC*>(L, 1 , lua::Metatables::ENTITY_NPC, " EntityNPC" );
4345 bool shouldAdvance = lua::luaL_optboolean (L, 2 , false );
4446
45- LootList loot = npc->fireplace_get_loot (shouldAdvance);
46- LootList* toLua = (LootList*)lua_newuserdata (L, sizeof (LootList));
47+ LootList* toLua = (LootList*)lua_newuserdata (L, sizeof (LootList));
48+ luaL_setmetatable (L, lua::metatables::LootListMT);
49+ new (toLua) LootList (std::move (npc->fireplace_get_loot (shouldAdvance)));
4750
48- luaL_setmetatable (L, lua::metatables::LootListMT);
49- memcpy (toLua, &loot, sizeof (LootList));
5051 return 1 ;
5152}
5253
5354LUA_FUNCTION (Lua_NPCGetShopkeeperLoot) {
5455 auto * npc = lua::GetLuabridgeUserdata<Entity_NPC*>(L, 1 , lua::Metatables::ENTITY_NPC, " EntityNPC" );
5556 bool shouldAdvance = lua::luaL_optboolean (L, 2 , false );
5657
57- LootList loot = npc->shopkeeper_get_loot (shouldAdvance);
58- LootList* toLua = (LootList*)lua_newuserdata (L, sizeof (LootList));
58+ LootList* toLua = (LootList*)lua_newuserdata (L, sizeof (LootList));
59+ luaL_setmetatable (L, lua::metatables::LootListMT);
60+ new (toLua) LootList (std::move (npc->shopkeeper_get_loot (shouldAdvance)));
5961
60- luaL_setmetatable (L, lua::metatables::LootListMT);
61- memcpy (toLua, &loot, sizeof (LootList));
6262 return 1 ;
6363}
6464
6565LUA_FUNCTION (Lua_LootListGetEntries)
6666{
6767 LootList* lootList = lua::GetRawUserdata<LootList*>(L, 1 , lua::metatables::LootListMT);
68- auto & entries = *lootList; // Assuming lootList is a std::deque<LootListEntry>
6968
7069 lua_newtable (L);
7170 int idx = 1 ;
72- for (LootListEntry& item : entries ) {
71+ for (LootListEntry& item : *lootList ) {
7372 LootListEntry** ud = (LootListEntry**)lua_newuserdata (L, sizeof (LootListEntry*));
7473 *ud = &item;
7574 luaL_setmetatable (L, lua::metatables::LootListEntryMT);
@@ -80,13 +79,12 @@ LUA_FUNCTION(Lua_LootListGetEntries)
8079 return 1 ;
8180}
8281
83- /* LUA_FUNCTION(Lua_LootList__gc) {
84- LootList* lootlist = lua::GetRawUserdata<LootList*>(L, 1, lua::metatables::LootListMT);
85- lootlist->~LootList();
86-
82+ LUA_FUNCTION (Lua_LootList__gc) {
83+ if ( LootList* lootlist = lua::GetRawUserdata<LootList*>(L, 1 , lua::metatables::LootListMT)) {
84+ lootlist->~LootList ();
85+ }
8786 return 0 ;
8887}
89- */
9088
9189static void RegisterLootList (lua_State* L) {
9290
@@ -100,7 +98,7 @@ static void RegisterLootList(lua_State* L) {
10098 { " PushEntry" , Lua_LootListPushEntry },
10199 { NULL , NULL }
102100 };
103- lua::RegisterNewClass (L, lua::metatables::LootListMT, lua::metatables::LootListMT, functions);
101+ lua::RegisterNewClass (L, lua::metatables::LootListMT, lua::metatables::LootListMT, functions, Lua_LootList__gc );
104102 lua_register (L, lua::metatables::LootListMT, Lua_LootListConstructor);
105103}
106104
0 commit comments