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