Mercurial > projects > dstep
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