Working with blocks (NSBlock)
Posted: Fri Nov 01, 2013 1:08 pm
Quite a few new Cocoa methods require blocks.
http://clang.llvm.org/docs/Block-ABI-Apple.html
I tried to implement them using PureBasic.
It's important that the block is passed to CocoaMessage by reference using @ otherwise it crashes.
Edit:
Tried to create a bit cleaner implementation as a module
http://www.purebasic.fr/english/viewtop ... 18#p467818
Alternative module
http://www.purebasic.fr/english/viewtop ... 75#p473875
http://clang.llvm.org/docs/Block-ABI-Apple.html
I tried to implement them using PureBasic.
It's important that the block is passed to CocoaMessage by reference using @ otherwise it crashes.
Edit:
Tried to create a bit cleaner implementation as a module
http://www.purebasic.fr/english/viewtop ... 18#p467818
Alternative module
http://www.purebasic.fr/english/viewtop ... 75#p473875
Code: Select all
; *** Global Block code ***
!extern __NSConcreteGlobalBlock
Macro GlobalBlock(BlockName, FunctionName, Sig32, Sig64)
DataSection
CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
FunctionName#_bl_sig:
!db Sig64, 0
FunctionName#_bl_desc:
Data.i 0, 32, ?FunctionName#_bl_sig, 0
FunctionName#_bl_lit:
!dq __NSConcreteGlobalBlock
CompilerElse
FunctionName#_bl_sig:
!db Sig32, 0
FunctionName#_bl_desc:
Data.i 0, 20, ?FunctionName#_bl_sig, 0
FunctionName#_bl_lit:
!dd __NSConcreteGlobalBlock
CompilerEndIf
Data.l $50000000, 0
Data.i @FunctionName#(), ?FunctionName#_bl_desc
EndDataSection
BlockName = CocoaMessage(0, ?FunctionName#_bl_lit, "copy")
EndMacro
; *** End of Global Block code ***
; *** Procedure to wrap inside a block ***
ProcedureC EventMonitor(*Block, Event)
AddGadgetItem(0, -1, "test")
ProcedureReturn Event
EndProcedure
; *** Wrap the procedure ***
GlobalBlock(*Block, EventMonitor, '@"NSEvent"8@?0@"NSEvent"4', '@"NSEvent"16@?0@"NSEvent"8')
; *** Use the block (use @ to pass the block!) ***
CocoaMessage(0, 0, "NSEvent addLocalMonitorForEventsMatchingMask:", 2, "handler:@", @*Block); *Block is executed when left mouse button is pressed
; *** Main code ***
If OpenWindow(0, 100, 200, 195, 260, "PureBasic Window", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
EditorGadget(0, 10, 10, 175, 240)
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf