2 * CocoaBridgePrimitives.M
5 * Created by Jan Trutzschler 08/2005.
8 sc3 bridge to obj-c/cocoa
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27 #import <Cocoa/Cocoa.h>
28 #import <objc/objc-runtime.h>
29 #import <objc/Object.h>
30 #import <QTKit/QTTime.h>
31 #import <QTKit/QTTimeRange.h>
32 #import <Foundation/NSMethodSignature.h>
35 #import "PyrPrimitive.h"
39 #import "MyDocument.h"
41 #import "SCVirtualMachine.h"
43 #if (MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4)
44 #define class_getName(a) ((a)->name)
47 #define COCOABRIDGE_VERBOSITY 0
48 #define COCOABRIDGE_STORE_OBJECTS_IN_ARRAY 1 // Conditional for storing all created objects in an NSArray. For future test with special Pool.
49 #define COCOABRIDGE_AUTOCONVERT_NSSTRING 1 /* for backward compat. set to 0.
50 Used only for converting NSString to PyrString on INVOCATION RETURN.
51 PyrString are automatically converted to NSString when passed as arguments
53 #if COCOABRIDGE_VERBOSITY
54 #define COCOABRIDGE_OBJ_RETAIN_LOG(nsobj) NSLog(@"OBJ_RETA NSObject(%p), type(%@)", nsobj, [nsobj class]);
55 #define COCOABRIDGE_OBJ_RELEASE_LOG(nsobj) NSLog(@"OBJ_RELE NSObject(%p), type(%@)", nsobj, [nsobj class]);
56 #define COCOABRIDGE_POOL_ADD_LOG(nsobj) NSLog(@"POOL_ADD NSObject(%p), type(%@), POOL_OBJ_NUMBER: %i", nsobj, [nsobj class], [nsobjects count]);
57 #define COCOABRIDGE_POOL_REM_LOG(nsobj) NSLog(@"POOL_REM NSObject(%p), type(%@), POOL_OBJ_NUMBER: %i", nsobj, [nsobj class], [nsobjects count]-1);
59 #define COCOABRIDGE_OBJ_RETAIN_LOG(nsobj) ;
60 #define COCOABRIDGE_OBJ_RELEASE_LOG(nsobj) ;
61 #define COCOABRIDGE_POOL_ADD_LOG(nsobj) ;
62 #define COCOABRIDGE_POOL_REM_LOG(nsobj) ;
65 #if COCOABRIDGE_STORE_OBJECTS_IN_ARRAY
66 # define COCOABRIDGE_POOL_ADD(nsobj) \
68 [nsobjects addObject
: nsobj
]; \
69 COCOABRIDGE_POOL_ADD_LOG(nsobj
) \
72 # define COCOABRIDGE_POOL_REM(nsobj) \
74 COCOABRIDGE_POOL_REM_LOG(nsobj
) \
75 [nsobjects removeObject
: nsobj
]; \
78 # define COCOABRIDGE_POOL_ADD(nsobj)
79 # define COCOABRIDGE_POOL_REM(nsobj)
82 #define COCOABRIDGE_OBJ_RETAIN(nsobj) \
85 /*COCOABRIDGE_OBJ_RETAIN_LOG(nsobj)*/ \
86 COCOABRIDGE_POOL_ADD(nsobj
) \
89 #define COCOABRIDGE_OBJ_RELEASE(nsobj) \
91 /*COCOABRIDGE_OBJ_RELEASE_LOG(nsobj)*/ \
92 COCOABRIDGE_POOL_REM(nsobj
) \
93 /*[nsobj release];*/ \
96 #define TryInvocation(anInvocation, receiver) \
98 [anInvocation invoke
]; \
99 }@catch(NSException
* e
){ \
100 post("ERROR: CocoaBridge exception caught: %s %s\n", [[e name
]UTF8String
], [[e reason
]UTF8String
]); \
106 PyrSymbol
*s_nsObject
;
107 //NSAutoreleasePool *nsAutoReleasePool;
109 #if COCOABRIDGE_STORE_OBJECTS_IN_ARRAY
110 //NSMutableSet *nsobjects = nil;
111 NSMutableArray
*nsobjects
= nil;
115 inline NSString
* nsStringFromPyrSlot(PyrSlot
*slot
)
119 int len
= strlen(slotRawSymbol(slot
)->name
);
120 char* symstr
= (char*)malloc(len
+1);
121 strcpy(symstr
, slotRawSymbol(slot
)->name
);
122 #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4
123 retval
= [NSString stringWithCString
:symstr length
:len
]; // Deprecated 10.4
125 retval
= [NSString stringWithCString
:symstr encoding
:NSASCIIStringEncoding
];
131 PyrString
* pyrString
= slotRawString(slot
);
132 #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4
133 return [NSString stringWithCString
: pyrString
->s length
: pyrString
->size
]; // Deprecated 10.4
135 char* symstr
= (char*)malloc(pyrString
->size
+ 1);
136 memcpy(symstr
, pyrString
->s
, pyrString
->size
); symstr
[pyrString
->size
] = 0;
137 NSString
*retval
= [NSString stringWithCString
:symstr encoding
:NSASCIIStringEncoding
];
145 inline int ObjcTypeFillPyrSlot(PyrSlot
* slot
, const char* type
, void* value
, PyrObjectHdr
** retPyrObject
) {
146 VMGlobals
*g
= gMainVMGlobals
;
149 *retPyrObject
= NULL
;
151 if(*type
== 'r') ++type
;
155 id idval
= *(id*)value
;
156 if([idval isKindOfClass
:[NSColor
class]]) {
157 //NSLog(@"ObjcTypeFillPyrSlot [_NSCOLOR]");
158 NSColor
* nscol
= [idval colorUsingColorSpaceName
:NSCalibratedRGBColorSpace
];
159 PyrObject
*color
= instantiateObject(g
->gc
, s_color
->u.classobj
, 0, false, true);
160 PyrSlot
*slots
= color
->slots
;
161 SetFloat(slots
+0, [nscol redComponent
]);
162 SetFloat(slots
+1, [nscol greenComponent
]);
163 SetFloat(slots
+2, [nscol blueComponent
]);
164 SetFloat(slots
+3, [nscol alphaComponent
]);
165 SetObject(slot
, color
);
167 *retPyrObject
= color
;
169 #if COCOABRIDGE_AUTOCONVERT_NSSTRING
170 else if([idval isKindOfClass
:[NSString
class]]) {
171 //NSLog(@"ObjcTypeFillPyrSlot [_NSSTRING]");
172 NSString
* string
= (NSString
*)idval
;
173 PyrString
* pyrPathString
= newPyrString(g
->gc
,[string UTF8String
],0,true);
174 SetObject(slot
, pyrPathString
);
176 *retPyrObject
= pyrPathString
;
180 //NSLog(@"ObjcTypeFillPyrSlot [_C_ID]");
182 COCOABRIDGE_OBJ_RETAIN(idval
);
183 SetPtr(slot
, (id) idval
);
192 //NSLog(@"ObjcTypeFillPyrSlot [_C_VOID | _C_UNDEF]");
198 //NSLog(@"ObjcTypeFillPyrSlot [_C_CHR | _C_UCHAR]");
199 //SetChar(slot, *(char*)value);
200 SetInt(slot
, *(char*)value
);
207 //NSLog(@"ObjcTypeFillPyrSlot [_C_LONG...]");
208 long sval
= *(long*)value
;
216 //NSLog(@"ObjcTypeFillPyrSlot [_C_SHORT...]");
217 short sval
= *(short*)value
;
225 //NSLog(@"ObjcTypeFillPyrSlot [_C_INT...]");
226 SetInt(slot
, *(int*)value
);
232 float fval
= *(float*)value
;
233 SetFloat(slot
, fval
);
239 //NSLog(@"ObjcTypeFillPyrSlot [_C_FLT...]");
240 double dval
= *(double*)value
;
241 SetFloat(slot
, dval
);
247 //NSLog(@"ObjcTypeFillPyrSlot [BOOLEAN...]");
248 bool b
= *(bool*)value
;
257 //NSLog(@"ObjcTypeFillPyrSlot [_C_BFLD BITFIELD...]");
262 //NSLog(@"ObjcTypeFillPyrSlot [_C_CHR | _C_UCHAR]");
263 SetPtr(slot
, *(void**)value
);
268 //NSLog(@"ObjcTypeFillPyrSlot [_C_SEL]");
269 SEL sel
= *(SEL*)value
;
270 PyrString
* pyrPathString
= newPyrString(g
->gc
, sel_getName(sel
), 0, true);
271 SetObject(slot
, pyrPathString
);
273 *retPyrObject
= pyrPathString
;
279 //NSLog(@"ObjcTypeFillPyrSlot [_C_CHARPTR | r]");
280 char* str
= *(char**)value
;
281 PyrString
* pyrPathString
= newPyrString(g
->gc
, str
,0,true);
282 SetObject(slot
, pyrPathString
);
284 *retPyrObject
= pyrPathString
;
291 support only for basic types.
292 TODO: plug some functions of the PyObjc to parse structure types.
295 if(strncmp(type
+1, "_NSSize", 7) == 0) {
296 //NSLog(@"ObjcTypeFillPyrSlot [_NSSize]");
298 PyrObject
*array
= ::instantiateObject(g
->gc
, s_array
->u.classobj
, 2, true, true);
299 if(!array
) return errOutOfMemory
;
300 NSSize s
= *(NSSize
*)value
;
301 SetFloat(array
->slots
+0, s.width
);
302 SetFloat(array
->slots
+1, s.height
);
303 SetObject(slot
, array
);
305 *retPyrObject
= array
;
307 }else if(strncmp(type
+1, "_NSRange", 8) == 0) {
308 //NSLog(@"ObjcTypeFillPyrSlot [_NSRange]");
310 PyrObject
*array
= ::instantiateObject(g
->gc
, s_array
->u.classobj
, 2, true, true);
311 if(!array
) return errOutOfMemory
;
312 NSRange r
= *(NSRange
*)value
;
313 SetInt(array
->slots
+0, r.location
);
314 SetInt(array
->slots
+1, r.length
);
315 SetObject(slot
, array
);
317 *retPyrObject
= array
;
318 }else if(strncmp(type
+1, "_NSRect", 7) == 0) {
319 //NSLog(@"ObjcTypeFillPyrSlot [_NSRect]");
322 PyrObject
*rect
= instantiateObject(g
->gc
, s_rect
->u.classobj
, 0, false, true);
323 NSRect r
= *(NSRect
*)value
;
326 SetFloat(slots
+0, r.origin.x
);
327 SetFloat(slots
+1, r.origin.y
);
328 SetFloat(slots
+2, r.size.width
);
329 SetFloat(slots
+3, r.size.height
);
330 SetObject(slot
, rect
);
332 *retPyrObject
= rect
;
333 }else if(strncmp(type
+1, "_NSPoint", 8) == 0) {
334 //NSLog(@"ObjcTypeFillPyrSlot [_NSPoint]");
337 PyrObject
*point
= instantiateObject(g
->gc
, s_point
->u.classobj
, 0, false, true);
338 NSPoint p
= *(NSPoint
*)value
;
340 slots
= point
->slots
;
341 SetFloat(slots
+0, p.x
);
342 SetFloat(slots
+1, p.y
);
343 SetObject(slot
, point
);
345 *retPyrObject
= point
;
346 }else if(strncmp(type
, "{?=qll}", 7) == 0) { // QTTime
347 PyrObject
*pyrarray
= instantiateObject(g
->gc
, s_array
->u.classobj
, 3, true, true);
348 if(!pyrarray
) return errOutOfMemory
;
349 QTTime p
= *(QTTime
*)value
;
350 SetInt(pyrarray
->slots
+0, (int)p.timeValue
);
351 SetInt(pyrarray
->slots
+1, (int)p.timeScale
);
352 SetInt(pyrarray
->slots
+2, (int)p.flags
);
353 SetObject(slot
, pyrarray
);
355 *retPyrObject
= pyrarray
;
357 //NSLog(@"ObjcTypeFillPyrSlot [_C_STRUCT]");
359 post("Warning: CocoaBridge objc structure type not supported.\n");
361 //cType[ptr-cType-1] = '=';
368 //NSLog(@"ObjcTypeFillPyrSlot [_C_STRUCT | _C_UNION | _C_ARY_E]");
378 post("ERROR: ObjcType conversion not handled: %c!\n", *type
);
387 @interface SCCocoaToLangAction
: NSResponder
389 struct PyrObject
*mSCObject
;
390 NSMutableDictionary
*mSelectorArray
;
394 - (void)setSCObject
: (struct PyrObject
*)inObject
;
395 - (struct PyrObject
*)getSCObject
;
396 - (void) doAction
: (id) sender
;
397 - (void) doFloatAction
: (id) sender
;
398 - (void) doIntAction
: (id) sender
;
399 - (void) doStateAction
: (id) sender
;
400 - (void) doFloatArrayAction
: (id) sender
;
401 - (void) doSCObjectAction
: (id) sender
;
403 - (void) keyUp
: (NSEvent
*) event
;
404 - (void) keyDown
: (NSEvent
*) event
;
405 - (void) mouseDown
: (NSEvent
*) event
;
406 - (void)windowWillClose
:(NSNotification
*)aNotification
;
407 - (void)notificationReceived
:(NSNotification
*)aNotification
;
409 - (void)addSelector
:(SEL)aSelector withObjcTypes
:(const char*)cTypes
;
410 - (void)removeSelector
:(SEL)aSelector
;
411 //- forward: (SEL)sel : (marg_list)args;
415 extern bool compiledOK
;
417 @implementation SCCocoaToLangAction
421 mSelectorArray
= [[NSMutableDictionary allocWithZone
:[self zone
]]initWithCapacity
:16];
426 - (void)setSCObject
: (struct PyrObject
*)inObject
428 mSCObject
= inObject
;
430 - (struct PyrObject
*)getSCObject
434 - (void) doFloatAction
: (id) sender
436 // post("doAction \n");
437 //need to sort out the event here ...
438 PyrObject
* pobj
= [self getSCObject
];
439 if(compiledOK
&& pobj
){
440 PyrSymbol
*method
= getsym("doAction");
441 VMGlobals
*g
= gMainVMGlobals
;
443 ++g
->sp
; SetObject(g
->sp
, pobj
);
444 ++g
->sp
; SetFloat(g
->sp
, [sender floatValue
]);
445 runInterpreter(g
, method
, 2);
446 g
->canCallOS
= false;
449 - (void) doAction
: (id) sender
451 // post("doAction \n");
452 pthread_mutex_lock (&gLangMutex
);
453 PyrObject
* pobj
= [self getSCObject
];
454 if(compiledOK
&& pobj
){
455 PyrSymbol
*method
= getsym("doAction");
456 VMGlobals
*g
= gMainVMGlobals
;
458 ++g
->sp
; SetObject(g
->sp
, pobj
);
459 ++g
->sp
; SetInt(g
->sp
, 1);
460 runInterpreter(g
, method
, 2);
461 g
->canCallOS
= false;
463 pthread_mutex_unlock (&gLangMutex
);
465 - (void) doStateAction
: (id) sender
467 // post("doAction \n");
468 pthread_mutex_lock (&gLangMutex
);
469 PyrObject
* pobj
= [self getSCObject
];
470 if(compiledOK
&& pobj
){
471 PyrSymbol
*method
= getsym("doAction");
472 VMGlobals
*g
= gMainVMGlobals
;
475 ++g
->sp
; SetObject(g
->sp
, pobj
);
476 ++g
->sp
; SetInt(g
->sp
, [sender state
]);
477 runInterpreter(g
, method
, 2);
478 g
->canCallOS
= false;
480 pthread_mutex_unlock (&gLangMutex
);
483 - (void) doIntAction
: (id) sender
485 pthread_mutex_lock (&gLangMutex
);
486 PyrObject
* pobj
= [self getSCObject
];
487 if(compiledOK
&& pobj
){
488 PyrSymbol
*method
= getsym("doAction");
489 VMGlobals
*g
= gMainVMGlobals
;
491 ++g
->sp
; SetObject(g
->sp
, pobj
);
492 ++g
->sp
; SetInt(g
->sp
, [sender intValue
]);
493 runInterpreter(g
, method
, 2);
494 g
->canCallOS
= false;
496 pthread_mutex_unlock (&gLangMutex
);
499 - (void) doArrayAction
: (id) sender
501 pthread_mutex_lock (&gLangMutex
);
502 PyrObject
* pobj
= [self getSCObject
];
503 if(compiledOK
&& pobj
){
504 PyrSymbol
*method
= getsym("doAction");
505 VMGlobals
*g
= gMainVMGlobals
;
507 ++g
->sp
; SetObject(g
->sp
, pobj
);
509 size_t size
= (size_t) [sender arraySize
];
510 float *src
= (float*) [sender floatArray
];
511 PyrDoubleArray
* array
= newPyrDoubleArray(g
->gc
, size
, 0 , true);
512 for(int i
=0; i
<size
; i
++){
513 array
->d
[i
] = src
[i
];
515 ++g
->sp
; SetObject(g
->sp
, array
);
516 runInterpreter(g
, method
, 2);
517 g
->canCallOS
= false;
519 pthread_mutex_unlock (&gLangMutex
);
524 - (void) doFloatArrayAction
: (id) sender
526 pthread_mutex_lock (&gLangMutex
);
527 PyrObject
* pobj
= [self getSCObject
];
528 if(compiledOK
&& pobj
){
529 PyrSymbol
*method
= getsym("doAction");
530 VMGlobals
*g
= gMainVMGlobals
;
532 ++g
->sp
; SetObject(g
->sp
, pobj
);
534 size_t size
= (size_t) [sender arraySize
];
535 float *src
= (float*) [sender floatArray
];
536 PyrDoubleArray
* array
= newPyrDoubleArray(g
->gc
, size
, 0 , true);
537 for(int i
=0; i
<size
; i
++){
538 array
->d
[i
] = src
[i
];
540 ++g
->sp
; SetObject(g
->sp
, array
);
541 runInterpreter(g
, method
, 2);
542 g
->canCallOS
= false;
544 pthread_mutex_unlock (&gLangMutex
);
547 - (void) doSCObjectAction
: (id) sender
549 pthread_mutex_lock (&gLangMutex
);
550 PyrObject
* pobj
= [self getSCObject
];
551 if(compiledOK
&& pobj
){
552 PyrSymbol
*method
= getsym("doAction");
553 VMGlobals
*g
= gMainVMGlobals
;
555 ++g
->sp
; SetObject(g
->sp
, pobj
);
556 //push values from sender
557 PyrObject
* reslut
= (PyrObject
*) [sender valueWith
: self];
559 ++g
->sp
; SetObject(g
->sp
, reslut
);
560 runInterpreter(g
, method
, 2);
561 g
->canCallOS
= false;
563 pthread_mutex_unlock (&gLangMutex
);
566 - (void) keyUp
: (NSEvent
*) event
569 - (void) keyDown
: (NSEvent
*) event
571 post("keyDown in cocoaToLang \n");
573 - (void) mouseDown
: (NSEvent
*) event
581 [mSelectorArray release
];
582 [[NSNotificationCenter defaultCenter
]removeObserver
:self]; // in case
586 - (void)windowWillClose
:(NSNotification
*)aNotification
588 pthread_mutex_lock (&gLangMutex
);
589 PyrObject
* pobj
= [self getSCObject
];
590 if(compiledOK
&& pobj
){
591 PyrSymbol
*method
= getsym("doAction");
592 VMGlobals
*g
= gMainVMGlobals
;
594 ++g
->sp
; SetObject(g
->sp
, pobj
);
595 runInterpreter(g
, method
, 1);
596 g
->canCallOS
= false;
598 pthread_mutex_unlock (&gLangMutex
);
603 #pragma mark __SCCOCOATOLANG_FORWARD___
604 - (void)notificationReceived
:(NSNotification
*)aNotification
606 //post("notification received by delegate\n");
607 pthread_mutex_lock (&gLangMutex
);
608 PyrObject
* pobj
= [self getSCObject
];
609 if(compiledOK
&& pobj
){
610 PyrSymbol
*method
= getsym("doNotificationAction");
611 VMGlobals
*g
= gMainVMGlobals
;
614 ++g
->sp
; SetObject(g
->sp
, pobj
);
616 PyrString
* pyrString
= newPyrString(g
->gc
,[[aNotification name
] cString
],0,true);
617 ++g
->sp
; SetObject(g
->sp
, pyrString
);
618 ++g
->sp
; SetPtr(g
->sp
, (void*)aNotification
);
619 ++g
->sp
; SetPtr(g
->sp
, (void*)[aNotification object
]);
621 runInterpreter(g
, method
, 4);
622 g
->canCallOS
= false;
624 pthread_mutex_unlock (&gLangMutex
);
628 - (void*)forward: (SEL)sel : (marg_list)args {
629 NSLog(@"Forward invoked with Selector %s ", sel_getName(sel));
630 [super forward:sel :args];
634 -(NSMethodSignature
*)methodSignatureForSelector
:(SEL)aSel
{
635 return (NSMethodSignature
*)[mSelectorArray objectForKey
:[NSNumber numberWithLong
:(long)aSel
]];
638 -(BOOL)respondsToSelector
:(SEL)sel
{
639 //post("trying %s ", sel_getName(sel));
640 NSEnumerator
*e
= [mSelectorArray keyEnumerator
];
642 while( (obj
= (NSNumber
*)[e nextObject
]) ) {
643 SEL thesel
= (SEL)[obj longValue
];
648 return [super respondsToSelector
:sel
];
651 -(void)forwardInvocation
:(NSInvocation
*)inv
{
653 SEL selector
= [inv selector
];
654 const char* retType
= [[inv methodSignature
]methodReturnType
];
655 const char* csel
= sel_getName(selector
);
657 pthread_mutex_lock (&gLangMutex
);
658 PyrObject
* pobj
= [self getSCObject
];
659 if(compiledOK
&& pobj
){
661 NSMethodSignature
* nsSignature
= [inv methodSignature
];
662 int maxArgs
= [nsSignature numberOfArguments
];
664 PyrSymbol
*method
= getsym("doDelegateAction");
665 VMGlobals
*g
= gMainVMGlobals
;
668 ++g
->sp
; SetObject(g
->sp
, pobj
);
670 PyrString
* pyrString
= newPyrString(g
->gc
, csel
, 0, true);
671 ++g
->sp
; SetObject(g
->sp
, pyrString
);
674 //NSLog(@"NSInvocation Name: %s has %i number of arguments", csel, maxArgs);
677 if(maxArgs
- 2 > 0) {
679 PyrObjectHdr
* pyrObject
;
681 //array = newPyrArray(g->gc, 2, 0, true);
682 array
= ::instantiateObject(g
->gc
, s_array
->u.classobj
, maxArgs
-2, true, true);
683 SetObject(g
->sp
, array
);
685 PyrSlot
* slots
= array
->slots
;
686 for(int i
=2; i
< maxArgs
; ++i
)
688 [inv getArgument
:(void*)&value atIndex
:i
];
689 ObjcTypeFillPyrSlot(slots
++, [nsSignature getArgumentTypeAtIndex
:i
], (void*)&value
, &pyrObject
);
691 g
->gc
->GCWrite(array
, pyrObject
);
698 runInterpreter(g
, method
, 3);
700 g
->canCallOS
= false;
701 if(*retType
!= _C_VOID
&& *retType
!= _C_UNDEF
) {
702 //NSLog(@"Setting NSInvocation Return Type");
703 //[inv retainArguments];
706 PyrSlot
* slot
= &(g
->result
);
707 void * retbuffer
=NULL
;
709 if(*retType
== 'r') ++retType
;
713 //NSLog(@"Setting [_C_ID]");
716 isKindOfSlot(slot
, s_nsObject
->u.classobj
) ||
717 isKindOfSlot(slot
, slotRawSymbol(&s_nsObject
->u.classobj
->superclass
)->u.classobj
)
719 //NSLog(@"Slot is a NSObject");
720 retval
= (id)slotRawPtr(slotRawObject(slot
)->slots
);
722 else if(isKindOfSlot(slot
, class_string
) ||
IsSym(slot
)) {
723 //NSLog(@"Slot is a string");
724 retval
= (id)nsStringFromPyrSlot(slot
);
726 else if(IsPtr(slot
) ) {
727 //NSLog(@"Slot is a Pointer");
728 retval
= (id)slotRawPtr(slot
);
730 else if(IsFloat(slot
)) {
731 //NSLog(@"Slot is a Float");
732 float f
; NSNumber
*n
;
733 slotFloatVal(slot
, &f
);
734 n
= [NSNumber numberWithFloat
:f
];
737 else if(IsInt(slot
)) {
738 //NSLog(@"Slot is an Int");
740 slotIntVal(slot
, &i
);
741 n
= [NSNumber numberWithInt
:i
];
744 else if(isKindOfSlot(slot
, s_color
->u.classobj
)) {
745 //NSLog(@"Slot is a Color");
747 PyrSlot
*slots
= slotRawObject(slot
)->slots
;
748 slotFloatVal(slots
+0, &r
);
749 slotFloatVal(slots
+1, &g
);
750 slotFloatVal(slots
+2, &b
);
751 slotFloatVal(slots
+3, &a
);
752 NSColor
*color
= [NSColor colorWithCalibratedRed
:r green
:g blue
:b alpha
:a
];
756 post("ERROR: Cocoa Bridge wrong type. expected %c. Set to NIL\n", _C_ID
);
757 retbuffer
= (void*)&retval
;
764 //NSLog(@"Setting [_C_CHR]");
767 retval
= slotRawChar(slot
);
769 post("ERROR: Cocoa Bridge wrong type. expected %c. Set to 0\n", _C_CHR
);
770 retbuffer
= (void*)&retval
;
775 case _C_USHT
: // same size PPC, PPC64, IA32...ect...
777 //NSLog(@"Setting [_C_SHT]");
778 int retval
= 0; short shortval
;
781 else if( IsFalse(slot
) )
783 else if(slotIntVal(slot
, &retval
) != errNone
)
784 post("ERROR: Cocoa Bridge wrong type. expected %c\n", _C_SHT
);
786 retbuffer
= (void*)&shortval
;
790 case _C_UINT
: // same size PPC, PPC64, IA32...ect...
792 //NSLog(@"Setting [_C_INT]");
796 else if( IsFalse(slot
) )
798 else if(slotIntVal(slot
, &retval
) != errNone
)
799 post("ERROR: Cocoa Bridge wrong type. expected %c\n", _C_INT
);
800 retbuffer
= (void*)&retval
;
805 case _C_ULNG
: // same size PPC, PPC64, IA32...ect...
807 //NSLog(@"Setting [_C_LNG]");
808 int retval
= 0; long longval
;
811 else if( IsFalse(slot
) )
813 else if(slotIntVal(slot
, &retval
) != errNone
)
814 post("ERROR: Cocoa Bridge wrong type. expected %c\n", _C_LNG
);
815 longval
= (long)retval
;
816 retbuffer
= (void*)&longval
;
822 //NSLog(@"Setting [_C_FLT]");
824 if(slotFloatVal(slot
, &retval
) != errNone
)
825 post("ERROR: Cocoa Bridge wrong type. expected %c\n", _C_FLT
);
826 retbuffer
= (void*)&retval
;
832 //NSLog(@"Setting [_C_DBL]");
834 if(slotDoubleVal(slot
, &retval
) != errNone
)
835 post("ERROR: Cocoa Bridge wrong type. expected %c\n", _C_DBL
);
836 retbuffer
= (void*)&retval
;
842 //NSLog(@"Setting [_C_PTR]");
845 ptr
= slotRawPtr(slot
);
849 post("ERROR: Cocoa Bridge wrong type. expected %c\n", _C_PTR
);
855 //NSLog(@"Setting [_C_CHARPTR | STRING]");
860 size
= strlen(slotRawSymbol(slot
)->name
);
861 else if( isKindOfSlot(slot
, class_string
) ) {
862 size
= ((PyrString
*)slotRawObject(slot
))->size
;
865 post("ERROR: Cocoa Bridge wrong type. expected %c. return ("")\n", _C_CHARPTR
);
866 retbuffer
= (void*)&retval
;
870 retval
= (char*)malloc(sizeof(char) * (size
+1));
871 slotStrVal(slot
, retval
, size
);
872 retbuffer
= (void*)&retval
;
879 support only for basic types.
880 TODO: plug some functions of the PyObjc to parse structure types.
884 cType
= (char*)retType
;
885 ptr
= strchr(retType
, '=') + 1;
886 cType
[ptr
-cType
-1] = '\0';
888 if( (strcmp(cType
+1, "_NSSize") == 0) && (
889 isKindOfSlot(slot
, s_point
->u.classobj
) ||
890 isKindOfSlot(slot
, class_array
))
892 PyrSlot
*slots
= slotRawObject(slot
)->slots
;
894 slotVal(slots
+0, &s.width
);
895 slotVal(slots
+1, &s.height
);
896 retbuffer
= (void*)&s
;
898 else if((strcmp(cType
+1, "_NSRange") == 0) && (
899 isKindOfSlot(slot
, s_point
->u.classobj
) ||
900 isKindOfSlot(slot
, class_array
))
902 PyrSlot
*slots
= slotRawObject(slot
)->slots
;
904 slotIntVal(slots
+0, (int*)&s.location
);
905 slotIntVal(slots
+1, (int*)&s.length
);
906 retbuffer
= (void*)&s
;
908 else if((strcmp(cType
+1, "_NSRect") == 0) && (
909 isKindOfSlot(slot
, s_rect
->u.classobj
) ||
910 isKindOfSlot(slot
, class_array
))
912 PyrSlot
*slots
= slotRawObject(slot
)->slots
;
914 slotVal(slots
+0, &(s.origin.x
));
915 slotVal(slots
+1, &(s.origin.y
));
916 slotVal(slots
+2, &(s.size.width
));
917 slotVal(slots
+3, &(s.size.height
));
918 retbuffer
= (void*)&s
;
920 else if((strcmp(cType
+1, "_NSPoint") == 0) && (
921 isKindOfSlot(slot
, s_point
->u.classobj
) ||
922 isKindOfSlot(slot
, class_array
))
924 PyrSlot
*slots
= slotRawObject(slot
)->slots
;
926 slotVal(slots
+0, &s.x
);
927 slotVal(slots
+1, &s.y
);
928 retbuffer
= (void*)&s
;
930 post("ERROR: Warning structure type not supported %c.\n", _C_STRUCT_B
);
932 cType
[ptr
-cType
-1] = '=';
946 NSLog(@
"ERROR: UNHANDLED RETURN TYPE OF INVOCATION: %c", *retType
);
947 //post("return type not handled");
951 //NSLog(@"Returning NSInvocation");
952 [inv setReturnValue
:retbuffer
];
954 } // End Of Compiled ok
955 pthread_mutex_unlock (&gLangMutex
);
962 - (void)addSelector
:(SEL)aSelector withObjcTypes
:(const char*)cTypes
964 NSNumber
* n
= [NSNumber numberWithLong
:(long)aSelector
];
965 NSMethodSignature
*signature
;
967 if(cTypes
&& strlen(cTypes
) > 0)
968 signature
= [NSMethodSignature signatureWithObjCTypes
:cTypes
]; // defined in <Foundation/NSMethodSignature>
970 signature
= [[self class] instanceMethodSignatureForSelector
:@selector(dummy
)];
973 post("ERROR: CocoaBridge Failed Creating valid signature for delegate !\n");
977 [mSelectorArray setObject
:signature forKey
:n
];
980 - (void)removeSelector
:(SEL)aSelector
982 NSNumber
* n
= [NSNumber numberWithLong
:(long)aSelector
];
983 [mSelectorArray removeObjectForKey
:n
];
989 these are a still experimental cocoa <-> sc bridge
990 an sc class: NSObjectHolder holds cocoa objects and lets you send and receive
993 prAllocInit { arg classname, initname,args;
995 ^this.primitiveFailed;
1002 int slotGetNSRect(PyrSlot
* a
, NSRect
*r
);
1003 int slotGetPoint(PyrSlot
* a
, NSPoint
*r
);
1005 static int nsinvocationSetArguments(PyrSlot
* args
, NSInvocation
*anInvocation
)
1007 int len
= slotRawObject(args
)->size
;
1008 for(int i
=0; i
<len
; i
++)
1010 PyrSlot
* slot
= slotRawObject(args
)->slots
+i
;
1011 char *cType
= (char *)[[anInvocation methodSignature
] getArgumentTypeAtIndex
: i
+2];
1012 if(*cType
== 'r') ++cType
; // increment and go
1017 if(slotFloatVal(slot
, &val
) != noErr
)
1020 if(*cType
== _C_FLT
) {
1021 [anInvocation setArgument
: &val atIndex
: i
+2];
1023 else if(*cType
== _C_DBL
) {
1024 double dblval
= (double)val
;
1025 [anInvocation setArgument
: &dblval atIndex
: i
+2];
1027 else if(*cType
== _C_INT ||
*cType
== _C_UINT
){
1028 int ival
= (int)val
;
1029 [anInvocation setArgument
: &ival atIndex
: i
+2];
1031 else if(*cType
== _C_LNG ||
*cType
== _C_ULNG
) {
1032 long lval
= (long)val
;
1033 [anInvocation setArgument
: &lval atIndex
: i
+2];
1035 else if(*cType
== _C_SHT ||
*cType
== _C_USHT
) {
1036 short sval
= (short)val
;
1037 [anInvocation setArgument
: &sval atIndex
: i
+2];
1039 else if(*cType
== _C_CHR ||
*cType
== _C_UCHR
) {
1040 char cval
= (char)val
;
1041 [anInvocation setArgument
: &cval atIndex
: i
+2];
1043 else if(*cType
== _C_ID
)
1046 if(slotDoubleVal(slot
, &dval
) != noErr
)
1048 NSNumber
* number
= [NSNumber numberWithDouble
:dval
];
1049 [anInvocation setArgument
: &number atIndex
: i
+2];
1052 post("wrong type (Float / Double) at arg: %i expected float\n", i
);
1053 return errWrongType
;
1057 else if(IsInt(slot
))
1060 if(slotIntVal(slot
, &val
) != noErr
)
1063 if(*cType
== _C_INT ||
*cType
== _C_UINT
) {
1064 [anInvocation setArgument
: &val atIndex
: i
+2];
1066 else if(*cType
== _C_LNG ||
*cType
== _C_ULNG
) {
1067 long lval
= (long)val
;
1068 [anInvocation setArgument
: &lval atIndex
: i
+2];
1070 else if(*cType
== _C_SHT ||
*cType
== _C_USHT
) {
1071 short sval
= (short)val
;
1072 [anInvocation setArgument
: &sval atIndex
: i
+2];
1074 else if(*cType
== _C_CHR ||
*cType
== _C_UCHR
) {
1075 char cval
= (char)val
;
1076 [anInvocation setArgument
: &cval atIndex
: i
+2];
1078 else if(*cType
== _C_FLT
) {
1081 [anInvocation setArgument
: &fval atIndex
: i
+2];
1082 }else if(*cType
== _C_DBL
) {
1085 [anInvocation setArgument
: &fval atIndex
: i
+2];
1086 }else if(*cType
== _C_ID
){
1087 NSNumber
* number
= [NSNumber numberWithInt
:val
];
1088 [anInvocation setArgument
: &number atIndex
: i
+2];
1090 post("wrong type (Integer) at arg: %i expected %c \n", i
, *cType
); return errWrongType
;
1094 isKindOfSlot(slot
, s_nsObject
->u.classobj
) ||
1095 isKindOfSlot(slot
, slotRawSymbol(&s_nsObject
->u.classobj
->superclass
)->u.classobj
)
1098 if(*cType
!= _C_ID
) {
1099 post("wrong type (SCNSObject) at arg: %i expected %c \n", i
, *cType
);
1100 return errWrongType
;
1102 id val
= (id) slotRawPtr(slotRawObject(slot
)->slots
);
1103 [anInvocation setArgument
: &val atIndex
: i
+2];
1105 else if(IsFalse(slot
)) {
1108 [anInvocation setArgument
: &val atIndex
: i
+2];
1110 else if(*cType
== _C_INT ||
*cType
== _C_UINT
) {
1111 int ival
= (int)val
;
1112 [anInvocation setArgument
: &ival atIndex
: i
+2];
1114 else if(*cType
== _C_SHT ||
*cType
== _C_USHT
) {
1115 short sval
= (short)val
;
1116 [anInvocation setArgument
: &sval atIndex
: i
+2];
1118 else if(*cType
== _C_LNG ||
*cType
== _C_ULNG
) {
1119 short lval
= (long)val
;
1120 [anInvocation setArgument
: &lval atIndex
: i
+2];
1122 else if(*cType
== _C_CHR ||
*cType
== _C_UCHR
) {
1123 char cval
= (char)val
;
1124 [anInvocation setArgument
: &cval atIndex
: i
+2];
1126 else if(*cType
== _C_ID
) {
1127 NSNumber
* number
= [NSNumber numberWithBool
:NO
];
1128 [anInvocation setArgument
: &number atIndex
: i
+2];
1131 post("wrong type (Boolean False) at arg: %i expected %c \n", i
, *cType
); return errWrongType
;
1134 else if(IsTrue(slot
)) {
1137 [anInvocation setArgument
: &val atIndex
: i
+2];
1139 else if(*cType
== _C_INT ||
*cType
== _C_UINT
) {
1140 int ival
= (int)val
;
1141 [anInvocation setArgument
: &ival atIndex
: i
+2];
1143 else if(*cType
== _C_SHT ||
*cType
== _C_USHT
) {
1144 short sval
= (short)val
;
1145 [anInvocation setArgument
: &sval atIndex
: i
+2];
1147 else if(*cType
== _C_LNG ||
*cType
== _C_ULNG
) {
1148 short lval
= (long)val
;
1149 [anInvocation setArgument
: &lval atIndex
: i
+2];
1151 else if(*cType
== _C_CHR ||
*cType
== _C_UCHR
) {
1152 char cval
= (char)val
;
1153 [anInvocation setArgument
: &cval atIndex
: i
+2];
1155 else if(*cType
== _C_ID
) {
1156 NSNumber
* number
= [NSNumber numberWithBool
:YES
];
1157 [anInvocation setArgument
: &number atIndex
: i
+2];
1160 post("wrong type (Boolean True) at arg: %i expected %c \n", i
, *cType
); return errWrongType
;
1163 else if(IsNil(slot
))
1165 if(*cType
== _C_ID
) {
1167 [anInvocation setArgument
: (void*)&idval atIndex
: i
+2];
1169 else if(*cType
== _C_PTR
) {
1171 [anInvocation setArgument
: &ptr atIndex
: i
+2];
1173 post("wrong type (Nil) at arg: %i expected %c \n", i
, *cType
); return errWrongType
;
1176 else if (isKindOfSlot(slot
, s_rect
->u.classobj
))
1178 if(*cType
!= _C_STRUCT_B
) {
1179 post("wrong type (Rect) at arg: %i expected %c \n", i
, *cType
);
1180 return errWrongType
;
1184 int err
= slotGetNSRect(slot
, &bounds
);
1185 if (err
) return err
;
1186 [anInvocation setArgument
: &bounds atIndex
: i
+2];
1188 else if (isKindOfSlot(slot
, s_color
->u.classobj
))
1190 if(*cType
!= _C_ID
) {
1191 post("wrong type (Color) at arg: %i expected %c \n", i
, *cType
);
1192 return errWrongType
;
1195 PyrSlot
*slots
= slotRawObject(slot
)->slots
;
1200 err
= slotFloatVal(slots
+0, &r
);
1201 if (err
) return err
;
1202 err
= slotFloatVal(slots
+1, &g
);
1203 if (err
) return err
;
1204 err
= slotFloatVal(slots
+2, &b
);
1205 if (err
) return err
;
1206 err
= slotFloatVal(slots
+3, &a
);
1207 if (err
) return err
;
1209 col
= [NSColor colorWithCalibratedRed
:r green
:g blue
:b alpha
:a
];
1210 [anInvocation setArgument
: &col atIndex
: i
+2];
1212 else if (isKindOfSlot(slot
, s_string
->u.classobj
))
1215 *cType
== _C_CHARPTR ||
1218 char * ch
= slotRawString(slot
)->s
;
1219 if(!ch
) return errFailed
;
1220 [anInvocation setArgument
: (void*) &ch atIndex
: i
+2];
1222 else if(*cType
== _C_ID
) {
1223 NSString
*s
= nsStringFromPyrSlot(slot
);
1224 if(!s
) return errFailed
;
1225 [anInvocation setArgument
: (void*)&s atIndex
: i
+2];
1227 else if(*cType
== _C_SEL
) { // blackrain
1228 NSString
*s
= nsStringFromPyrSlot(slot
);
1229 if(!s
) return errFailed
;
1230 SEL sel
= NSSelectorFromString(s
);
1231 [anInvocation setArgument
: (void*)&sel atIndex
: i
+2];
1234 post("wrong type (String) at arg: %i expected %c \n", i
, *cType
);
1235 return errWrongType
;
1238 else if (isKindOfSlot(slot
, s_point
->u.classobj
))
1240 if(*cType
!= _C_STRUCT_B
) return errWrongType
;
1242 int err
= slotGetPoint(slot
, &point
);
1243 if (err
) return err
;
1244 [anInvocation setArgument
: &point atIndex
: i
+2];
1246 else if (isKindOfSlot(slot
, class_signal
))
1248 float *slotvalues
= (float*)(slotRawObject(slot
)->slots
) ;
1249 [anInvocation setArgument
: &slotvalues atIndex
: i
+2];
1252 else if (isKindOfSlot(slot
, s_int8array
->u.classobj
))
1254 if( *cType
== _C_PTR
) {
1255 void* ptr
= (void*)(((PyrInt8Array
*)slotRawObject(slot
))->b
);
1256 if(!ptr
) return errFailed
;
1257 [anInvocation setArgument
: &ptr atIndex
: i
+2];
1259 post("wrong type (Int8Array) at arg: %i expected %c \n", i
, *cType
); return errWrongType
;
1262 else if (isKindOfSlot(slot
, s_int16array
->u.classobj
))
1264 if( *cType
== _C_PTR
) {
1265 void* ptr
= (void*)(((PyrInt16Array
*)slotRawObject(slot
))->i
);
1266 if(!ptr
) return errFailed
;
1267 [anInvocation setArgument
: &ptr atIndex
: i
+2];
1269 post("wrong type (Int16Array) at arg: %i expected %c \n", i
, *cType
); return errWrongType
;
1272 else if (isKindOfSlot(slot
, s_int32array
->u.classobj
))
1274 if( *cType
== _C_PTR
) {
1275 void* ptr
= (void*)(((PyrInt32Array
*)slotRawObject(slot
))->i
);
1276 if(!ptr
) return errFailed
;
1277 [anInvocation setArgument
: &ptr atIndex
: i
+2];
1279 post("wrong type (Int32Array) at arg: %i expected %c \n", i
, *cType
); return errWrongType
;
1282 else if (isKindOfSlot(slot
, s_doublearray
->u.classobj
))
1284 if( *cType
== _C_PTR
) {
1285 void* ptr
= (void*)(((PyrDoubleArray
*)slotRawObject(slot
))->d
);
1286 if(!ptr
) return errFailed
;
1287 [anInvocation setArgument
: &ptr atIndex
: i
+2];
1289 post("wrong type (DoubleArray) at arg: %i expected %c \n", i
, *cType
); return errWrongType
;
1292 else if (isKindOfSlot(slot
, s_floatarray
->u.classobj
))
1294 if( *cType
== _C_PTR
) {
1295 void* ptr
= (void*)(((PyrFloatArray
*)slotRawObject(slot
))->f
);
1296 if(!ptr
) return errFailed
;
1297 [anInvocation setArgument
: &ptr atIndex
: i
+2];
1299 post("wrong type (FloatArray) at arg: %i expected %c \n", i
, *cType
); return errWrongType
;
1302 else if (isKindOfSlot(slot
, s_arrayed_collection
->u.classobj
))
1304 if(strncmp(cType
, "{_NSSize", 8) == 0) {
1305 NSSize size
= (NSSize
){0.f
, 0.f
};
1307 if(slotRawObject(slot
)->size
> 0) {
1308 if(slotFloatVal(slotRawObject(slot
)->slots
+0, &value
)) return errFailed
;
1311 if(slotRawObject(slot
)->size
> 1) {
1312 if(slotFloatVal(slotRawObject(slot
)->slots
+1, &value
)) return errFailed
;
1313 size.height
= value
;
1315 [anInvocation setArgument
: (void*)&size atIndex
: i
+2];
1317 else if(strncmp(cType
, "{_NSRange", 9) == 0) {
1318 NSRange range
= (NSRange
){0, 0};
1320 if(slotRawObject(slot
)->size
> 0) {
1321 if(slotIntVal(slotRawObject(slot
)->slots
+0, &value
)) return errFailed
;
1322 range.location
= (unsigned int)value
;
1324 if(slotRawObject(slot
)->size
> 1) {
1325 if(slotIntVal(slotRawObject(slot
)->slots
+1, &value
)) return errFailed
;
1326 range.length
= (unsigned int)value
;
1328 [anInvocation setArgument
: (void*)&range atIndex
: i
+2];
1330 else if( strncmp(cType
, "{?=qll}", 6) == 0 ) { // special QTTime structure
1333 PyrSlot
* slots
= slotRawObject(slot
)->slots
;
1335 if(slotRawObject(slot
)->size
< 2) {
1336 post("wrong number of elements in Array : 2 elements expected\n"); return errFailed
;
1340 (long long)(IsInt(slots
+0) ?
slotRawInt(&slots
[0]) : (IsFloat(slots
+0) ?
slotRawFloat(slots
) : 0)),
1341 (long)(IsInt(slots
+1) ?
slotRawInt(&slots
[1]) : (IsFloat(slots
+1) ?
slotRawFloat(&slots
[1]) : 0))
1344 if( slotRawObject(slot
)->size
> 2 )
1345 time.flags
= (long) (IsInt(slots
+2) ?
slotRawInt(&slots
[2]) : (IsFloat(slots
+2) ?
slotRawFloat(&slots
[2]) : 0));
1347 [anInvocation setArgument
: (void*)&time atIndex
: i
+2];
1349 else if( strncmp(cType
, "{?={?=qll}{?=qll}}", 18) == 0 ) { // special QTTimeRange structure
1351 QTTimeRange timeRange
; QTTime
* time
;
1352 if(slotRawObject(slot
)->size
< 2) {
1353 post("wrong number of elements in Array: expected 2 elements\n"); return errFailed
;
1357 for( int i
=0; i
< 2; ++i
) {
1358 if(slotRawObject(&slotRawObject(slot
)->slots
[i
])->size
< 2) {
1359 post("wrong number of elements in sub Array: expected 2 elements\n"); return errFailed
;
1362 slots
= slotRawObject(&slotRawObject(slot
)->slots
[i
])->slots
;
1363 time
= (i
== 0) ?
&timeRange.time
: &timeRange.duration
;
1365 (long long) (IsInt(slots
+0) ?
slotRawInt(&slots
[0]) : (IsFloat(slots
+0) ?
slotRawFloat(slots
) : 0)),
1366 (long) (IsInt(slots
+1) ?
slotRawInt(&slots
[1]) : (IsFloat(slots
+1) ?
slotRawFloat(&slots
[1]) : 0))
1368 if( slotRawObject(slot
)->size
> 2 )
1369 time
->flags
= (long) (IsInt(slots
+2) ?
slotRawInt(&slots
[2]) : (IsFloat(slots
+2) ?
slotRawFloat(&slots
[2]) : 0));
1375 //for now only arrays of SCNSObject
1376 id * nsObjects
= (id*) malloc(slotRawObject(args
)->size
* sizeof(id));
1377 for(int j
=0; j
<slotRawObject(slot
)->size
; j
++)
1379 PyrSlot
* nsslot
= slotRawObject(slot
)->slots
+j
;
1380 nsObjects
[j
] = (id) slotRawPtr(slotRawObject(nsslot
)->slots
);
1382 if(!nsObjects
) return errFailed
;
1383 [anInvocation setArgument
: &nsObjects atIndex
: i
+2];
1387 post("ERROR: bad argument type or Nil argument !\n");
1394 int prObjcAllocInit(struct VMGlobals
*g
, int numArgsPushed
);
1395 int prObjcAllocInit(struct VMGlobals
*g
, int numArgsPushed
)
1397 PyrSlot
*receiver
= g
->sp
- 4;
1398 PyrSlot
*classname
= g
->sp
- 3;
1399 PyrSlot
*initname
= g
->sp
- 2;
1400 PyrSlot
*args
= g
->sp
-1;
1401 PyrSlot
*defer
= g
->sp
;
1404 bool hasArg
= NotNil(args
);
1405 bool isCollection
= isKindOfSlot(args
, class_array
);
1406 NSString
* nsclassname
= nsStringFromPyrSlot(classname
);
1407 if([nsclassname length
] < 1){
1408 post("ERROR: CocoaBridge NSClass name invalid\n");
1413 Class nsclass
= [NSClassFromString( nsclassname
) class];
1415 post("ERROR: CocoaBridge Failed finding valid NSClass\n");
1420 NSString
* nsinitname
= nsStringFromPyrSlot(initname
);
1421 if([nsinitname length
] < 1) {
1422 post("ERROR: CocoaBridge Failed converting method to NSString\n");
1427 //post("Trying Class: %s selector: %s\n", [nsclassname UTF8String], [nsinitname UTF8String]);
1429 SEL sel
= NSSelectorFromString(nsinitname
);
1430 BOOL isInstanceMethod
= [nsclass instancesRespondToSelector
: sel
];
1432 !isInstanceMethod
&&
1433 ((isInstanceMethod
= ![nsclass respondsToSelector
: sel
]) == YES
)
1435 // not an instance method and not a class method
1437 post("Warning: NSClass: %s does not respond to: %s \n", [nsclassname cString
], [nsinitname cString
]);
1442 NSMethodSignature
*sig
= isInstanceMethod ?
[nsclass instanceMethodSignatureForSelector
: sel
] : [nsclass methodSignatureForSelector
: sel
];
1444 post("ERROR: CocoaBridge NSMethodSignature not found\n");
1448 NSInvocation
*anInvocation
= [NSInvocation invocationWithMethodSignature
: sig
];
1450 post("ERROR: CocoaBridge Failed creating NSInvocation\n");
1454 SCVirtualMachine
* scvm
= [SCVirtualMachine sharedInstance
];
1456 int numberOfArgs
= (int) [sig numberOfArguments
] - 2; //cocoa args start at 2
1458 if (hasArg
&& isCollection
&& numberOfArgs
>0)
1460 int len
= slotRawObject(args
)->size
;
1462 //should check for type [sig getArgumentTypeAtIndex: i];
1463 if(numberOfArgs
!= len
)
1465 post("Warning: NSClass: %s numberOfArguments does not match: %i, provided: %i \n", [nsclassname cString
],numberOfArgs
, len
);
1469 int err
= nsinvocationSetArguments(args
, anInvocation
);
1471 post("ERROR: CocoaBridge failed setting arguments for Invocation\n");
1475 } else if (numberOfArgs
>0)
1477 post("Warning: CocoaBridge mismatching arguments \n");
1482 [anInvocation setTarget
: isInstanceMethod ?
[nsclass alloc
] : (id)nsclass
];
1483 [anInvocation setSelector
: sel
];
1486 [scvm defer
: anInvocation
];
1489 PyrObjectHdr
*convertedObject
=NULL
;
1491 const char *cType
=NULL
;
1492 unsigned int length
;
1495 TryInvocation(anInvocation
, receiver
);
1497 cType
= [[anInvocation methodSignature
]methodReturnType
];
1498 length
= [[anInvocation methodSignature
] methodReturnLength
];
1499 //NSLog(@"AllocInit type: %c length: %i", cType, length);
1504 retval
= (void*)malloc(length
);
1505 [anInvocation getReturnValue
: (void*)retval
];
1508 if(ObjcTypeFillPyrSlot(&retslot
, cType
, retval
, &convertedObject
) != noErr
) {
1509 post("ERROR: CocoaBridge returned object type: %c is not-of-type _C_ID !\n", *cType
);
1510 if(retval
) free(retval
);
1514 // If no suitable Cocoa<->SCLang conversion can be done for the object value
1515 if(*cType
== _C_ID
&& !convertedObject
) {
1517 if(IsNil(&retslot
)) { // the returned object is Nil - might lead to EXC_BAD_ACCESS after
1518 SetNil(slotRawObject(receiver
)->slots
+0); // set the dataptr slot to nil
1519 SetNil(receiver
); // return nil
1520 if(retval
) free(retval
);
1521 return errNone
; // should returning nil be considered as an error ?
1524 slotCopy(&slotRawObject(receiver
)->slots
[0], &retslot
);
1525 newThing
= (id) slotRawPtr(slotRawObject(receiver
)->slots
);
1527 if([newThing isKindOfClass
:[NSWindow
class]])
1528 [newThing setReleasedWhenClosed
:NO
]; // prevent user crash for this specific UI
1530 NSString
*classNameString
= NSStringFromClass( [newThing
class] );
1531 PyrString
*pyrClassNameString
= newPyrString(g
->gc
,[classNameString UTF8String
],0,true);
1532 SetObject(slotRawObject(receiver
)->slots
+ 1, pyrClassNameString
);
1534 if(isInstanceMethod
)
1535 [newThing release
]; // retained and added already in ObjcTypeFillPyrSlot
1538 slotCopy(receiver
, &retslot
);
1546 int prObjcSetActionForControl(struct VMGlobals
*g
, int numArgsPushed
);
1547 int prObjcSetActionForControl(struct VMGlobals
*g
, int numArgsPushed
)
1549 PyrSlot
*a
= g
->sp
- 2;
1550 PyrSlot
*b
= g
->sp
- 1;
1552 id objc
= (id) slotRawPtr(slotRawObject(a
)->slots
);
1553 if(!objc
) return errFailed
;
1554 NSString
* actionname
= nsStringFromPyrSlot(c
);
1555 if([actionname length
] < 1){ return errFailed
; }
1556 SEL selAc
= NSSelectorFromString(actionname
);
1558 if(![[objc
class] instancesRespondToSelector
:@selector(setAction
:)])
1560 post("Warning: %s does not respond to setAction:.\n", [[objc className
] UTF8String
]);
1564 SCCocoaToLangAction
*action
= [[SCCocoaToLangAction alloc
] init
];
1568 COCOABRIDGE_OBJ_RETAIN(action
);
1569 [action release
]; // already retained
1571 [action setSCObject
: slotRawObject(b
)];
1573 [objc setAction
: selAc
];
1574 [objc setTarget
: action
];
1576 SetPtr(slotRawObject(b
)->slots
+ 0, action
);
1581 //// Notification Test thelych
1582 int prObjcRegisterNotification(struct VMGlobals
*g
, int numArgsPushed
);
1583 int prObjcRegisterNotification(struct VMGlobals
*g
, int numArgsPushed
)
1586 PyrSlot
*b
= g
->sp
- 1;
1587 PyrSlot
*a
= g
->sp
- 2;
1588 id objc
= (id) slotRawPtr(slotRawObject(a
)->slots
);
1590 if(!objc
) return errFailed
;
1592 if([[objc
class] instancesRespondToSelector
:@selector(delegate
)])
1593 delegate
= [objc delegate
];
1596 //post("ERROR delegate does not exists\n"); // try to recover
1599 IsNil(&(slotRawObject(a
)->slots
[3])) ||
1600 IsNil((slotRawObject(&slotRawObject(a
)->slots
[3]))->slots
)
1602 printf("Error: Slot is nil\n");
1606 delegate
= (id) slotRawPtr(slotRawObject(&slotRawObject(a
)->slots
[3])->slots
); // some objects do not respond to
1607 // setDelegate but do post notifications...
1610 NSString
*notificationName
= nsStringFromPyrSlot(b
);
1611 post([[NSString stringWithFormat
:@
"Registering Notification: %@\n", notificationName
] UTF8String
]);
1613 if (IsNil(c
)) { // br
1615 post("Listening to Notifications from any Object.\n");
1617 objc
= (id) slotRawPtr(slotRawObject(c
)->slots
);
1619 [[NSNotificationCenter defaultCenter
] addObserver
:delegate
1620 selector
:@selector(notificationReceived
:)
1621 name
:notificationName object
:objc
// apply only to object
1627 int prObjcSetDelegate(struct VMGlobals
*g
, int numArgsPushed
);
1628 int prObjcSetDelegate(struct VMGlobals
*g
, int numArgsPushed
)
1630 PyrSlot
*a
= g
->sp
- 1;
1632 id objc
= (id) slotRawPtr(slotRawObject(a
)->slots
);
1634 #pragma mark __TEST_CUSTOM_DELEGATE_
1635 SCCocoaToLangAction
*action
= [[SCCocoaToLangAction alloc
] init
];
1636 post("Warning: creating a special delegate %p\n", action
);
1639 COCOABRIDGE_OBJ_RETAIN(action
);
1640 [action release
]; // already retained
1642 [action setSCObject
: slotRawObject(b
)];
1643 SetPtr(slotRawObject(b
)->slots
+ 0, action
);
1647 if(![[objc
class] instancesRespondToSelector
:@selector(setDelegate
:)])
1649 // setting void action so it can register notifications
1650 SCCocoaToLangAction
*action
= [[SCCocoaToLangAction alloc
] init
];
1651 post("Warning: creating a void delegate\n");
1655 COCOABRIDGE_OBJ_RETAIN(action
);
1656 [action release
]; // already retained
1657 [action setSCObject
: slotRawObject(b
)];
1658 SetPtr(slotRawObject(b
)->slots
+ 0, action
);
1662 // do not create a delegate if a previous delegate exists already
1663 // default delegate can be SCVirtualMachine
1664 if(![objc delegate
]) {
1665 SCCocoaToLangAction
*action
= [[SCCocoaToLangAction alloc
] init
];
1669 COCOABRIDGE_OBJ_RETAIN(action
);
1670 [action release
]; // already retained
1671 [action setSCObject
: slotRawObject(b
)];
1672 [objc setDelegate
: action
];
1673 SetPtr(slotRawObject(b
)->slots
+ 0, action
);
1675 post("Warning: There is already a delegate for this NSObject (%s).\n", [[objc delegate
]className
]);
1676 SetNil(slotRawObject(b
)->slots
+ 0);
1678 post("delegate created successfully for object %p of class %s\n", objc
, [[objc className
]UTF8String
]);
1682 int prObjcGetClass(struct VMGlobals
*g
, int numArgsPushed
);
1683 int prObjcGetClass(struct VMGlobals
*g
, int numArgsPushed
)
1685 PyrSlot
*receiver
= g
->sp
- 1;
1686 PyrSlot
*classname
= g
->sp
;
1688 id nsclass
= [objc_getClass(slotRawString(classname
)->s
) class];
1691 SetPtr(slotRawObject(receiver
)->slots
+ 0, nsclass
);
1695 int prObjcSendMessage(struct VMGlobals
*g
, int numArgsPushed
);
1696 int prObjcSendMessage(struct VMGlobals
*g
, int numArgsPushed
)
1698 PyrSlot
*receiver
= g
->sp
- 2;
1699 PyrSlot
*msgname
= g
->sp
- 1;
1700 PyrSlot
*args
= g
->sp
;
1701 // PyrSlot *defer = g->sp;
1704 // bool hasArg = NotNil(args);
1705 // bool isCollection = isKindOfSlot(args, class_array);
1707 id newThing
= (id) slotRawPtr(slotRawObject(receiver
)->slots
);
1708 if (!newThing
) return errFailed
;
1710 NSString
* nsinitname
= nsStringFromPyrSlot(msgname
);
1711 if([nsinitname length
] < 1){ return errNone
; }
1713 SEL sel
= NSSelectorFromString(nsinitname
);
1717 // slotIntVal(slotRawObject(args)->slots+0, &val);
1718 newThing
= objc_msgSend(newThing
, sel
, args
);
1719 // [newThing retain];
1721 SetPtr(slotRawObject(receiver
)->slots
+ 0, newThing
);
1723 SetNil(slotRawObject(receiver
)->slots
+ 0);
1728 int prObjcAllocSend(struct VMGlobals
*g
, int numArgsPushed
);
1729 int prObjcAllocSend(struct VMGlobals
*g
, int numArgsPushed
)
1731 //under construction ...
1732 PyrSlot
*receiver
= g
->sp
- 3;
1733 PyrSlot
*classname
= g
->sp
- 2;
1734 PyrSlot
*initname
= g
->sp
- 1;
1735 // PyrSlot *args = g->sp;
1738 // bool hasArg = NotNil(args);
1739 // bool isCollection = isKindOfSlot(args, class_array);
1741 NSString
* nsclassname
= nsStringFromPyrSlot(classname
);
1742 if([nsclassname length
] < 1){ return errFailed
; }
1743 NSString
* nsinitname
= nsStringFromPyrSlot(initname
);
1744 if([nsinitname length
] < 1){ return errNone
; }
1746 SEL sel
= NSSelectorFromString(nsinitname
);
1748 // NSMethodSignature *sig = [[NSClassFromString( nsclassname ) class] instanceMethodSignatureForSelector: sel];
1750 id nsclass
= objc_getClass(slotRawString(classname
)->s
);
1753 // slotIntVal(slotRawObject(args)->slots+0, &val);
1754 id newThing
= objc_msgSend(nsclass
, sel
, val
);
1759 slotIntVal(slotRawObject(args
)->slots
+0, &val
);
1761 id newThing
= [[NSClassFromString( nsclassname
) class] sel val
];
1765 SetPtr(slotRawObject(receiver
)->slots
+ 0, newThing
);
1766 // SetInt(slotRawObject(receiver)->slots + 0, 123);
1771 int prObjcGetClassName(struct VMGlobals
*g
, int numArgsPushed
);
1772 int prObjcGetClassName(struct VMGlobals
*g
, int numArgsPushed
)
1774 PyrSlot
*a
= g
->sp
- 1;
1775 // PyrSlot *b = g->sp;
1776 id objc
= (id) slotRawPtr(slotRawObject(a
)->slots
+ 0);
1777 if(!objc
) return errFailed
;
1778 PyrString
*pyrPathString
= newPyrString(g
->gc
, [[objc className
] UTF8String
], 0, true);
1779 SetObject(a
, pyrPathString
);
1783 int prObjcDeferInvocation(struct VMGlobals
*g
, int numArgsPushed
);
1784 int prObjcDeferInvocation(struct VMGlobals
*g
, int numArgsPushed
)
1786 PyrSlot
*receiver
= g
->sp
- 3;
1787 PyrSlot
*initname
= g
->sp
- 2;
1788 PyrSlot
*args
= g
->sp
- 1;
1789 PyrSlot
*defer
= g
->sp
;
1792 return errCantCallOS
; //moght be better to check this ?
1794 bool hasArg
= NotNil(args
) && isKindOfSlot(args
, class_array
);
1795 bool isCollection
= isKindOfSlot(args
, class_array
);
1796 if(!isCollection
) return errFailed
;
1798 // must defer in case of large loads and gui
1799 id newThing
= (id) slotRawPtr(slotRawObject(receiver
)->slots
);
1801 post("ERROR: no valid NSObject to defer Invocation to !\n");
1805 NSString
* nsclassname
= [newThing className
];
1806 Class nsclass
= [NSClassFromString( nsclassname
) class];
1807 NSString
* nsinitname
= nsStringFromPyrSlot(initname
);
1809 if([nsinitname length
] < 1){
1810 post("ERROR: Method argument is invalid !\n");
1814 SEL sel
= NSSelectorFromString(nsinitname
);
1815 if(![nsclass instancesRespondToSelector
:sel
])
1817 post("Warning: %s does not respond to: %s \n", [nsclassname cString
], [nsinitname cString
]);
1821 NSMethodSignature
*sig
= [nsclass instanceMethodSignatureForSelector
: sel
];
1822 NSInvocation
*anInvocation
= [NSInvocation invocationWithMethodSignature
: sig
];
1823 SCVirtualMachine
* scvm
= [SCVirtualMachine sharedInstance
];
1824 [anInvocation setTarget
: newThing
];
1825 [anInvocation setSelector
: sel
];
1827 int numberOfArgs
= (int) [sig numberOfArguments
] - 2; //cocoa args start at 2
1828 int len
= slotRawObject(args
)->size
;
1830 if(len
< numberOfArgs
) return errFailed
;
1831 if(len
> numberOfArgs
) len
= numberOfArgs
;
1835 int err
= nsinvocationSetArguments(args
, anInvocation
);
1840 [anInvocation retainArguments
];
1841 [scvm defer
: anInvocation
];
1845 //?use void objc_msgSend_stret(void * stretAddr, id theReceiver, SEL theSelector, ...);
1846 PyrObjectHdr
*convertedObject
=NULL
;
1847 unsigned int length
= 0;
1849 void *retval
= NULL
;
1851 TryInvocation(anInvocation
, receiver
);
1853 length
= [[anInvocation methodSignature
] methodReturnLength
];
1854 cType
= (char *)[[anInvocation methodSignature
] methodReturnType
];
1856 if(*cType
!= _C_VOID
&& *cType
!= _C_UNDEF
&& (length
> 0)) {
1857 retval
= (void*)malloc(length
);
1858 [anInvocation getReturnValue
: (void*)retval
];
1860 if(ObjcTypeFillPyrSlot(receiver
, cType
, retval
, &convertedObject
) != noErr
) {
1861 post("ERROR: CocoaBridge returned object type: %c is not-of-type _C_ID !\n", *cType
);
1862 if(retval
) free(retval
);
1873 int prObjcDealloc(struct VMGlobals
*g
, int numArgsPushed
);
1874 int prObjcDealloc(struct VMGlobals
*g
, int numArgsPushed
)
1876 //PyrSlot *receiver = g->sp - 1;
1877 PyrSlot
*receiver
= g
->sp
;
1878 //PyrSlot *dataptr = g->sp;
1880 // have to put them in a specific pool so they can be released on command
1881 //if(! IsInt(dataptr) )
1882 // return errWrongType;
1884 //id nsobj = (id)dataptr->ui;
1885 // check retain count and return in case
1886 id nsobj
= (id)slotRawPtr(slotRawObject(receiver
)->slots
);
1888 COCOABRIDGE_OBJ_RELEASE(nsobj
);
1889 SetPtr(slotRawObject(receiver
)->slots
, 0);
1891 post("SCNSObject object pointer is nil\n");
1896 int prObjcLoadBundle(struct VMGlobals
*g
, int numArgsPushed
);
1897 int prObjcLoadBundle(struct VMGlobals
*g
, int numArgsPushed
)
1899 PyrSlot
*a
= g
->sp
- 1;
1900 PyrSlot
*path
= g
->sp
;
1901 //lazy load of a bundle and its principla class as desciped by apple
1902 NSString
* bundlePath
= nsStringFromPyrSlot(path
);
1903 NSBundle
*bundle
= [NSBundle bundleWithPath
:bundlePath
];
1905 SetPtr(slotRawObject(a
)->slots
+ 0, bundle
);
1911 int prObjcBundleAllocPrincipalClass(struct VMGlobals
*g
, int numArgsPushed
);
1912 int prObjcBundleAllocPrincipalClass(struct VMGlobals
*g
, int numArgsPushed
)
1915 PyrSlot
*receiver
= g
->sp
;
1917 // have to put them in a specific pool so they can be released on command
1918 id bundle
= (id) slotRawPtr(slotRawObject(receiver
)->slots
);
1919 if (!bundle
) return errFailed
;
1920 Class principalClass
= [bundle principalClass
];
1921 NSObject
* _bundleObject
= NULL
;
1925 _bundleObject
= [[principalClass alloc
] init
]; // 5
1928 SetPtr(receiver
, _bundleObject
);
1934 int prObjcBundleAllocClassNamed(struct VMGlobals
*g
, int numArgsPushed
);
1935 int prObjcBundleAllocClassNamed(struct VMGlobals
*g
, int numArgsPushed
)
1938 PyrSlot
*receiver
= g
->sp
- 4;
1939 PyrSlot
*name
= g
->sp
- 3;
1940 PyrSlot
*initname
= g
->sp
- 2;
1941 PyrSlot
*args
= g
->sp
-1;
1942 PyrSlot
*defer
= g
->sp
;
1944 bool hasArg
= NotNil(args
);
1945 bool isCollection
= isKindOfSlot(args
, class_array
);
1947 //lazy load of a bundle and its principla class as desciped by apple
1948 NSString
* nsclassname
= nsStringFromPyrSlot(name
);
1949 id bundle
= (id) slotRawPtr(slotRawObject(receiver
)->slots
);
1950 if (!bundle
) return errFailed
;
1951 Class nsclass
= NULL
;
1952 NSObject
* newThing
= NULL
;
1953 nsclass
= [bundle classNamed
:nsclassname
];
1954 if(!nsclass
){SetNil(receiver
); post("class %s not found in bundle\n", [nsclassname cStringUsingEncoding
: NSMacOSRomanStringEncoding
]);return errFailed
;}
1955 // sort out initMethod
1956 NSString
* nsinitname
= nsStringFromPyrSlot(initname
);
1957 if([nsinitname length
] < 1){ SetNil(receiver
); return errFailed
; }
1959 SEL sel
= NSSelectorFromString(nsinitname
);
1960 if(![nsclass instancesRespondToSelector
:sel
])
1963 post("Warning: NSClass: %s does not respond to: %s \n", [nsclassname cString
], [nsinitname cString
]);
1966 NSMethodSignature
*sig
= [nsclass instanceMethodSignatureForSelector
: sel
];
1967 NSInvocation
*anInvocation
= [NSInvocation invocationWithMethodSignature
: sig
];
1968 SCVirtualMachine
* scvm
= [SCVirtualMachine sharedInstance
];
1970 int numberOfArgs
= (int) [sig numberOfArguments
] - 2; //cocoa args start at 2
1972 if (hasArg
&& isCollection
&& numberOfArgs
>0)
1974 int len
= slotRawObject(args
)->size
;
1976 //should check for type [sig getArgumentTypeAtIndex: i];
1977 if(numberOfArgs
!= len
)
1979 post("Warning: NSClass: %s numberOfArguments does not match: %i, provided: %i \n", [nsclassname cString
],numberOfArgs
, len
);
1983 int err
= nsinvocationSetArguments(args
, anInvocation
);
1984 if(err
){ SetNil(receiver
); return err
;}
1987 } else if (numberOfArgs
>0)
1989 post("Warning: mismatching arguments \n");
1993 newThing
= [nsclass alloc
];
1994 [anInvocation setTarget
: newThing
];
1995 [anInvocation setSelector
: sel
];
1998 [scvm defer
: anInvocation
];
2003 [anInvocation invoke
];
2004 [anInvocation getReturnValue
: (void*)&val
];
2005 newThing
= (id) val
;
2007 SetPtr(receiver
, newThing
);
2008 COCOABRIDGE_OBJ_RETAIN(newThing
);
2013 // if(_bundleObject)
2014 // SetPtr(receiver, _bundleObject);
2016 // SetNil(receiver);
2020 int prObjcNSStringToPyrString(struct VMGlobals
*g
, int numArgsPushed
);
2021 int prObjcNSStringToPyrString(struct VMGlobals
*g
, int numArgsPushed
)
2023 PyrSlot
*a
= g
->sp
; // the scns_object
2024 id nsstring
= (id)slotRawPtr(slotRawObject(a
)->slots
);
2025 PyrString
* pyrString
;
2026 NSString
* className
= [nsstring className
];
2028 [nsstring isKindOfClass
:[NSString
class]]
2030 pyrString
= newPyrString(g
->gc
, [(NSString
*)nsstring UTF8String
], 0, true);
2032 pyrString
= newPyrString(g
->gc
, [className UTF8String
], 0, true);
2034 SetObject(a
, pyrString
);
2038 int prObjcIsSubclassOfNSClass(struct VMGlobals
*g
, int numArgsPushed
);
2039 int prObjcIsSubclassOfNSClass(struct VMGlobals
*g
, int numArgsPushed
)
2041 PyrSlot
*a
= g
->sp
- 1;
2045 NSString
*nsstr
= nsStringFromPyrSlot(b
);
2049 Class objcclass
= NSClassFromString(nsstr
);
2050 if(objcclass
!= nil) {
2051 id obj
= (id)slotRawPtr(slotRawObject(a
)->slots
);
2052 if([obj isKindOfClass
:objcclass
]) {
2062 int prObjcDelegateAddSelector(struct VMGlobals
*g
, int numArgsPushed
);
2063 int prObjcDelegateAddSelector(struct VMGlobals
*g
, int numArgsPushed
)
2065 PyrSlot
*a
= g
->sp
- 2;
2066 PyrSlot
*b
= g
->sp
- 1;
2069 char slotString
[64];
2071 SCCocoaToLangAction
* nsobj
= (SCCocoaToLangAction
*)slotRawPtr(slotRawObject(a
)->slots
);
2073 if(!isKindOfSlot(b
, class_string
) ||
!isKindOfSlot(c
, class_string
))
2074 return errWrongType
;
2076 if(slotStrVal(b
, slotString
, 64) != noErr
)
2077 return errWrongType
;
2079 SEL selector
= sel_getUid(slotString
);
2083 if(slotStrVal(c
, slotString
, 64) != noErr
)
2084 return errWrongType
;
2086 [nsobj addSelector
:selector withObjcTypes
:slotString
];
2091 int prObjcDelegateRemoveSelector(struct VMGlobals
*g
, int numArgsPushed
);
2092 int prObjcDelegateRemoveSelector(struct VMGlobals
*g
, int numArgsPushed
)
2094 PyrSlot
*a
= g
->sp
- 1;
2096 SCCocoaToLangAction
* nsobj
= (SCCocoaToLangAction
*)slotRawPtr(slotRawObject(a
)->slots
);
2098 if(!isKindOfSlot(b
, class_string
))
2099 return errWrongType
;
2101 char slotString
[64];
2102 if(slotStrVal(b
, slotString
, 64) != noErr
)
2103 return errWrongType
;
2105 SEL selector
= sel_getUid(slotString
);
2109 [nsobj removeSelector
:selector
];
2113 int prObjcDumpPool(struct VMGlobals
*g
, int numArgsPushed
);
2114 int prObjcDumpPool(struct VMGlobals
*g
, int numArgsPushed
)
2116 #if COCOABRIDGE_STORE_OBJECTS_IN_ARRAY
2121 post("\n--- POOL DUMP %i ---\n", [nsobjects count
]);
2122 NSEnumerator
*e
= [nsobjects objectEnumerator
];
2124 while((obj
= [e nextObject
])) {
2125 post("OBJECT (%p), CLASS (%s), IDX(%i)\n", obj
, [NSStringFromClass([obj
class]) UTF8String
], i
);
2128 post("--- END OF DUMP ---\n");
2133 int prObjcFreePool(struct VMGlobals
*g
, int numArgsPushed
);
2134 int prObjcFreePool(struct VMGlobals
*g
, int numArgsPushed
)
2136 #if COCOABRIDGE_STORE_OBJECTS_IN_ARRAY
2141 [nsobjects removeAllObjects
];
2142 post("POOL FREED\n");
2147 int prObjcNSDataToPyrArray(struct VMGlobals
*g
, int numArgsPushed
);
2148 int prObjcNSDataToPyrArray(struct VMGlobals
*g
, int numArgsPushed
)
2150 PyrSlot
*a
= g
->sp
- 2; // the scns_object
2151 PyrSlot
*b
= g
->sp
- 1; // the array (or string)
2152 PyrSlot
*c
= g
->sp
; // length to retrieve
2154 PyrObject
* pyrarray
= slotRawObject(b
);
2155 PyrClass
* pyrclass
= pyrarray
->classptr
;
2157 NSData
* nsobject
= (NSData
*)slotRawPtr(slotRawObject(a
)->slots
);
2158 int size
=0, nssize
= [nsobject length
]; // in bytes
2160 if(!IsInt(c
) && !IsFloat(c
))
2161 return errWrongType
;
2163 size
= IsFloat(c
) ?
(int)slotRawFloat(c
) : (int)slotRawInt(c
);
2164 if(size
<= 0 || nssize
<= 0) {
2169 if(pyrclass
== class_int8array
) {
2171 size
= sc_min(nssize
, size
);
2172 memcpy(((PyrInt8Array
*)pyrarray
)->b
, [nsobject bytes
], size
);
2174 } else if(pyrclass
== class_int32array
){
2176 size
= sc_min(nssize
, size
/* >> 2*/);
2177 memcpy(((PyrInt32Array
*)pyrarray
)->i
, [nsobject bytes
], size
);
2179 } else if(pyrclass
== class_int16array
) {
2181 size
= sc_min(nssize
, size
/* >> 1*/);
2182 memcpy(((PyrInt32Array
*)pyrarray
)->i
, [nsobject bytes
], size
);
2184 } else if(pyrclass
== class_doublearray
) {
2186 size
= sc_min(nssize
, size
/* >> (sizeof(double)>>1)*/); // double size same for PPC32 - IA32 - IA64 according to Mac ABI
2187 memcpy(((PyrDoubleArray
*)pyrarray
)->d
, [nsobject bytes
], size
);
2189 } else if(pyrclass
== class_floatarray
) {
2191 size
= sc_min(nssize
, size
/*>> (sizeof(float)>>1)*/); // float size same for PPC32 - IA32 - IA64 according to Mac ABI
2192 memcpy(((PyrFloatArray
*)pyrarray
)->f
, [nsobject bytes
], size
);
2194 } else if(pyrclass
== class_string
) {
2196 size
= sc_min(nssize
, size
);
2197 memcpy(((PyrString
*)pyrarray
)->s
, [nsobject bytes
], size
);
2200 return errWrongType
;
2202 //pyrarray->size = size;
2203 SetObject(a
, pyrarray
);
2207 void initCocoaBridgePrimitives()
2211 base
= nextPrimitiveIndex();
2213 s_nsObject
= getsym("SCNSObject");
2215 #if COCOABRIDGE_STORE_OBJECTS_IN_ARRAY
2218 #if COCOABRIDGE_VERBOSITY
2219 NSLog(@
"----- POOL_MNG -----");
2220 NSLog(@
"Number of objects: %i", [nsobjects count
]);
2223 NSEnumerator
* e
= [nsobjects objectEnumerator
];
2224 while((nsobj
= [e nextObject
])) {
2225 if(strcmp(class_getName(nsobj
->isa
->isa
), "FREED(id)") == 0) { // may happen so add verbosity
2226 NSLog(@
"Already FREED NSObject in POOL -> will cause crash");
2230 COCOABRIDGE_POOL_REM_LOG(nsobj
)
2231 if([nsobj isKindOfClass
:[NSWindow
class]]) {
2232 // NSWindows are special since they are directly deallocated (freed - not just released)
2233 // by the windowing system - so we must take care that it won't crash by releasing an already freed reference
2234 // or we should disable this default behaviour
2235 NSWindow
* wobj
= (NSWindow
*)nsobj
;
2236 if([wobj isVisible
]) {
2237 [wobj setReleasedWhenClosed
:NO
]; // otherwise might lead to a crash
2238 //[wobj close]; // close any windows instance
2242 [nsobjects release
]; // will release all references
2245 // nsobjects = [[NSMutableSet setWithCapacity: 8]retain];
2246 nsobjects
= [[NSMutableArray arrayWithCapacity
: 8]retain
];
2249 definePrimitive(base
, index
++, "_ObjC_AllocInit", prObjcAllocInit
, 5, 0);
2250 definePrimitive(base
, index
++, "_ObjC_Dealloc", prObjcDealloc
, 1, 0);
2251 definePrimitive(base
, index
++, "_ObjC_Invoke", prObjcDeferInvocation
, 4, 0);
2252 definePrimitive(base
, index
++, "_ObjC_GetClassName", prObjcGetClassName
, 2, 0);
2253 definePrimitive(base
, index
++, "_ObjC_SetActionForControl", prObjcSetActionForControl
, 3, 0);
2254 definePrimitive(base
, index
++, "_ObjC_SetDelegate", prObjcSetDelegate
, 2, 0);
2255 definePrimitive(base
, index
++, "_ObjC_AllocSend", prObjcAllocSend
, 4, 0);
2256 definePrimitive(base
, index
++, "_ObjC_GetClass", prObjcGetClass
, 2, 0);
2257 definePrimitive(base
, index
++, "_ObjC_SendMessage", prObjcSendMessage
, 3, 0);
2258 definePrimitive(base
, index
++, "_ObjC_LoadBundle", prObjcLoadBundle
, 2, 0);
2259 definePrimitive(base
, index
++, "_ObjcBundleAllocPrincipalClass", prObjcBundleAllocPrincipalClass
, 1, 0);
2260 definePrimitive(base
, index
++, "_ObjcBundleAllocClassNamed", prObjcBundleAllocClassNamed
, 5, 0);
2261 definePrimitive(base
, index
++, "_ObjC_RegisterNotification", prObjcRegisterNotification
, 3, 0); // added cp
2262 definePrimitive(base
, index
++, "_ObjC_NSDataToSCArray", prObjcNSDataToPyrArray
, 3, 0);
2263 definePrimitive(base
, index
++, "_ObjC_NSStringToPyrString", prObjcNSStringToPyrString
, 1, 0);
2264 definePrimitive(base
, index
++, "_ObjC_IsSubclassOfNSClass", prObjcIsSubclassOfNSClass
, 2, 0);
2265 definePrimitive(base
, index
++, "_ObjC_DelegateAddSelector", prObjcDelegateAddSelector
, 3, 0);
2266 definePrimitive(base
, index
++, "_ObjC_DelegateRemoveSelector", prObjcDelegateRemoveSelector
, 2, 0);
2267 definePrimitive(base
, index
++, "_ObjC_DumpPool", prObjcDumpPool
, 1, 0);
2268 definePrimitive(base
, index
++, "_ObjC_FreePool", prObjcFreePool
, 1, 0);