Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / SCClassLibrary / Common / osx / objC / scide_scapp / SCNSObject.sc
blob0c4cee054f8933a787d7f12995cde6a0ad280e80
1 //SCNSClass {
2 //      var <name;
3 //
4 //      *new{|name|
5 //              ^super.newCopyArgs
6 //      }
7 //
8 //      asString{
9 //              ^name
10 //      }
12 //      //todo implement objc functionality
15 //}
17 SCNSObjectAbstract {
18         var <dataptr=nil, <> className, < nsAction=nil, < nsDelegate=nil;
20         *dumpPool {
21                 _ObjC_DumpPool
22                 ^this.primitiveFailed;
23         }
25         *freePool {
26                 _ObjC_FreePool
27                 ^this.primitiveFailed;
28         }
30         *new{|classname, initname, args, defer=false|
31                 ^super.new.init(classname.asString, initname, args, defer)
32         }
34         *getClass{|classname| //return only the class id, the object is not allocated yet ...
35                 ^super.new.initClass(classname);
36         }
38         invoke{|method, args, defer=false|
39                 var result;
40                 if(dataptr.isNil, {^nil;});
41                 args = args ? []; //todo: fix that in the primitive ...
42                 result = this.prInvoke(method, args, defer);
43                 ^result.asNSReturn
44         }
46         initClass{|name|
47                 this.prGetClass(name)
48         }
50         isSubclassOf {
51                 |nsclassname|
52                 _ObjC_IsSubclassOfNSClass
53                 ^this.primitiveFailed;
54         }
56         release {
57                 if(nsAction.notNil, {nsAction.release; nsAction=nil;});
58                 if(nsDelegate.notNil, {nsDelegate.release; nsDelegate=nil;});
59                 this.prDealloc;
60                 dataptr = nil;
61         }
63         isAllocated {
64                 ^dataptr.notNil
65         }
67         isReleased {
68                 ^dataptr.isNil
69         }
71         initAction{|actionName = "doFloatAction:"|
72                 var out;
73                 out = CocoaAction.newClear;
74                 this.prSetActionForControl(out, actionName);
75                 out.prSetClassName;
76                 nsAction = out;
77                 nsAction.object = this;
78                 ^out
79         }
80         setDelegate{
81                 var out;
82                 out = CocoaAction.newClear;
83                 this.prSetDelegate(out);
84                 out.prSetClassName;
85                 nsDelegate = out;
86                 nsDelegate.object = this;
87                 ^out
88         }
90         sendMessage{|msgname, args|
91                 this.prSendMsg(msgname, args)
92         }
94         prSendMsg{|msgname, args|
95                         _ObjC_SendMessage
96         }
97 //private
98         *newFromRawPointer{|ptr|
99                 ^super.new.initFromRawPointer(ptr)
100         }
102         *newClear{
103                 ^super.new
104         }
106         *newWith{| classname, initname,args|
107                 ^super.new.initWith( classname, initname,args)
108         }
110         initWith{| cn, initname,args|
111                 className = cn;
112                 this.prAllocWith( cn, initname,args);
113         }
115         initFromRawPointer{|ptr|
116                 dataptr = ptr;
117                 className = this.prGetClassName;
118         }
120         prSetClassName{
121                 className = this.prGetClassName;
122         }
124         init{|cn, in, args, defer|
125                 var result;
126         //      className = cn; // set upon return
127                 if(cn.isKindOf(String) and:{in.isKindOf(String)}, {
128                         result = this.prAllocInit(cn, in, args, defer);
129                         ^result;
130                 });
131         }
133         prAllocInit { arg classname, initname,args;
134                 _ObjC_AllocInit;
135                 ^this.primitiveFailed;
136         }
138         prDealloc {
139                 _ObjC_Dealloc;
140                 ^this.primitiveFailed;
141         }
143         prInvoke { arg initname,args, defer=true;
144                 _ObjC_Invoke
145                 ^this.primitiveFailed;
146         }
148         prGetClassName{|it|
149                 _ObjC_GetClassName
150 //              ^this.primitiveFailed;
151         }
153         prAllocWith { arg classname, initname,args;
154                 _ObjC_AllocSend;
155                 ^this.primitiveFailed;
156         }
157         prGetClass{arg classname;
158                 _ObjC_GetClass
159                 ^this.primitiveFailed;
160         }
162         /*
163         asPyrString {
164                 ^this.prAsPyrString;
165         }
166         */
168         //for NSControl:
169         prSetActionForControl{|control|
170                 _ObjC_SetActionForControl
171         }
172         prSetDelegate{|control|
173                 _ObjC_SetDelegate
174         }
176 //      sendMsg{|initname,args|
177 //              ^this.prSendMsg(className, initname, args, 0)
178 //      }
180 // experimental
181         *panel{|path|
182                 _LoadUserPanel
183         }
185         asArray {arg arrayType;
186                 var requestedLength;
187                 requestedLength = this.invoke("length").asInteger;
188                 if(this.isSubclassOf("NSData"), {
189                         if(arrayType.isKindOf(String), {arrayType = arrayType.asSymbol});
190                         if(arrayType.isKindOf(Symbol), {
191                                 arrayType = case
192                                         { arrayType == \string } { String.newClear(requestedLength) }
193                                         { arrayType == \int8   } { Int8Array.newClear(requestedLength) }
194                                         { arrayType == \int16  } { Int16Array.newClear(requestedLength >> 1) }
195                                         { arrayType == \int32  } { Int32Array.newClear(requestedLength >> 2) }
196                                         { arrayType == \double } { DoubleArray.newClear(requestedLength >> 3) }
197                                         { arrayType == \float  } { FloatArray.newClear(requestedLength >> 2) };
198                                 ^this.prAsArray(arrayType, requestedLength);
199                         });
200                         ^nil;
201                 });
202         }
204         prAsArray {|type, len|
205                 _ObjC_NSDataToSCArray
206                 ^this.primitiveFailed;
207         }
209         /*
210         prAsPyrString {
211                 _ObjC_NSStringToPyrString
212                 ^this.primitiveFailed;
213         }
214         */
216         registerNotification {
217                 |aNotificationName, aFunc, obj=1|
218                 if(nsDelegate.isNil, {
219                         this.setDelegate;
220                 });
221                 nsDelegate.prRegisterNotification(aNotificationName, aFunc);
222                 if (obj.notNil and:{ obj == 1 }) { obj = this };
223                 this.prRegisterNotification(aNotificationName, obj);
224         }
226         prRegisterNotification {|aNotificationName, obj|
227                 _ObjC_RegisterNotification
228         }
231 //this is usually noy created directly. call SCNSObject-initAction instead.
232 CocoaAction : SCNSObjectAbstract{
233         var <>action, notificationActions=nil, delegateActions=nil, <>object;
235         doAction{|it|
236                 action.value(this, it);
237         }
239         doNotificationAction {
240                 |notif, nsNotification, obj|
241                 var func;
242                 func = notificationActions.at(notif.asSymbol);
243                 if(func.notNil, {
244                         func.value(notif, nsNotification, obj, this);
245                 });
246         }
248         doDelegateAction {
249                 |method, arguments|
250                 var result, func;
251                 func = delegateActions.at(method.asSymbol);
252                 if(func.notNil, {
253                         result = func.value(method, arguments);
254                         ^result;
255                 });
256         }
258         addMethod {
259                 |selectorName, returntype, objctypes, aFunc|
260                 var types;
261                 if(selectorName.notNil and:{aFunc.isKindOf(Function)}, {
262                         if(delegateActions.isNil, {delegateActions = IdentityDictionary.new(16)});
263                         if(returntype.isNil, {returntype = "v"});
264                         types = returntype ++ "@:" ++ objctypes; // first and second types are always ID and _cmd
265                         this.praddMethod(selectorName, types);
266                         delegateActions.add(selectorName.asSymbol -> aFunc);
267                 });
268         }
270         prRegisterNotification {
271                 |aNotName, aFunc|
272                 if(aNotName.notNil, {
273                         if(notificationActions.isNil, {notificationActions = IdentityDictionary.new(16);});
274                         notificationActions.add(aNotName.asSymbol -> aFunc);
275                 });
276         }
278         praddMethod {
279                 |selectorName, objctypesAsString|
280                 _ObjC_DelegateAddSelector
281                 ^this.primitiveFailed;
282         }
284         removeMethod {
285                 _ObjC_DelegateRemoveSelector
286                 ^this.primitiveFailed;
287         }
290 SCNSObject : SCNSObjectAbstract{
294 NSBundle : SCNSObject {
295         classvar <> all;
297         *new{|path|
298                 ^super.newClear.loadBundle(path);
299         }
301         allocPrincipalClass{
302                 ^SCNSObject.newFromRawPointer(this.prAllocPrincipalClass);
303         }
305         allocClassNamed{|name, initname, args, defer=false|
306                 var ptr;
307                 ptr = this.prAllocClassNamed(name, initname, args, defer);
308                 if(ptr.isNil){"could not alloc class: %".format(name).warn; ^nil};
309                 ^SCNSObject.newFromRawPointer(ptr);
310         }
313         //private
315         loadBundle{|path|
316                 this.prLoadBundle(path);
317                 if(this.isAllocated){
318                         all = all.add(this);
319                 }
320         }
322         prLoadBundle{|path|
323                 _ObjC_LoadBundle
324         }
326         prAllocPrincipalClass{
327                 _ObjcBundleAllocPrincipalClass
328         }
330         prAllocClassNamed{|name, initname, args, defer|
331                 _ObjcBundleAllocClassNamed
332         }
336 /* cocoa-bridge by Jan Trutzschler 2005 */
338 NSTypeEncoding {
339         *object {^"@"}
340         *integer {^"i"}
341         *float {^"f"}
342         *double {^"d"}
343         *boolean {^"i"}
346 + SCView {
347         primitive {^dataptr;}
348         *newFromRawPointer {|nsptr|
349         }