diff --git a/basis/cocoa/plists/plists.factor b/basis/cocoa/plists/plists.factor index 31b59a6eac..ceb097bb3a 100644 --- a/basis/cocoa/plists/plists.factor +++ b/basis/cocoa/plists/plists.factor @@ -4,7 +4,7 @@ USING: strings arrays hashtables assocs sequences fry macros cocoa.messages cocoa.classes cocoa.application cocoa kernel namespaces io.backend math cocoa.enumeration byte-arrays -combinators alien.c-types words core-foundation +combinators alien.c-types words core-foundation quotations core-foundation.data core-foundation.utilities ; IN: cocoa.plists @@ -41,10 +41,16 @@ DEFER: plist> *void* [ -> release "read-plist failed" throw ] when* ; MACRO: objc-class-case ( alist -- quot ) - [ [ '[ dup _ execute -> isKindOfClass: c-bool> ] ] dip ] assoc-map '[ _ cond ] ; + [ + dup callable? + [ first2 [ '[ dup _ execute -> isKindOfClass: c-bool> ] ] dip 2array ] + unless + ] map '[ _ cond ] ; PRIVATE> +ERROR: invalid-plist-object object ; + : plist> ( plist -- value ) { { NSString [ (plist-NSString>) ] } @@ -53,6 +59,7 @@ PRIVATE> { NSArray [ (plist-NSArray>) ] } { NSDictionary [ (plist-NSDictionary>) ] } { NSObject [ ] } + [ invalid-plist-object ] } objc-class-case ; : read-plist ( path -- assoc ) diff --git a/extra/game-input/iokit/iokit.factor b/extra/game-input/iokit/iokit.factor index de1529f8df..5f09a054f9 100755 --- a/extra/game-input/iokit/iokit.factor +++ b/extra/game-input/iokit/iokit.factor @@ -1,13 +1,15 @@ USING: cocoa cocoa.plists core-foundation iokit iokit.hid kernel cocoa.enumeration destructors math.parser cocoa.application sequences locals combinators.short-circuit threads -namespaces assocs vectors arrays combinators +namespaces assocs vectors arrays combinators hints alien core-foundation.run-loop accessors sequences.private alien.c-types math parser game-input vectors ; IN: game-input.iokit SINGLETON: iokit-game-input-backend +SYMBOLS: +hid-manager+ +keyboard-state+ +mouse-state+ +controller-states+ ; + iokit-game-input-backend game-input-backend set-global : hid-manager-matching ( matching-seq -- alien ) @@ -23,7 +25,6 @@ iokit-game-input-backend game-input-backend set-global CONSTANT: game-devices-matching-seq { - H{ { "DeviceUsage" 1 } { "DeviceUsagePage" 1 } } ! pointers H{ { "DeviceUsage" 2 } { "DeviceUsagePage" 1 } } ! mouses H{ { "DeviceUsage" 4 } { "DeviceUsagePage" 1 } } ! joysticks H{ { "DeviceUsage" 5 } { "DeviceUsagePage" 1 } } ! gamepads @@ -88,19 +89,17 @@ CONSTANT: hat-switch-matching-hash game-devices-matching-seq hid-manager-matching ; : device-property ( device key -- value ) - IOHIDDeviceGetProperty plist> ; + IOHIDDeviceGetProperty [ plist> ] [ f ] if* ; : element-property ( element key -- value ) - IOHIDElementGetProperty plist> ; + IOHIDElementGetProperty [ plist> ] [ f ] if* ; : set-element-property ( element key value -- ) [ ] [ >plist ] bi* IOHIDElementSetProperty drop ; : transfer-element-property ( element from-key to-key -- ) - [ dupd element-property ] dip swap set-element-property ; + [ dupd element-property ] dip swap + [ set-element-property ] [ 2drop ] if* ; : mouse-device? ( device -- ? ) - { - [ 1 1 IOHIDDeviceConformsTo ] - [ 1 2 IOHIDDeviceConformsTo ] - } 1|| ; + 1 2 IOHIDDeviceConformsTo ; : controller-device? ( device -- ? ) { @@ -113,28 +112,31 @@ CONSTANT: hat-switch-matching-hash [ IOHIDElementGetUsagePage ] [ IOHIDElementGetUsage ] bi 2array ; -: button? ( {usage-page,usage} -- ? ) - first 9 = ; inline -: keyboard-key? ( {usage-page,usage} -- ? ) - first 7 = ; inline +: button? ( element -- ? ) + IOHIDElementGetUsagePage 9 = ; inline +: keyboard-key? ( element -- ? ) + IOHIDElementGetUsagePage 7 = ; inline +: axis? ( element -- ? ) + IOHIDElementGetUsagePage 1 = ; inline + : x-axis? ( {usage-page,usage} -- ? ) - { 1 HEX: 30 } = ; inline + IOHIDElementGetUsage HEX: 30 = ; inline : y-axis? ( {usage-page,usage} -- ? ) - { 1 HEX: 31 } = ; inline + IOHIDElementGetUsage HEX: 31 = ; inline : z-axis? ( {usage-page,usage} -- ? ) - { 1 HEX: 32 } = ; inline + IOHIDElementGetUsage HEX: 32 = ; inline : rx-axis? ( {usage-page,usage} -- ? ) - { 1 HEX: 33 } = ; inline + IOHIDElementGetUsage HEX: 33 = ; inline : ry-axis? ( {usage-page,usage} -- ? ) - { 1 HEX: 34 } = ; inline + IOHIDElementGetUsage HEX: 34 = ; inline : rz-axis? ( {usage-page,usage} -- ? ) - { 1 HEX: 35 } = ; inline + IOHIDElementGetUsage HEX: 35 = ; inline : slider? ( {usage-page,usage} -- ? ) - { 1 HEX: 36 } = ; inline + IOHIDElementGetUsage HEX: 36 = ; inline : wheel? ( {usage-page,usage} -- ? ) - { 1 HEX: 38 } = ; inline + IOHIDElementGetUsage HEX: 38 = ; inline : hat-switch? ( {usage-page,usage} -- ? ) - { 1 HEX: 39 } = ; inline + IOHIDElementGetUsage HEX: 39 = ; inline CONSTANT: pov-values { @@ -152,45 +154,55 @@ CONSTANT: pov-values : pov-value ( value -- pov-direction ) IOHIDValueGetIntegerValue pov-values ?nth [ pov-neutral ] unless* ; -: record-button ( hid-value usage state -- ) - [ button-value ] [ second 1- ] [ buttons>> ] tri* set-nth ; +: record-button ( state hid-value element -- ) + [ buttons>> ] [ button-value ] [ IOHIDElementGetUsage 1- ] tri* rot set-nth ; : record-controller ( controller-state value -- ) - dup IOHIDValueGetElement element-usage { - { [ dup button? ] [ rot record-button ] } - { [ dup x-axis? ] [ drop axis-value >>x drop ] } - { [ dup y-axis? ] [ drop axis-value >>y drop ] } - { [ dup z-axis? ] [ drop axis-value >>z drop ] } - { [ dup rx-axis? ] [ drop axis-value >>rx drop ] } - { [ dup ry-axis? ] [ drop axis-value >>ry drop ] } - { [ dup rz-axis? ] [ drop axis-value >>rz drop ] } - { [ dup slider? ] [ drop axis-value >>slider drop ] } - { [ dup hat-switch? ] [ drop pov-value >>pov drop ] } + dup IOHIDValueGetElement { + { [ dup button? ] [ record-button ] } + { [ dup axis? ] [ { + { [ dup x-axis? ] [ drop axis-value >>x drop ] } + { [ dup y-axis? ] [ drop axis-value >>y drop ] } + { [ dup z-axis? ] [ drop axis-value >>z drop ] } + { [ dup rx-axis? ] [ drop axis-value >>rx drop ] } + { [ dup ry-axis? ] [ drop axis-value >>ry drop ] } + { [ dup rz-axis? ] [ drop axis-value >>rz drop ] } + { [ dup slider? ] [ drop axis-value >>slider drop ] } + { [ dup hat-switch? ] [ drop pov-value >>pov drop ] } + [ 3drop ] + } cond ] } [ 3drop ] } cond ; -SYMBOLS: +hid-manager+ +keyboard-state+ +mouse-state+ +controller-states+ ; +HINTS: record-controller { controller-state alien } ; : ?set-nth ( value nth seq -- ) 2dup bounds-check? [ set-nth-unsafe ] [ 3drop ] if ; -: record-keyboard ( value -- ) - dup IOHIDValueGetElement element-usage keyboard-key? [ +: record-keyboard ( keyboard-state value -- ) + dup IOHIDValueGetElement dup keyboard-key? [ [ IOHIDValueGetIntegerValue c-bool> ] - [ IOHIDValueGetElement IOHIDElementGetUsage ] bi - +keyboard-state+ get ?set-nth - ] [ drop ] if ; + [ IOHIDElementGetUsage ] bi* + rot ?set-nth + ] [ 3drop ] if ; -: record-mouse ( value -- ) - dup IOHIDValueGetElement element-usage { - { [ dup button? ] [ +mouse-state+ get record-button ] } - { [ dup x-axis? ] [ drop mouse-axis-value +mouse-state+ get [ + ] change-dx drop ] } - { [ dup y-axis? ] [ drop mouse-axis-value +mouse-state+ get [ + ] change-dy drop ] } - { [ dup wheel? ] [ drop mouse-axis-value +mouse-state+ get [ + ] change-scroll-dx drop ] } - { [ dup z-axis? ] [ drop mouse-axis-value +mouse-state+ get [ + ] change-scroll-dy drop ] } - [ 2drop ] +HINTS: record-keyboard { array alien } ; + +: record-mouse ( mouse-state value -- ) + dup IOHIDValueGetElement { + { [ dup button? ] [ record-button ] } + { [ dup axis? ] [ { + { [ dup x-axis? ] [ drop mouse-axis-value [ + ] curry change-dx drop ] } + { [ dup y-axis? ] [ drop mouse-axis-value [ + ] curry change-dy drop ] } + { [ dup wheel? ] [ drop mouse-axis-value [ + ] curry change-scroll-dx drop ] } + { [ dup z-axis? ] [ drop mouse-axis-value [ + ] curry change-scroll-dy drop ] } + [ 3drop ] + } cond ] } + [ 3drop ] } cond ; +HINTS: record-mouse { mouse-state alien } ; + M: iokit-game-input-backend read-mouse +mouse-state+ get ; @@ -263,8 +275,8 @@ M: iokit-game-input-backend reset-mouse { [ sender controller-device? ] [ sender +controller-states+ get at value record-controller ] } - { [ sender mouse-device? ] [ value record-mouse ] } - [ value record-keyboard ] + { [ sender mouse-device? ] [ +mouse-state+ get value record-mouse ] } + [ +keyboard-state+ get value record-keyboard ] } cond ] IOHIDValueCallback ; @@ -289,7 +301,7 @@ M: iokit-game-input-backend (open-game-input) } cleave ; M: iokit-game-input-backend (reset-game-input) - { +hid-manager+ +keyboard-state+ +controller-states+ } + { +hid-manager+ +keyboard-state+ +mouse-state+ +controller-states+ } [ f swap set-global ] each ; M: iokit-game-input-backend (close-game-input)