Change: [Script] Automate the ScriptObject reference counting

pull/491/head
Rubidium 1 year ago committed by Loïc Guilloux
parent a1fc4d5c0e
commit 728973859d

@ -21,6 +21,8 @@
#include "../script_suspend.hpp"
#include "../squirrel.hpp"
#include <utility>
/**
* The callback function for Mode-classes.
*/
@ -367,4 +369,68 @@ bool ScriptObject::ScriptDoCommandHelper<Tcmd, Tret(*)(DoCommandFlag, Targs...)>
}
}
/**
* Internally used class to automate the ScriptObject reference counting.
* @api -all
*/
template <typename T>
class ScriptObjectRef {
private:
T *data; ///< The reference counted object.
public:
/**
* Create the reference counter for the given ScriptObject instance.
* @param data The underlying object.
*/
ScriptObjectRef(T *data) : data(data)
{
this->data->AddRef();
}
/* No copy constructor. */
ScriptObjectRef(const ScriptObjectRef<T> &ref) = delete;
/* Move constructor. */
ScriptObjectRef(ScriptObjectRef<T> &&ref) noexcept : data(std::exchange(ref.data, nullptr))
{
}
/* No copy assignment. */
ScriptObjectRef& operator=(const ScriptObjectRef<T> &other) = delete;
/* Move assignment. */
ScriptObjectRef& operator=(ScriptObjectRef<T> &&other) noexcept
{
std::swap(this->data, other.data);
return *this;
}
/**
* Release the reference counted object.
*/
~ScriptObjectRef()
{
if (this->data != nullptr) this->data->Release();
}
/**
* Dereferencing this reference returns a reference to the reference
* counted object
* @return Reference to the underlying object.
*/
T &operator*()
{
return *this->data;
}
/**
* The arrow operator on this reference returns the reference counted object.
* @return Pointer to the underlying object.
*/
T *operator->()
{
return this->data;
}
};
#endif /* SCRIPT_OBJECT_HPP */

@ -53,19 +53,10 @@ ScriptText::ScriptText(HSQUIRRELVM vm) :
}
}
ScriptText::~ScriptText()
{
for (int i = 0; i < SCRIPT_TEXT_MAX_PARAMETERS; i++) {
if (std::holds_alternative<ScriptText *>(this->param[i])) std::get<ScriptText *>(this->param[i])->Release();
}
}
SQInteger ScriptText::_SetParam(int parameter, HSQUIRRELVM vm)
{
if (parameter >= SCRIPT_TEXT_MAX_PARAMETERS) return SQ_ERROR;
if (std::holds_alternative<ScriptText *>(this->param[parameter])) std::get<ScriptText *>(this->param[parameter])->Release();
switch (sq_gettype(vm, -1)) {
case OT_STRING: {
const SQChar *value;
@ -102,8 +93,7 @@ SQInteger ScriptText::_SetParam(int parameter, HSQUIRRELVM vm)
if (real_instance == nullptr) return SQ_ERROR;
ScriptText *value = static_cast<ScriptText *>(real_instance);
value->AddRef();
this->param[parameter] = value;
this->param[parameter] = ScriptTextRef(value);
break;
}
@ -184,9 +174,9 @@ char *ScriptText::_GetEncodedText(char *p, char *lastofp, int &param_count)
param_count++;
continue;
}
if (std::holds_alternative<ScriptText *>(this->param[i])) {
if (std::holds_alternative<ScriptTextRef>(this->param[i])) {
p += seprintf(p, lastofp, ":");
p = std::get<ScriptText *>(this->param[i])->_GetEncodedText(p, lastofp, param_count);
p = std::get<ScriptTextRef>(this->param[i])->_GetEncodedText(p, lastofp, param_count);
continue;
}
p += seprintf(p, lastofp, ":" OTTD_PRINTFHEX64, std::get<SQInteger>(this->param[i]));

@ -90,7 +90,6 @@ public:
*/
ScriptText(StringID string, ...);
#endif /* DOXYGEN_API */
~ScriptText();
#ifndef DOXYGEN_API
/**
@ -129,8 +128,10 @@ public:
virtual const std::string GetEncodedText();
private:
using ScriptTextRef = ScriptObjectRef<ScriptText>;
StringID string;
std::variant<SQInteger, std::string, ScriptText *> param[SCRIPT_TEXT_MAX_PARAMETERS];
std::variant<SQInteger, std::string, ScriptTextRef> param[SCRIPT_TEXT_MAX_PARAMETERS];
int paramc;
/**

Loading…
Cancel
Save