mirror of
https://github.com/edo9300/ygopro-core
synced 2026-08-25 16:23:07 -04:00
No longer manage a Group's lifetime explicitly in native code, but instead leverage Lua's garbage collector to handle it's lifetime. In this change, Groups will be stored internally in the core inside a weak table, so that they will still be reference-able when needed, but if no reference were to exist in Lua code, they will be subject to garbage collection. Whenever a Group is used by native code, its wrapped by a owned_lua template class, this is akin to std::shared_ptr--It reference counts the usages of that group internally in the core, including managing it in the Lua registry index when in use, so that it won't be collected. With this approach, the exponential memory usage growth caused by long running procedures due to the creation hundredths of thousands of groups per iteration, is mitigated, since the temporary groups will be reaped more frequently, as opposed to the old approach of them being cleared only after the topmost Lua function had finished executing. For now a single GC step is triggered whenever the total number of groups is more than 2048--an arbitrary value that seems to work well enough, but which can be changed/optimized after proper profiling. A major upgrade with this approach is the removal of the concept of Groups "kept alive" and having to "explicitly delete" them to make them outlive a Lua function execution, since they will now follow Lua's variables lifetime properly.
46 lines
1.4 KiB
C++
46 lines
1.4 KiB
C++
/*
|
|
* Copyright (c) 2010-2015, Argon Sun (Fluorohydride)
|
|
* Copyright (c) 2019-2025, Edoardo Lolletti (edo9300) <edoardo762@gmail.com>
|
|
*
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
*/
|
|
#ifndef GROUP_H_
|
|
#define GROUP_H_
|
|
|
|
#include <set>
|
|
#include <vector>
|
|
#include "common.h"
|
|
#include "containers_fwd.h"
|
|
#include "lua_obj.h"
|
|
|
|
class card;
|
|
class duel;
|
|
|
|
class group : public lua_obj_helper<LuaParam::GROUP> {
|
|
public:
|
|
card_set container;
|
|
card_set::iterator it;
|
|
bool is_readonly{ false };
|
|
bool is_iterator_dirty{ true };
|
|
|
|
bool has_card(card* c) const {
|
|
return container.find(c) != container.end();
|
|
}
|
|
|
|
explicit group(duel* pd) : lua_obj_helper(pd) {}
|
|
group(duel* pd, card* pcard) : lua_obj_helper(pd), container({ pcard }) {}
|
|
group(duel* pd, card_set cset) : lua_obj_helper(pd), container(std::move(cset)) {}
|
|
group(duel* pd, group* pgroup) : group(pd, pgroup->container) {}
|
|
template<typename Iter>
|
|
group(duel* pd, const Iter begin, const Iter end) : lua_obj_helper(pd), container(begin, end) {}
|
|
group(duel* pd, const std::vector<card*>& vcard) : group(pd, vcard.begin(), vcard.end()) {}
|
|
group(duel* pd, lua_obj* pobj) : lua_obj_helper(pd) {
|
|
if(pobj->lua_type == LuaParam::CARD)
|
|
container.insert(reinterpret_cast<card*>(pobj));
|
|
else if(pobj->lua_type == LuaParam::GROUP)
|
|
container = reinterpret_cast<group*>(pobj)->container;
|
|
}
|
|
~group() = default;
|
|
};
|
|
|
|
#endif /* GROUP_H_ */
|