Rigs of Rods 2026.01
Soft-body Physics Simulation
Loading...
Searching...
No Matches
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
26template<class T> class RefCountingObject
27{
28public:
33
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++;
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;
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/*
109MIT License
110
111Copyright (c) 2022 Petr OhlĂ­dal
112
113Permission is hereby granted, free of charge, to any person obtaining a copy
114of this software and associated documentation files (the "Software"), to deal
115in the Software without restriction, including without limitation the rights
116to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
117copies of the Software, and to permit persons to whom the Software is
118furnished to do so, subject to the following conditions:
119
120The above copyright notice and this permission notice shall be included in all
121copies or substantial portions of the Software.
122
123THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
124IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
125FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
126AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
127LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
128OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
129SOFTWARE.
130*/
System integration layer; inspired by OgreBites::ApplicationContext.
Central state/object manager and communications hub.
#define RefCoutingObject_DEBUGTRACE()
#define RefCountingObject_ASSERT(_Expr_)
Self reference-counting objects, as requred by AngelScript garbage collector.
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...
static void RegisterRefCountingObject(AS_NAMESPACE_QUALIFIER asIScriptEngine *engine, const char *name)
static void ReleaseGeneric(AS_NAMESPACE_QUALIFIER asIScriptGeneric *gen)
static void AddRefGeneric(AS_NAMESPACE_QUALIFIER asIScriptGeneric *gen)
AppContext * GetAppContext()