comparison dstep/objc/bridge/Capsule.d @ 16:19885b43130e

Huge update, the bridge actually works now
author Jacob Carlborg <doob@me.com>
date Sun, 03 Jan 2010 22:06:11 +0100
parents 9fd439a28ce3
children ab33fc0c3fc1
comparison
equal deleted inserted replaced
15:7ff919f595d5 16:19885b43130e
9 version (Tango) 9 version (Tango)
10 { 10 {
11 import tango.core.Memory; 11 import tango.core.Memory;
12 import tango.math.Math : log2; 12 import tango.math.Math : log2;
13 13
14 alias GC.addRoot addRoot;
15
16 import tango.core.Traits; 14 import tango.core.Traits;
17 } 15 }
18 16
19 else 17 else
20 { 18 {
21 import std.gc : addRoot; 19 import GC = std.gc : addRoot;
22 import std.math : log2; 20 import std.math : log2;
23 } 21 }
24 22
25 import dstep.internal.String; 23 import dstep.internal.String;
26 import dstep.objc.bridge.Bridge; 24 import dstep.objc.bridge.Bridge;
30 import dstep.objc.message; 28 import dstep.objc.message;
31 import dstep.objc.objc; 29 import dstep.objc.objc;
32 import dstep.objc.runtime; 30 import dstep.objc.runtime;
33 import bindings = dstep.objc.bindings; 31 import bindings = dstep.objc.bindings;
34 32
35 import mambo.io; 33 /// Returns the capsule class
36
37 Class capsuleClass () 34 Class capsuleClass ()
38 { 35 {
39 if (!Capsule.capsuleClass) 36 if (!Capsule.capsuleClass)
40 initCapsuleClass; 37 initCapsuleClass;
41 38
90 { 87 {
91 Class superClass = cast(Class) objc.getClass!("NSObject"); 88 Class superClass = cast(Class) objc.getClass!("NSObject");
92 Capsule.capsuleClass = objc.allocateClassPair!("D_Object")(superClass, 0); 89 Capsule.capsuleClass = objc.allocateClassPair!("D_Object")(superClass, 0);
93 90
94 ubyte alignment = cast(ubyte) log2(Bridge.DObjectType.sizeof); 91 ubyte alignment = cast(ubyte) log2(Bridge.DObjectType.sizeof);
95 92
96 Capsule.capsuleClass.addIvar!(Bridge.dObjectVar, encode!(Bridge.DObjectType))(Bridge.DObjectType.sizeof, alignment); 93 Capsule.capsuleClass.addIvar!(Bridge.dObjectVar, encode!(Bridge.DObjectType))(Bridge.DObjectType.sizeof, alignment);
97 94
98 Capsule.capsuleClass.addMethod!(encodeCallable!(Capsule.description))(sel.registerName!("description"), cast(IMP) &Capsule.description); 95 Capsule.capsuleClass.addMethod!(encodeCallable!(Capsule.description))(sel.registerName!("description"), cast(IMP) &Capsule.description);
99 Capsule.capsuleClass.addMethod!(encodeCallable!(Capsule.hash))(sel.registerName!("hash"), cast(IMP) &Capsule.hash); 96 Capsule.capsuleClass.addMethod!(encodeCallable!(Capsule.hash))(sel.registerName!("hash"), cast(IMP) &Capsule.hash);
100 Capsule.capsuleClass.addMethod!(encodeCallable!(Capsule.isEqual))(sel.registerName!("isEqual"), cast (IMP) &Capsule.isEqual); 97 Capsule.capsuleClass.addMethod!(encodeCallable!(Capsule.isEqual))(sel.registerName!("isEqual"), cast (IMP) &Capsule.isEqual);
101 98
102 objc.registerClassPair(capsuleClass); 99 objc.registerClassPair(capsuleClass);
103 } 100 }
104 101
105 bool isCapsule (id capsule) 102 /**
106 { 103 * Returns $(D_KEYWORD true) if the given Objective-C instance is a capsule
107 if (!capsule) 104 *
108 return false; 105 * Params:
109 106 * instance = the Objective-C instance
110 Class cls = capsule.isa; 107 *
111 return cls.getInstanceVariable!(Bridge.dObjectVar) !is null; 108 * Returns: $(D_KEYWORD true) if the given Objective-C instance is a capsule
112 } 109 */
113 110 bool isCapsule (id instance)
111 {
112 //if (capsule && capsule.isa)
113 //return capsule.isa.getInstanceVariable!(Bridge.dObjectVar) !is null;
114
115 if (instance)
116 {
117 Class cls = instance.isa;
118
119 while (cls && cls !is capsuleClass)
120 cls = cls.super_class;
121
122 return cls is capsuleClass;
123 }
124
125 return false;
126 }
127
128 /**
129 * Returns $(D_KEYWORD true) if the given Objective-C class is a capsule
130 *
131 * Params:
132 * cls = the Objective-C class
133 *
134 * Returns: true if the given Objective-C class is a capsule
135 */
136 bool isCapsule (Class cls)
137 {
138 while (cls && cls !is capsuleClass)
139 cls = cls.super_class;
140
141 return cls is capsuleClass;
142 }
143
144 /**
145 * Encapsulate the value of type $(D_PARAM T) to corresponding Objective-C type $(D_PSYMBOL ObjcType!(T))
146 *
147 * Params:
148 * T = the type of the value
149 * value = the value to encapsulate
150 *
151 * Returns: the encapsulated value
152 */
114 ObjcType!(T) encapsule (T) (T value) 153 ObjcType!(T) encapsule (T) (T value)
115 { 154 {
116 static if (needsEncapsulation!(T)) 155 static if (needsEncapsulation!(T))
117 { 156 {
118 if (!value) 157 if (!value)
119 return null; 158 return null;
120 159
121 if (auto wrapper = cast(ObjcWrapper) value) 160 if (auto wrapper = cast(ObjcWrapper) value)
122 return wrapper.objcObject; 161 return wrapper.objcObject;
123 162
124 return Capsule.create(value, capsuleClass); 163 static if (is(T == interface))
164 return Capsule.create(cast(Object) value, capsuleClass);
165
166 return Capsule.create(cast(Object) value, capsuleClass);
125 } 167 }
126 168
127 else 169 else
128 return value; 170 return value;
129 } 171 }
130 172
173 /**
174 * Decapsulate the given Objective-C value of type $(D_PSYMBOL ObjcType!(T)) to corresponding D type $(D_PARAM T).
175 *
176 * Params:
177 * T = the type of the decapsulated value
178 * value = the value to decapsulate
179 *
180 * Returns: the decapsulated value
181 */
131 T decapsule (T) (ObjcType!(T) value) 182 T decapsule (T) (ObjcType!(T) value)
132 { 183 {
133 static if (needsEncapsulation!(T)) 184 static if (needsEncapsulation!(T))
134 { 185 {
135 if (isCapsule(value)) 186 static if (hasIdConstructor!(T))
187 {
188 T instance = cast(T) Bridge.getDObject(value);
189
190 return instance ? instance : new T(value);
191 }
192
193 else
136 return cast(T) Bridge.getDObject(value); 194 return cast(T) Bridge.getDObject(value);
137
138 else
139 {
140 static if (is(T : ObjcWrapper))
141 new T(value);
142
143 else
144 return null;
145 }
146 } 195 }
147 196
148 else 197 else
149 return value; 198 return value;
150 } 199 }