inkcpp
Loading...
Searching...
No Matches
story_ptr.h
1/* Copyright (c) 2024 Julian Benda
2 *
3 * This file is part of inkCPP which is released under MIT license.
4 * See file LICENSE.txt or go to
5 * https://github.com/JBenda/inkcpp for full license details.
6 */
7#pragma once
8
9#include "system.h"
10
11namespace ink::runtime
12{
13namespace internal
14{
16 struct ref_block {
17 ref_block()
18 : references(0)
19 , valid(true)
20 {
21 }
22
23 size_t references;
24 bool valid;
25
26 static void remove_reference(ref_block*&);
27 };
28
30 class story_ptr_base
31 {
32 protected:
34 story_ptr_base(internal::ref_block* story);
36 story_ptr_base(internal::ref_block* story, internal::ref_block* instance);
38 story_ptr_base(const story_ptr_base&);
39
40 story_ptr_base& operator=(const story_ptr_base&) = delete;
41
43 void add_reference();
47 bool remove_reference();
48
50 void set(const story_ptr_base& other);
51
53 inline bool is_valid() const
54 {
55 return _story_block != nullptr && _instance_block != nullptr && _story_block->valid
56 && _instance_block->valid;
57 }
58
60 inline bool is_story_valid() const { return _story_block != nullptr && _story_block->valid; }
61
62 private:
63 // reference block for the parent story
64 ref_block* _story_block;
65
66 // reference block for this pointer
67 ref_block* _instance_block;
68 };
69} // namespace internal
70
83template<typename T>
84class story_ptr : public internal::story_ptr_base
85{
86public:
90 story_ptr(T* ptr, internal::ref_block* story)
91 : story_ptr_base(story)
92 , _ptr(ptr)
93 {
94 add_reference();
95 }
96
100 template<typename U>
101 story_ptr(T* ptr, const story_ptr<U>& other)
102 : story_ptr_base(other)
103 , _ptr(ptr)
104 {
105 add_reference();
106 }
107
111 story_ptr(T* ptr)
112 : story_ptr_base(nullptr, nullptr)
113 , _ptr(nullptr)
114 {
115 inkAssert(ptr == nullptr, "can not create story_ptr from existing pointer!");
116 }
117
118 // null constructor
119 story_ptr()
120 : story_ptr_base(nullptr, nullptr)
121 , _ptr(nullptr)
122 {
123 }
124
125 // destructor
126 ~story_ptr();
127
128 // == copy methods ==
132 story_ptr(const story_ptr<T>& oth);
136 story_ptr<T>& operator=(const story_ptr<T>& oth);
137
138 // == casting ==
142 template<typename U>
144 {
145 // if cast fails, return null
146#ifdef INK_ENABLE_UNREAL
147 // Unreal disables RTTI
148 U* casted = reinterpret_cast<U*>(_ptr);
149#else
150 U* casted = dynamic_cast<U*>(_ptr);
151#endif
152 if (casted == nullptr)
153 return nullptr;
154
155 // create new pointer with casted value but same instance blocks
156 return story_ptr<U>(casted, *this);
157 }
158
159 // == equality ==
161 inline bool operator==(const story_ptr<T>& other) { return _ptr == other._ptr; }
162
163 // == validity ==
165 bool is_valid() const { return story_ptr_base::is_valid() && _ptr; }
166
168 inline operator bool() const { return is_valid(); }
169
170 // === dereference operators ==
174 inline T* get() { return is_valid() ? _ptr : nullptr; }
175
179 inline const T* get() const { return is_valid() ? _ptr : nullptr; }
180
182 inline T* operator->() { return get(); }
183
185 inline const T* operator->() const { return get(); }
186
188 inline T& operator*() { return *get(); }
189
191 inline const T& operator*() const { return *get(); }
192
193private:
194 T* _ptr;
195};
196
197template<typename T>
198story_ptr<T>::~story_ptr()
199{
200 if (remove_reference()) {
201 delete _ptr;
202 _ptr = nullptr;
203 }
204}
205
206template<typename T>
208 : story_ptr_base(other)
209 , _ptr(other._ptr)
210{
211 add_reference();
212}
213
214template<typename T>
216{
217 // Clear out any old data
218 if (remove_reference()) {
219 delete _ptr;
220 _ptr = nullptr;
221 }
222
223 // Set pointers
224 set(other);
225 _ptr = other._ptr;
226
227 // initialize
228 add_reference();
229
230 // return reference to self
231 return *this;
232}
233} // namespace ink::runtime
Pointer wrapper to an object whose lifetime is tied to a story object.
Definition story_ptr.h:85
const T * get() const
access value as ptr
Definition story_ptr.h:179
T * get()
access value as ptr
Definition story_ptr.h:174
bool operator==(const story_ptr< T > &other)
implement operator==
Definition story_ptr.h:161
T * operator->()
implement operator->
Definition story_ptr.h:182
story_ptr(T *ptr)
pointer constructor.
Definition story_ptr.h:111
bool is_valid() const
checks if optional contains a value
Definition story_ptr.h:165
story_ptr< U > cast()
pointer cast while keeping ref count
Definition story_ptr.h:143
T & operator*()
implement operator*
Definition story_ptr.h:188
const T & operator*() const
implement operator*
Definition story_ptr.h:191
story_ptr< T > & operator=(const story_ptr< T > &oth)
copy assigment operator
Definition story_ptr.h:215
const T * operator->() const
implement operator->
Definition story_ptr.h:185
A loaded ink story.
Definition story.h:26
Contaning all modules and classes used for the inkles ink runtime.
Definition choice.h:13