1 /**
2     Internal Implementation Details.
3 
4     You should not import this, as it does not expose any
5     API outside outside of the nulib library.
6 
7     Copyright:
8         Copyright © 2023-2025, Kitsunebi Games
9         Copyright © 2023-2025, Inochi2D Project
10     
11     License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
12     Authors:   Luna Nielsen
13 */
14 module nulib.memory.internal;
15 import numem.core.traits;
16 import numem;
17 
18 package(nulib.memory):
19 
20 /**
21     Container for refcounted memory.
22 */
23 struct __refcount_t(T) {
24 @nogc:
25     alias SelfType = typeof(this);
26     alias SelfTypeRef = SelfType*;
27 
28     SelfTypeRef self;
29     Ref!T ptr;
30 
31     size_t strongrefs;
32     size_t weakrefs;
33 
34     // Debug utils for unit testing.
35     version(unittest) {
36         void* userdata;
37         void function(void* userdata) onDeleted;
38     }
39 
40     ~this() {
41         ptr = null;
42         self = null;
43 
44         version(unittest) {
45             if (onDeleted) {
46                 onDeleted(userdata);
47                 onDeleted = null;
48             }
49         }
50     }
51 
52     void retain(bool strong)() @trusted {
53         static if (strong)
54             strongrefs++;
55         else
56             weakrefs++;
57     }
58 
59     void release(bool strong)() @trusted {
60         static if (strong)
61             strongrefs--;
62         else
63             weakrefs--;
64 
65         if (strongrefs == 0) {
66             if (ptr)
67                 nogc_delete(ptr);
68         
69             if (weakrefs == 0 && self)
70                 nogc_delete(self);
71         }
72     }
73 
74     static SelfTypeRef createNew(Ref!T ptr) @trusted {
75         SelfTypeRef selfptr = nogc_new!(SelfType);
76 
77         selfptr.self = selfptr;
78         selfptr.ptr = ptr;
79         selfptr.strongrefs = 1;
80         return selfptr;
81     }
82 
83     ref Ref!T get() @trusted nothrow {
84         static if (is(Ref!T == T))
85             return ptr;
86         else
87             return *ptr;
88     }
89 }