Mercurial > projects > dstep
annotate dstep/objc/bridge/Capsule.d @ 24:ab33fc0c3fc1
Fixed the implementation for the methods in Capsule. Changed a method name in objc_class
author | Jacob Carlborg <doob@me.com> |
---|---|
date | Wed, 10 Feb 2010 19:24:32 +0100 |
parents | 19885b43130e |
children | b9de51448c6b |
rev | line source |
---|---|
1 | 1 /** |
2 * Copyright: Copyright (c) 2009 Jacob Carlborg. | |
3 * Authors: Jacob Carlborg | |
4 * Version: Initial created: Feb 3, 2009 | |
5 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0) | |
6 */ | |
7 module dstep.objc.bridge.Capsule; | |
8 | |
9 version (Tango) | |
10 { | |
11 import tango.core.Memory; | |
12 import tango.math.Math : log2; | |
13 | |
14 import tango.core.Traits; | |
15 } | |
16 | |
17 else | |
18 { | |
16
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
19 import GC = std.gc : addRoot; |
1 | 20 import std.math : log2; |
21 } | |
22 | |
23 import dstep.internal.String; | |
24 import dstep.objc.bridge.Bridge; | |
2
9fd439a28ce3
Adapted the scripts for the new bridge + a lot more
Jacob Carlborg <doob@me.com>
parents:
1
diff
changeset
|
25 import dstep.objc.bridge.Type; |
1 | 26 import dstep.objc.bridge.TypeEncoding; |
27 import dstep.objc.bridge.Wrapper; | |
28 import dstep.objc.message; | |
29 import dstep.objc.objc; | |
30 import dstep.objc.runtime; | |
31 import bindings = dstep.objc.bindings; | |
32 | |
16
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
33 /// Returns the capsule class |
1 | 34 Class capsuleClass () |
35 { | |
36 if (!Capsule.capsuleClass) | |
37 initCapsuleClass; | |
38 | |
39 return Capsule.capsuleClass; | |
40 } | |
41 | |
42 private struct Capsule | |
43 { | |
44 static Class capsuleClass; | |
45 | |
46 static id create (Object object, Class capsuleClass) | |
47 { | |
48 id capsule = objc.createInstance(capsuleClass, 0); | |
49 | |
50 Bridge.setDObject(object, capsule); | |
51 | |
52 return capsule; | |
53 } | |
54 | |
55 static id description (id self, SEL op) | |
56 in | |
57 { | |
58 assert(isCapsule(self)); | |
59 } | |
60 body | |
61 { | |
24
ab33fc0c3fc1
Fixed the implementation for the methods in Capsule. Changed a method name in objc_class
Jacob Carlborg <doob@me.com>
parents:
16
diff
changeset
|
62 if (auto object = decapsule!(Object)(self)) |
ab33fc0c3fc1
Fixed the implementation for the methods in Capsule. Changed a method name in objc_class
Jacob Carlborg <doob@me.com>
parents:
16
diff
changeset
|
63 return encapsuleString(object.toString); |
ab33fc0c3fc1
Fixed the implementation for the methods in Capsule. Changed a method name in objc_class
Jacob Carlborg <doob@me.com>
parents:
16
diff
changeset
|
64 |
ab33fc0c3fc1
Fixed the implementation for the methods in Capsule. Changed a method name in objc_class
Jacob Carlborg <doob@me.com>
parents:
16
diff
changeset
|
65 objc_super superObject; |
ab33fc0c3fc1
Fixed the implementation for the methods in Capsule. Changed a method name in objc_class
Jacob Carlborg <doob@me.com>
parents:
16
diff
changeset
|
66 superObject.cls = .capsuleClass.getSuperclass; |
ab33fc0c3fc1
Fixed the implementation for the methods in Capsule. Changed a method name in objc_class
Jacob Carlborg <doob@me.com>
parents:
16
diff
changeset
|
67 superObject.receiver = self; |
ab33fc0c3fc1
Fixed the implementation for the methods in Capsule. Changed a method name in objc_class
Jacob Carlborg <doob@me.com>
parents:
16
diff
changeset
|
68 |
ab33fc0c3fc1
Fixed the implementation for the methods in Capsule. Changed a method name in objc_class
Jacob Carlborg <doob@me.com>
parents:
16
diff
changeset
|
69 return Bridge.invokeObjcSuperMethod!(id, "description")(&superObject); |
1 | 70 } |
71 | |
72 static hash_t hash (id self, SEL op) | |
73 in | |
74 { | |
75 assert(isCapsule(self)); | |
76 } | |
77 body | |
78 { | |
24
ab33fc0c3fc1
Fixed the implementation for the methods in Capsule. Changed a method name in objc_class
Jacob Carlborg <doob@me.com>
parents:
16
diff
changeset
|
79 if (auto object = decapsule!(Object)(self)) |
ab33fc0c3fc1
Fixed the implementation for the methods in Capsule. Changed a method name in objc_class
Jacob Carlborg <doob@me.com>
parents:
16
diff
changeset
|
80 return object.toHash; |
ab33fc0c3fc1
Fixed the implementation for the methods in Capsule. Changed a method name in objc_class
Jacob Carlborg <doob@me.com>
parents:
16
diff
changeset
|
81 |
ab33fc0c3fc1
Fixed the implementation for the methods in Capsule. Changed a method name in objc_class
Jacob Carlborg <doob@me.com>
parents:
16
diff
changeset
|
82 objc_super superObject; |
ab33fc0c3fc1
Fixed the implementation for the methods in Capsule. Changed a method name in objc_class
Jacob Carlborg <doob@me.com>
parents:
16
diff
changeset
|
83 superObject.cls = .capsuleClass.getSuperclass; |
ab33fc0c3fc1
Fixed the implementation for the methods in Capsule. Changed a method name in objc_class
Jacob Carlborg <doob@me.com>
parents:
16
diff
changeset
|
84 superObject.receiver = self; |
ab33fc0c3fc1
Fixed the implementation for the methods in Capsule. Changed a method name in objc_class
Jacob Carlborg <doob@me.com>
parents:
16
diff
changeset
|
85 |
ab33fc0c3fc1
Fixed the implementation for the methods in Capsule. Changed a method name in objc_class
Jacob Carlborg <doob@me.com>
parents:
16
diff
changeset
|
86 return Bridge.invokeObjcSuperMethod!(hash_t, "hash")(&superObject); |
1 | 87 } |
88 | |
24
ab33fc0c3fc1
Fixed the implementation for the methods in Capsule. Changed a method name in objc_class
Jacob Carlborg <doob@me.com>
parents:
16
diff
changeset
|
89 static bool isEqual (id self, SEL op, Object other) |
1 | 90 in |
91 { | |
92 assert(isCapsule(self)); | |
93 } | |
94 body | |
95 { | |
24
ab33fc0c3fc1
Fixed the implementation for the methods in Capsule. Changed a method name in objc_class
Jacob Carlborg <doob@me.com>
parents:
16
diff
changeset
|
96 if (auto object = decapsule!(Object)(self)) |
ab33fc0c3fc1
Fixed the implementation for the methods in Capsule. Changed a method name in objc_class
Jacob Carlborg <doob@me.com>
parents:
16
diff
changeset
|
97 return cast(bool) (object == other); |
ab33fc0c3fc1
Fixed the implementation for the methods in Capsule. Changed a method name in objc_class
Jacob Carlborg <doob@me.com>
parents:
16
diff
changeset
|
98 |
ab33fc0c3fc1
Fixed the implementation for the methods in Capsule. Changed a method name in objc_class
Jacob Carlborg <doob@me.com>
parents:
16
diff
changeset
|
99 objc_super superObject; |
ab33fc0c3fc1
Fixed the implementation for the methods in Capsule. Changed a method name in objc_class
Jacob Carlborg <doob@me.com>
parents:
16
diff
changeset
|
100 superObject.cls = .capsuleClass.getSuperclass; |
ab33fc0c3fc1
Fixed the implementation for the methods in Capsule. Changed a method name in objc_class
Jacob Carlborg <doob@me.com>
parents:
16
diff
changeset
|
101 superObject.receiver = self; |
ab33fc0c3fc1
Fixed the implementation for the methods in Capsule. Changed a method name in objc_class
Jacob Carlborg <doob@me.com>
parents:
16
diff
changeset
|
102 |
ab33fc0c3fc1
Fixed the implementation for the methods in Capsule. Changed a method name in objc_class
Jacob Carlborg <doob@me.com>
parents:
16
diff
changeset
|
103 return Bridge.invokeObjcSuperMethod!(bool, "isEqual:", Object)(&superObject, other); |
1 | 104 } |
105 } | |
106 | |
107 private void initCapsuleClass () | |
108 { | |
109 Class superClass = cast(Class) objc.getClass!("NSObject"); | |
110 Capsule.capsuleClass = objc.allocateClassPair!("D_Object")(superClass, 0); | |
111 | |
112 ubyte alignment = cast(ubyte) log2(Bridge.DObjectType.sizeof); | |
16
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
113 |
1 | 114 Capsule.capsuleClass.addIvar!(Bridge.dObjectVar, encode!(Bridge.DObjectType))(Bridge.DObjectType.sizeof, alignment); |
115 | |
116 Capsule.capsuleClass.addMethod!(encodeCallable!(Capsule.description))(sel.registerName!("description"), cast(IMP) &Capsule.description); | |
117 Capsule.capsuleClass.addMethod!(encodeCallable!(Capsule.hash))(sel.registerName!("hash"), cast(IMP) &Capsule.hash); | |
118 Capsule.capsuleClass.addMethod!(encodeCallable!(Capsule.isEqual))(sel.registerName!("isEqual"), cast (IMP) &Capsule.isEqual); | |
119 | |
120 objc.registerClassPair(capsuleClass); | |
121 } | |
122 | |
16
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
123 /** |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
124 * Returns $(D_KEYWORD true) if the given Objective-C instance is a capsule |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
125 * |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
126 * Params: |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
127 * instance = the Objective-C instance |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
128 * |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
129 * Returns: $(D_KEYWORD true) if the given Objective-C instance is a capsule |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
130 */ |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
131 bool isCapsule (id instance) |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
132 { |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
133 //if (capsule && capsule.isa) |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
134 //return capsule.isa.getInstanceVariable!(Bridge.dObjectVar) !is null; |
1 | 135 |
16
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
136 if (instance) |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
137 { |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
138 Class cls = instance.isa; |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
139 |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
140 while (cls && cls !is capsuleClass) |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
141 cls = cls.super_class; |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
142 |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
143 return cls is capsuleClass; |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
144 } |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
145 |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
146 return false; |
1 | 147 } |
148 | |
16
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
149 /** |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
150 * Returns $(D_KEYWORD true) if the given Objective-C class is a capsule |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
151 * |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
152 * Params: |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
153 * cls = the Objective-C class |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
154 * |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
155 * Returns: true if the given Objective-C class is a capsule |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
156 */ |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
157 bool isCapsule (Class cls) |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
158 { |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
159 while (cls && cls !is capsuleClass) |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
160 cls = cls.super_class; |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
161 |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
162 return cls is capsuleClass; |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
163 } |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
164 |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
165 /** |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
166 * Encapsulate the value of type $(D_PARAM T) to corresponding Objective-C type $(D_PSYMBOL ObjcType!(T)) |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
167 * |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
168 * Params: |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
169 * T = the type of the value |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
170 * value = the value to encapsulate |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
171 * |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
172 * Returns: the encapsulated value |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
173 */ |
1 | 174 ObjcType!(T) encapsule (T) (T value) |
2
9fd439a28ce3
Adapted the scripts for the new bridge + a lot more
Jacob Carlborg <doob@me.com>
parents:
1
diff
changeset
|
175 { |
1 | 176 static if (needsEncapsulation!(T)) |
177 { | |
178 if (!value) | |
179 return null; | |
180 | |
181 if (auto wrapper = cast(ObjcWrapper) value) | |
182 return wrapper.objcObject; | |
183 | |
16
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
184 static if (is(T == interface)) |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
185 return Capsule.create(cast(Object) value, capsuleClass); |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
186 |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
187 return Capsule.create(cast(Object) value, capsuleClass); |
1 | 188 } |
189 | |
190 else | |
191 return value; | |
192 } | |
193 | |
16
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
194 /** |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
195 * Decapsulate the given Objective-C value of type $(D_PSYMBOL ObjcType!(T)) to corresponding D type $(D_PARAM T). |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
196 * |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
197 * Params: |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
198 * T = the type of the decapsulated value |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
199 * value = the value to decapsulate |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
200 * |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
201 * Returns: the decapsulated value |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
202 */ |
2
9fd439a28ce3
Adapted the scripts for the new bridge + a lot more
Jacob Carlborg <doob@me.com>
parents:
1
diff
changeset
|
203 T decapsule (T) (ObjcType!(T) value) |
1 | 204 { |
2
9fd439a28ce3
Adapted the scripts for the new bridge + a lot more
Jacob Carlborg <doob@me.com>
parents:
1
diff
changeset
|
205 static if (needsEncapsulation!(T)) |
16
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
206 { |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
207 static if (hasIdConstructor!(T)) |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
208 { |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
209 T instance = cast(T) Bridge.getDObject(value); |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
210 |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
211 return instance ? instance : new T(value); |
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
212 } |
2
9fd439a28ce3
Adapted the scripts for the new bridge + a lot more
Jacob Carlborg <doob@me.com>
parents:
1
diff
changeset
|
213 |
9fd439a28ce3
Adapted the scripts for the new bridge + a lot more
Jacob Carlborg <doob@me.com>
parents:
1
diff
changeset
|
214 else |
16
19885b43130e
Huge update, the bridge actually works now
Jacob Carlborg <doob@me.com>
parents:
2
diff
changeset
|
215 return cast(T) Bridge.getDObject(value); |
1 | 216 } |
2
9fd439a28ce3
Adapted the scripts for the new bridge + a lot more
Jacob Carlborg <doob@me.com>
parents:
1
diff
changeset
|
217 |
9fd439a28ce3
Adapted the scripts for the new bridge + a lot more
Jacob Carlborg <doob@me.com>
parents:
1
diff
changeset
|
218 else |
9fd439a28ce3
Adapted the scripts for the new bridge + a lot more
Jacob Carlborg <doob@me.com>
parents:
1
diff
changeset
|
219 return value; |
1 | 220 } |
221 | |
222 private id encapsuleString (string str) | |
223 { | |
224 enum { NSUTF8StringEncoding = 4 } | |
225 | |
226 return objc.getClass!("NSString").msgSend(sel.registerName!("alloc")).msgSend(sel.registerName!("initWithBytes:length:encoding:"), str.ptr, str.length, NSUTF8StringEncoding); | |
227 } |