Mercurial > projects > dstep
comparison dstep/objc/bridge/ClassInitializer.d @ 1:033d260cfc9b
First upload of the bridge
author | Jacob Carlborg <doob@me.com> |
---|---|
date | Thu, 18 Jun 2009 22:00:13 +0200 |
parents | |
children | 9fd439a28ce3 |
comparison
equal
deleted
inserted
replaced
0:c7db221de6e8 | 1:033d260cfc9b |
---|---|
1 /** | |
2 * Copyright: Copyright (c) 2009 Jacob Carlborg. | |
3 * Authors: Jacob Carlborg | |
4 * Version: Initial created: Apr 7, 2009 | |
5 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0) | |
6 */ | |
7 module dstep.objc.bridge.ClassInitializer; | |
8 | |
9 version (Tango) | |
10 import tango.math.Math; | |
11 | |
12 else | |
13 import std.math; | |
14 | |
15 import dstep.internal.String; | |
16 import bindings = dstep.objc.bindings; | |
17 import dstep.objc.bridge.Bridge; | |
18 import dstep.objc.bridge.TypeEncoding; | |
19 import dstep.objc.objc; | |
20 import dstep.objc.runtime; | |
21 | |
22 package template ObjcSubclassInitializer (string subclassName, string superclassName) | |
23 { | |
24 import dstep.internal.String : string; | |
25 import dstep.objc.bridge.Bridge : ObjcBindMethod; | |
26 import dstep.objc.runtime : Method, objc_method, sel, objc; | |
27 import dstep.objc.bridge.TypeEncoding : encode; | |
28 | |
29 static Class objcClass () | |
30 { | |
31 if (objcClass_) | |
32 return objcClass_; | |
33 | |
34 Class superClass = cast(Class) objc.getClass!(superclassName); | |
35 | |
36 while (!superClass) | |
37 superClass = super.objcClass; | |
38 | |
39 return objcClass_ = subclassInit!(subclassName)(superClass, collectObjcInstanceMethods, collectObjcClassMethods); | |
40 } | |
41 | |
42 private static Method[] collectObjcInstanceMethods () | |
43 { | |
44 Method[] methods; | |
45 | |
46 mixin("alias " ~ superclassName ~ " Type;"); | |
47 | |
48 foreach (i, f; typeof(Type.tupleof)) | |
49 { | |
50 const len = Type.stringof.length; | |
51 const fieldName = Type.tupleof[i].stringof[1 + len + 2 .. $]; | |
52 | |
53 static if (fieldName == Bridge.objcMethodDeclarationVar) | |
54 { | |
55 typeof(Type.tupleof[i]) field; | |
56 | |
57 Method m = new objc_method; | |
58 m.method_name = sel.registerName!(field.methodName); | |
59 m.method_types = encode!(field.returnType, id, SEL, field.argsType).ptr; | |
60 m.method_imp = cast(IMP) &Type.ObjcBindMethod!(field.methodImp, field.returnType, field.methodName, field.argsType).forwardVirtualCall; | |
61 | |
62 methods ~= m; | |
63 } | |
64 } | |
65 | |
66 return methods; | |
67 } | |
68 | |
69 private static Method[] collectObjcClassMethods () | |
70 { | |
71 Method[] methods; | |
72 | |
73 mixin("alias " ~ superclassName ~ " Type;"); | |
74 | |
75 foreach (i, f; typeof(Type.tupleof)) | |
76 { | |
77 const len = Type.stringof.length; | |
78 const fieldName = Type.tupleof[i].stringof[1 + len + 2 .. $]; | |
79 | |
80 static if (fieldName == Bridge.objcClassMethodDeclarationVar) | |
81 { | |
82 typeof(Type.tupleof[i]) field; | |
83 | |
84 Method m = new objc_method; | |
85 m.method_name = sel.registerName!(field.methodName); | |
86 m.method_types = encode!(field.returnType, field.argsType).ptr; | |
87 m.method_imp = cast(IMP) &Type.ObjcBindClassMethod!(field.methodImp, field.returnType, field.methodName, field.argsType).forwardStaticCall; | |
88 | |
89 methods ~= m; | |
90 } | |
91 } | |
92 | |
93 return methods; | |
94 } | |
95 | |
96 private R invokeObjcSelf (R, string name, ARGS...) (ARGS args) | |
97 { | |
98 return Bridge.invokeObjcMethod!(R, name, ARGS)(objcObject, args); | |
99 } | |
100 | |
101 private R invokeObjcSuper (R, string name, ARGS...) (ARGS args) | |
102 { | |
103 return Bridge.invokeObjcMethod!(R, name, ARGS)(objcSuper, args); | |
104 } | |
105 | |
106 private static R invokeObjcSelfClass (R, string name, ARGS...) (ARGS args) | |
107 { | |
108 return Bridge.invokeObjcClassMethod!(R, name, ARGS)(objcClass, args); | |
109 } | |
110 | |
111 private static R invokeObjcSuperClass (R, string name, ARGS...) (ARGS args) | |
112 { | |
113 return Bridge.invokeObjcClassMethod!(R, name, ARGS)(objcClass.getSuperclass, args); | |
114 } | |
115 } | |
116 | |
117 Class subclassInit (string className) (Class superClass, Method[] instanceMethods = null, Method[] classMethods = null) | |
118 { | |
119 Class cls = objc.allocateClassPair!(className)(superClass, 0); | |
120 Class metaClass = (cast(id) cls).getClass; | |
121 | |
122 ubyte alignment = cast(ubyte) log2(Bridge.DObjectType.sizeof); | |
123 | |
124 cls.addIvar!(Bridge.dObjectVar, encode!(Bridge.DObjectType))(Bridge.DObjectType.sizeof, alignment); | |
125 | |
126 foreach (method ; instanceMethods) | |
127 bindings.class_addMethod(cls, method.method_name, method.method_imp, method.method_types); | |
128 | |
129 foreach (method ; classMethods) | |
130 bindings.class_addMethod(metaClass, method.method_name, method.method_imp, method.method_types); | |
131 | |
132 objc.registerClassPair(cls); | |
133 | |
134 return cls; | |
135 } |