Rigs of Rods
2026.01
Soft-body Physics Simulation
Main Page
Related Pages
Topics
Namespaces
Data Structures
Files
File List
Globals
Loading...
Searching...
No Matches
source
main
utils
memory
RefCountingObject.h
Go to the documentation of this file.
1
2
// RefCountingObject system for AngelScript
3
// Copyright (c) 2022 Petr Ohlidal
4
// https://github.com/only-a-ptr/RefCountingObject-AngelScript
5
// See license (MIT) at the bottom of this file.
6
7
#pragma once
8
9
#include <angelscript.h>
10
11
#include <mutex>
// Against accidental threaded access
12
#include "
Application.h
"
// Provides access to AppContext
13
#include "
AppContext.h
"
// Stores main thread ID for debug checking
14
15
16
#if !defined(RefCoutingObject_DEBUGTRACE)
17
# define RefCoutingObject_DEBUGTRACE()
18
#endif
19
20
#if !defined(RefCountingObject_ASSERT)
21
# include <cassert>
22
# define RefCountingObject_ASSERT(_Expr_) assert(_Expr_)
23
#endif
24
26
template
<
class
T>
class
RefCountingObject
27
{
28
public
:
29
RefCountingObject
()
30
{
31
RefCoutingObject_DEBUGTRACE
();
32
}
33
34
virtual
~RefCountingObject
()
35
{
36
RefCoutingObject_DEBUGTRACE
();
37
}
38
39
void
AddRef
()
40
{
41
// Detect and prevent accidental threaded access.
42
RefCountingObject_ASSERT
(
RoR::App::GetAppContext
()->GetMainThreadID() == std::this_thread::get_id());
43
std::unique_lock<std::mutex> lock(
m_refcount_mtx
);
44
m_refcount
++;
45
RefCoutingObject_DEBUGTRACE
();
46
}
47
48
void
Release
()
49
{
50
// Detect and prevent accidental threaded access.
51
RefCountingObject_ASSERT
(
RoR::App::GetAppContext
()->GetMainThreadID() == std::this_thread::get_id());
52
int
nw_refcount = -1;
53
{
54
std::unique_lock<std::mutex> lock(
m_refcount_mtx
);
55
m_refcount
--;
56
nw_refcount =
m_refcount
;
57
RefCoutingObject_DEBUGTRACE
();
58
}
59
if
(nw_refcount == 0)
60
{
61
// commit suicide! This is legit in C++, but you must completely 100% positively read https://isocpp.org/wiki/faq/freestore-mgmt#delete-this
62
// to correctly invoke destructor, we must cast to wrapped type!
63
delete
static_cast<
T*
>
(
this
);
64
}
65
}
66
67
static
void
RegisterRefCountingObject
(AS_NAMESPACE_QUALIFIER asIScriptEngine* engine,
const
char
* name)
68
{
69
int
r;
70
71
#if defined(AS_USE_NAMESPACE)
72
using namespace
AngelScript;
73
#endif
74
75
// Registering the reference type
76
r = engine->RegisterObjectType(name, 0, asOBJ_REF);
RefCountingObject_ASSERT
( r >= 0 );
77
78
// Registering the addref/release behaviours
79
r = engine->RegisterObjectBehaviour(name, asBEHAVE_ADDREF,
"void f()"
, asMETHOD(T,
AddRef
), asCALL_THISCALL);
RefCountingObject_ASSERT
( r >= 0 );
80
r = engine->RegisterObjectBehaviour(name, asBEHAVE_RELEASE,
"void f()"
, asMETHOD(T,
Release
), asCALL_THISCALL);
RefCountingObject_ASSERT
( r >= 0 );
81
}
82
84
static
void
RegisterRefCountingObjectGeneric
(AS_NAMESPACE_QUALIFIER asIScriptEngine* engine,
const
char
* name)
85
{
86
int
r;
87
88
#if defined(AS_USE_NAMESPACE)
89
using namespace
AngelScript;
90
#endif
91
92
// Registering the reference type
93
r = engine->RegisterObjectType(name, 0, asOBJ_REF);
RefCountingObject_ASSERT
( r >= 0 );
94
95
// Registering the addref/release behaviours
96
r = engine->RegisterObjectBehaviour(name, asBEHAVE_ADDREF,
"void f()"
, asFUNCTION(
AddRefGeneric
), asCALL_GENERIC);
RefCountingObject_ASSERT
( r >= 0 );
97
r = engine->RegisterObjectBehaviour(name, asBEHAVE_RELEASE,
"void f()"
, asFUNCTION(
ReleaseGeneric
), asCALL_GENERIC);
RefCountingObject_ASSERT
( r >= 0 );
98
}
99
100
// Generic calling convention wrappers, to be invoked by AngelScript only!
101
static
void
AddRefGeneric
(AS_NAMESPACE_QUALIFIER asIScriptGeneric* gen) {
static_cast<
T*
>
(gen->GetObject())->
AddRef
(); }
102
static
void
ReleaseGeneric
(AS_NAMESPACE_QUALIFIER asIScriptGeneric* gen) {
static_cast<
T*
>
(gen->GetObject())->
Release
(); }
103
104
int
m_refcount
= 0;
105
std::mutex
m_refcount_mtx
;
// Against accidental threaded access
106
};
107
108
/*
109
MIT License
110
111
Copyright (c) 2022 Petr OhlĂdal
112
113
Permission is hereby granted, free of charge, to any person obtaining a copy
114
of this software and associated documentation files (the "Software"), to deal
115
in the Software without restriction, including without limitation the rights
116
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
117
copies of the Software, and to permit persons to whom the Software is
118
furnished to do so, subject to the following conditions:
119
120
The above copyright notice and this permission notice shall be included in all
121
copies or substantial portions of the Software.
122
123
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
124
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
125
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
126
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
127
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
128
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
129
SOFTWARE.
130
*/
AppContext.h
System integration layer; inspired by OgreBites::ApplicationContext.
Application.h
Central state/object manager and communications hub.
RefCoutingObject_DEBUGTRACE
#define RefCoutingObject_DEBUGTRACE()
Definition
RefCountingObject.h:17
RefCountingObject_ASSERT
#define RefCountingObject_ASSERT(_Expr_)
Definition
RefCountingObject.h:22
RefCountingObject
Self reference-counting objects, as requred by AngelScript garbage collector.
Definition
RefCountingObject.h:27
RefCountingObject::m_refcount
int m_refcount
Definition
RefCountingObject.h:104
RefCountingObject::~RefCountingObject
virtual ~RefCountingObject()
Definition
RefCountingObject.h:34
RefCountingObject::RefCountingObject
RefCountingObject()
Definition
RefCountingObject.h:29
RefCountingObject::AddRef
void AddRef()
Definition
RefCountingObject.h:39
RefCountingObject::m_refcount_mtx
std::mutex m_refcount_mtx
Definition
RefCountingObject.h:105
RefCountingObject::RegisterRefCountingObjectGeneric
static void RegisterRefCountingObjectGeneric(AS_NAMESPACE_QUALIFIER asIScriptEngine *engine, const char *name)
Same as RegisterRefCountingObject() but uses the generic calling convention (for platforms with AS_MA...
Definition
RefCountingObject.h:84
RefCountingObject::Release
void Release()
Definition
RefCountingObject.h:48
RefCountingObject::RegisterRefCountingObject
static void RegisterRefCountingObject(AS_NAMESPACE_QUALIFIER asIScriptEngine *engine, const char *name)
Definition
RefCountingObject.h:67
RefCountingObject::ReleaseGeneric
static void ReleaseGeneric(AS_NAMESPACE_QUALIFIER asIScriptGeneric *gen)
Definition
RefCountingObject.h:102
RefCountingObject::AddRefGeneric
static void AddRefGeneric(AS_NAMESPACE_QUALIFIER asIScriptGeneric *gen)
Definition
RefCountingObject.h:101
RoR::App::GetAppContext
AppContext * GetAppContext()
Definition
Application.cpp:297
Generated on Sun Oct 18 2026 08:40:12 for Rigs of Rods by
1.9.8