diff 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
line wrap: on
line diff
--- a/dstep/objc/bridge/Capsule.d	Mon Aug 03 15:31:48 2009 +0200
+++ b/dstep/objc/bridge/Capsule.d	Sun Jan 03 22:06:11 2010 +0100
@@ -11,14 +11,12 @@
 	import tango.core.Memory;
 	import tango.math.Math : log2;
 	
-	alias GC.addRoot addRoot;
-	
 	import tango.core.Traits;
 }
 
 else
 {
-	import std.gc : addRoot;
+	import GC = std.gc : addRoot;
 	import std.math : log2;
 }
 
@@ -32,8 +30,7 @@
 import dstep.objc.runtime;
 import bindings = dstep.objc.bindings;
 
-import mambo.io;
-
+/// Returns the capsule class
 Class capsuleClass ()
 {
 	if (!Capsule.capsuleClass)
@@ -92,7 +89,7 @@
 	Capsule.capsuleClass = objc.allocateClassPair!("D_Object")(superClass, 0);
 	
 	ubyte alignment = cast(ubyte) log2(Bridge.DObjectType.sizeof);
-
+	
 	Capsule.capsuleClass.addIvar!(Bridge.dObjectVar, encode!(Bridge.DObjectType))(Bridge.DObjectType.sizeof, alignment);
 	
 	Capsule.capsuleClass.addMethod!(encodeCallable!(Capsule.description))(sel.registerName!("description"), cast(IMP) &Capsule.description);
@@ -102,15 +99,57 @@
 	objc.registerClassPair(capsuleClass);
 }
 
-bool isCapsule (id capsule)
-{
-	if (!capsule)
-		return false;
+/**
+ * Returns $(D_KEYWORD true) if the given Objective-C instance is a capsule
+ * 
+ * Params:
+ *     instance = the Objective-C instance 
+ *     
+ * Returns: $(D_KEYWORD true) if the given Objective-C instance is a capsule
+ */
+bool isCapsule (id instance)
+{	
+	//if (capsule && capsule.isa)
+		//return capsule.isa.getInstanceVariable!(Bridge.dObjectVar) !is null;
 	
-	Class cls = capsule.isa;
-	return cls.getInstanceVariable!(Bridge.dObjectVar) !is null;
+	if (instance)
+	{
+		Class cls = instance.isa;
+		
+		while (cls && cls !is capsuleClass)
+			cls = cls.super_class;
+		
+		return cls is capsuleClass;
+	}
+	
+	return false;
 }
 
+/**
+ * Returns $(D_KEYWORD true) if the given Objective-C class is a capsule
+ * 
+ * Params:
+ *     cls = the Objective-C class 
+ *     
+ * Returns: true if the given Objective-C class is a capsule
+ */
+bool isCapsule (Class cls)
+{	
+	while (cls && cls !is capsuleClass)
+		cls = cls.super_class;
+	
+	return cls is capsuleClass;
+}
+
+/**
+ * Encapsulate the value of type $(D_PARAM T) to corresponding Objective-C type $(D_PSYMBOL ObjcType!(T))
+ * 
+ * Params:
+ * 	   T = the type of the value
+ *     value = the value to encapsulate
+ *     
+ * Returns: the encapsulated value
+ */
 ObjcType!(T) encapsule (T) (T value)
 {		
 	static if (needsEncapsulation!(T))
@@ -121,28 +160,38 @@
 		if (auto wrapper = cast(ObjcWrapper) value)
 			return wrapper.objcObject;
 		
-		return Capsule.create(value, capsuleClass);
+		static if (is(T == interface))
+			return Capsule.create(cast(Object) value, capsuleClass);
+		
+		return Capsule.create(cast(Object) value, capsuleClass);
 	}
 	
 	else
 		return value;
 }
 
+/**
+ * Decapsulate the given Objective-C value of type $(D_PSYMBOL ObjcType!(T)) to corresponding D type $(D_PARAM T). 
+ * 
+ * Params:
+ * 	   T = the type of the decapsulated value
+ *     value = the value to decapsulate
+ *     
+ * Returns: the decapsulated value
+ */
 T decapsule (T) (ObjcType!(T) value)
 {
 	static if (needsEncapsulation!(T))
-	{
-		if (isCapsule(value))
-			return cast(T) Bridge.getDObject(value);
+	{		
+		static if (hasIdConstructor!(T))
+		{
+			T instance = cast(T) Bridge.getDObject(value);
+			
+			return instance ? instance : new T(value);
+		}
 		
 		else
-		{
-			static if (is(T : ObjcWrapper))
-				new T(value);
-			
-			else
-				return null;
-		}
+			return cast(T) Bridge.getDObject(value);
 	}
 	
 	else