1
1
#pragma once
2
2
3
- #include < string.h>
4
- #include < assert.h>
3
+ #ifndef __SCITER_OM_H__
4
+ #define __SCITER_OM_H__
5
+
5
6
6
7
struct som_passport_t ;
7
8
8
9
typedef UINT64 som_atom_t ;
9
10
10
-
11
- struct som_asset_class_t ;
12
-
13
11
typedef struct som_asset_t {
14
12
struct som_asset_class_t * isa;
15
13
} som_asset_t ;
16
14
17
- struct som_asset_class_t {
15
+ typedef struct som_asset_class_t {
18
16
long (*asset_add_ref)(som_asset_t * thing);
19
17
long (*asset_release)(som_asset_t * thing);
20
18
long (*asset_get_interface)(som_asset_t * thing, const char * name, void ** out);
21
19
struct som_passport_t * (*asset_get_passport)(som_asset_t * thing);
22
- };
20
+ } som_asset_class_t ;
21
+
22
+ inline struct som_asset_class_t * som_asset_get_class (const struct som_asset_t * pass)
23
+ {
24
+ #ifdef __cplusplus
25
+ return pass ? pass->isa : nullptr ;
26
+ #else
27
+ return pass ? pass->isa : NULL ;
28
+ #endif
29
+ }
23
30
31
+ som_atom_t SCAPI SciterAtomValue (const char * name);
24
32
25
33
#ifdef CPP11
26
34
35
+ #include < cstring>
36
+ #include < cassert>
27
37
#include < atomic>
28
38
29
39
namespace sciter {
30
40
41
+ class atom {
42
+ som_atom_t _atom;
43
+ public:
44
+ atom (const char * name) { _atom = SciterAtomValue (name); }
45
+ atom (const atom& other) { _atom = other._atom ; }
46
+ operator som_atom_t () const { return _atom; }
47
+ };
48
+
31
49
namespace om {
32
50
33
51
template <class R > class hasset ;
34
52
53
+ // implementation of som_asset_t ISA
54
+ // note: does not define asset_add_ref()/asset_release() as they shall be defined in specializations
35
55
template <class A >
36
56
class iasset : public som_asset_t
37
57
{
@@ -47,8 +67,8 @@ namespace sciter {
47
67
if (out) { this ->asset_add_ref (); *out = this ; }
48
68
return true ;
49
69
}
50
- virtual som_passport_t * asset_get_passport () const {
51
- return nullptr ;
70
+ virtual som_passport_t * asset_get_passport () const {
71
+ return nullptr ;
52
72
}
53
73
54
74
static som_asset_class_t * get_asset_class () {
@@ -69,8 +89,7 @@ namespace sciter {
69
89
static const char * interface_name () { return " asset.sciter.com" ; }
70
90
// template<class C> hasset<C> interface_of() { hasset<C> p; get_interface(C::interface_name(), p.target()); return p; }
71
91
};
72
-
73
-
92
+
74
93
inline long asset_add_ref (som_asset_t *ptr) {
75
94
assert (ptr);
76
95
assert (ptr->isa );
@@ -89,16 +108,21 @@ namespace sciter {
89
108
assert (ptr->isa ->asset_get_interface );
90
109
return ptr->isa ->asset_get_interface (ptr, name, out);
91
110
}
92
-
111
+
93
112
inline som_passport_t * asset_get_passport (som_asset_t *ptr) {
94
113
assert (ptr);
95
114
assert (ptr->isa );
96
115
assert (ptr->isa ->asset_get_passport );
97
116
return ptr->isa ->asset_get_passport (ptr);
98
117
}
99
118
119
+ inline som_asset_class_t * asset_get_class (som_asset_t *ptr) {
120
+ assert (ptr);
121
+ return ptr->isa ;
122
+ }
123
+
100
124
// hasset - yet another shared_ptr
101
- // R here is something derived from the iasset (om::iasset) above
125
+ // R here is an entity derived from som_asset_t
102
126
template <class R > class hasset
103
127
{
104
128
protected:
@@ -108,10 +132,10 @@ namespace sciter {
108
132
typedef R asset_t ;
109
133
110
134
hasset () :p(nullptr ) {}
111
- hasset (R* lp) :p(nullptr ) { if (lp) (p = lp)-> asset_add_ref ( ); }
112
- hasset (const hasset<R>& cp) :p(nullptr ) { if (cp.p ) (p = cp.p )-> asset_add_ref ( ); }
135
+ hasset (R* lp) :p(nullptr ) { if (lp) asset_add_ref (p = lp); }
136
+ hasset (const hasset<R>& cp) :p(nullptr ) { if (cp.p ) asset_add_ref (p = cp.p ); }
113
137
114
- ~hasset () { if (p) p-> asset_release (); }
138
+ ~hasset () { if (p) asset_release (p ); }
115
139
operator R*() const { return p; }
116
140
R* operator ->() const { assert (p != 0 ); return p; }
117
141
@@ -121,7 +145,7 @@ namespace sciter {
121
145
bool operator ==(R* pR) const { return p == pR; }
122
146
123
147
// release the interface and set it to NULL
124
- void release () { if (p) { R* pt = p; p = 0 ; pt-> asset_release (); } }
148
+ void release () { if (p) { R* pt = p; p = 0 ; asset_release (pt ); } }
125
149
126
150
// attach to an existing interface (does not AddRef)
127
151
void attach (R* p2) { asset_release (p); p = p2; }
@@ -130,8 +154,8 @@ namespace sciter {
130
154
131
155
static R* assign (R* &pp, R* lp)
132
156
{
133
- if (lp != 0 ) lp-> asset_add_ref ();
134
- if (pp) pp-> asset_release ();
157
+ if (lp != 0 ) asset_add_ref (lp );
158
+ if (pp) asset_release (pp );
135
159
pp = lp;
136
160
return lp;
137
161
}
@@ -142,11 +166,9 @@ namespace sciter {
142
166
void ** target () { release (); return (void **)&p; }
143
167
144
168
};
145
-
146
-
147
- // intrusive add_ref/release counter
148
-
149
- template <class C >
169
+
170
+ // reference counted asset, uses intrusive add_ref/release counter
171
+ template <class C >
150
172
class asset : public iasset <asset<C>>
151
173
{
152
174
std::atomic<long > _ref_cntr;
@@ -179,11 +201,20 @@ namespace sciter {
179
201
delete static_cast <C*>(this );
180
202
}
181
203
};
204
+ }
182
205
183
-
206
+ template <class AT >
207
+ inline AT* value::get_asset () const {
208
+ som_asset_t * pass = get_asset ();
209
+ if (pass && (som_asset_get_class (pass) == AT::get_asset_class ()))
210
+ return static_cast <AT*>(pass);
211
+ return nullptr ;
184
212
}
213
+
185
214
}
186
215
187
216
#endif
188
217
189
218
#include " sciter-om-def.h"
219
+
220
+ #endif
0 commit comments