Mercurial > projects > dstep
view dstep/objc/bridge/Capsule.d @ 2:9fd439a28ce3
Adapted the scripts for the new bridge + a lot more
author | Jacob Carlborg <doob@me.com> |
---|---|
date | Sun, 05 Jul 2009 17:16:19 +0200 |
parents | 033d260cfc9b |
children | 19885b43130e |
line wrap: on
line source
/** * Copyright: Copyright (c) 2009 Jacob Carlborg. * Authors: Jacob Carlborg * Version: Initial created: Feb 3, 2009 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0) */ module dstep.objc.bridge.Capsule; version (Tango) { import tango.core.Memory; import tango.math.Math : log2; alias GC.addRoot addRoot; import tango.core.Traits; } else { import std.gc : addRoot; import std.math : log2; } import dstep.internal.String; import dstep.objc.bridge.Bridge; import dstep.objc.bridge.Type; import dstep.objc.bridge.TypeEncoding; import dstep.objc.bridge.Wrapper; import dstep.objc.message; import dstep.objc.objc; import dstep.objc.runtime; import bindings = dstep.objc.bindings; import mambo.io; Class capsuleClass () { if (!Capsule.capsuleClass) initCapsuleClass; return Capsule.capsuleClass; } private struct Capsule { static Class capsuleClass; static id create (Object object, Class capsuleClass) { id capsule = objc.createInstance(capsuleClass, 0); Bridge.setDObject(object, capsule); return capsule; } static id description (id self, SEL op) in { assert(isCapsule(self)); } body { return encapsuleString(decapsule!(Object)(self).toString); } static hash_t hash (id self, SEL op) in { assert(isCapsule(self)); } body { return decapsule!(Object)(self).toHash; } static byte isEqual (id self, SEL op, Object object) in { assert(isCapsule(self)); } body { return decapsule!(Object)(self) == object; } } private void initCapsuleClass () { Class superClass = cast(Class) objc.getClass!("NSObject"); 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); Capsule.capsuleClass.addMethod!(encodeCallable!(Capsule.hash))(sel.registerName!("hash"), cast(IMP) &Capsule.hash); Capsule.capsuleClass.addMethod!(encodeCallable!(Capsule.isEqual))(sel.registerName!("isEqual"), cast (IMP) &Capsule.isEqual); objc.registerClassPair(capsuleClass); } bool isCapsule (id capsule) { if (!capsule) return false; Class cls = capsule.isa; return cls.getInstanceVariable!(Bridge.dObjectVar) !is null; } ObjcType!(T) encapsule (T) (T value) { static if (needsEncapsulation!(T)) { if (!value) return null; if (auto wrapper = cast(ObjcWrapper) value) return wrapper.objcObject; return Capsule.create(value, capsuleClass); } else return value; } T decapsule (T) (ObjcType!(T) value) { static if (needsEncapsulation!(T)) { if (isCapsule(value)) return cast(T) Bridge.getDObject(value); else { static if (is(T : ObjcWrapper)) new T(value); else return null; } } else return value; } private id encapsuleString (string str) { enum { NSUTF8StringEncoding = 4 } return objc.getClass!("NSString").msgSend(sel.registerName!("alloc")).msgSend(sel.registerName!("initWithBytes:length:encoding:"), str.ptr, str.length, NSUTF8StringEncoding); }