Mercurial > projects > dstep
view dstep/objc/bridge/ClassInitializer.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: Apr 7, 2009 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0) */ module dstep.objc.bridge.ClassInitializer; version (Tango) import tango.math.Math; else import std.math; import dstep.internal.String; import bindings = dstep.objc.bindings; import dstep.objc.bridge.Bridge; import dstep.objc.bridge.TypeEncoding; import dstep.objc.objc; import dstep.objc.runtime; package template ObjcSubclassInitializer (string subclassName, string superclassName) { import dstep.internal.String : string; import dstep.objc.bridge.Bridge : ObjcBindMethod; import dstep.objc.runtime : Method, objc_method, sel, objc; import dstep.objc.bridge.TypeEncoding : encode; static Class objcClass () { if (objcClass_) return objcClass_; Class superClass = cast(Class) objc.getClass!(superclassName); while (!superClass) superClass = super.objcClass; return objcClass_ = subclassInit!(subclassName)(superClass, collectObjcInstanceMethods, collectObjcClassMethods); } private static Method[] collectObjcInstanceMethods () { Method[] methods; mixin("alias " ~ superclassName ~ " Type;"); foreach (i, f; typeof(Type.tupleof)) { const len = Type.stringof.length; const fieldName = Type.tupleof[i].stringof[1 + len + 2 .. $]; static if (fieldName == Bridge.objcMethodDeclarationVar) { typeof(Type.tupleof[i]) field; Method m = new objc_method; m.method_name = sel.registerName!(field.methodName); m.method_types = encode!(field.returnType, id, SEL, field.argsType).ptr; m.method_imp = cast(IMP) &Type.ObjcBindMethod!(field.methodImp, field.returnType, field.methodName, field.argsType).forwardVirtualCall; methods ~= m; } } return methods; } private static Method[] collectObjcClassMethods () { Method[] methods; mixin("alias " ~ superclassName ~ " Type;"); foreach (i, f; typeof(Type.tupleof)) { const len = Type.stringof.length; const fieldName = Type.tupleof[i].stringof[1 + len + 2 .. $]; static if (fieldName == Bridge.objcClassMethodDeclarationVar) { typeof(Type.tupleof[i]) field; Method m = new objc_method; m.method_name = sel.registerName!(field.methodName); m.method_types = encode!(field.returnType, field.argsType).ptr; m.method_imp = cast(IMP) &Type.ObjcBindClassMethod!(field.methodImp, field.returnType, field.methodName, field.argsType).forwardStaticCall; methods ~= m; } } return methods; } private R invokeObjcSelf (R, string name, ARGS...) (ARGS args) { return Bridge.invokeObjcMethod!(R, name, ARGS)(objcObject, args); } private R invokeObjcSuper (R, string name, ARGS...) (ARGS args) { return Bridge.invokeObjcMethod!(R, name, ARGS)(objcSuper, args); } private static R invokeObjcSelfClass (R, string name, ARGS...) (ARGS args) { return Bridge.invokeObjcClassMethod!(R, name, ARGS)(objcClass, args); } private static R invokeObjcSuperClass (R, string name, ARGS...) (ARGS args) { return Bridge.invokeObjcClassMethod!(R, name, ARGS)(objcSuperClass, args); } } Class subclassInit (string className) (Class superClass, Method[] instanceMethods = null, Method[] classMethods = null) { Class cls = objc.allocateClassPair!(className)(superClass, 0); Class metaClass = (cast(id) cls).getClass; ubyte alignment = cast(ubyte) log2(Bridge.DObjectType.sizeof); cls.addIvar!(Bridge.dObjectVar, encode!(Bridge.DObjectType))(Bridge.DObjectType.sizeof, alignment); foreach (method ; instanceMethods) bindings.class_addMethod(cls, method.method_name, method.method_imp, method.method_types); foreach (method ; classMethods) bindings.class_addMethod(metaClass, method.method_name, method.method_imp, method.method_types); objc.registerClassPair(cls); return cls; }