From 5d5ce370f1ecbf7dc5487a49663fffc80b314ef7 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Sun, 24 Oct 2021 05:02:12 +0900 Subject: [PATCH] internal/uidriver/mobile: Implement Vibrate on iOS Updates #1452 --- internal/uidriver/mobile/gamepad_ios.go | 4 +- internal/uidriver/mobile/ui.go | 5 - internal/uidriver/mobile/vibrate_android.go | 23 +++++ internal/uidriver/mobile/vibrate_ios.go | 106 ++++++++++++++++++++ vibrate.go | 1 - 5 files changed, 131 insertions(+), 8 deletions(-) create mode 100644 internal/uidriver/mobile/vibrate_android.go create mode 100644 internal/uidriver/mobile/vibrate_ios.go diff --git a/internal/uidriver/mobile/gamepad_ios.go b/internal/uidriver/mobile/gamepad_ios.go index 1a71fb37d..298ba38b8 100644 --- a/internal/uidriver/mobile/gamepad_ios.go +++ b/internal/uidriver/mobile/gamepad_ios.go @@ -417,7 +417,7 @@ package mobile // } // } // -// static void init(void) { +// static void initializeGamepads(void) { // controllers = [NSMutableArray array]; // controllerProperties = [NSMutableArray array]; // @@ -453,7 +453,7 @@ import ( ) func init() { - C.init() + C.initializeGamepads() } func (i *Input) updateGamepads() { diff --git a/internal/uidriver/mobile/ui.go b/internal/uidriver/mobile/ui.go index 21f85b58b..3e8ca62a0 100644 --- a/internal/uidriver/mobile/ui.go +++ b/internal/uidriver/mobile/ui.go @@ -22,7 +22,6 @@ import ( "runtime/debug" "sync" "sync/atomic" - "time" "unicode" "golang.org/x/mobile/app" @@ -493,7 +492,3 @@ func (u *UserInterface) ScheduleFrame() { u.renderRequester.RequestRenderIfNeeded() } } - -func (u *UserInterface) Vibrate(duration time.Duration) { - // TODO: Implement this (#1452) -} diff --git a/internal/uidriver/mobile/vibrate_android.go b/internal/uidriver/mobile/vibrate_android.go new file mode 100644 index 000000000..658a5d7de --- /dev/null +++ b/internal/uidriver/mobile/vibrate_android.go @@ -0,0 +1,23 @@ +// Copyright 2021 The Ebiten Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package mobile + +import ( + "time" +) + +func (u *UserInterface) Vibrate(duration time.Duration) { + // TODO: Implement this (#1452) +} diff --git a/internal/uidriver/mobile/vibrate_ios.go b/internal/uidriver/mobile/vibrate_ios.go new file mode 100644 index 000000000..2e7eff3b5 --- /dev/null +++ b/internal/uidriver/mobile/vibrate_ios.go @@ -0,0 +1,106 @@ +// Copyright 2021 The Ebiten Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build ios +// +build ios + +package mobile + +// #cgo LDFLAGS: -framework CoreHaptics +// +// #import +// +// static CHHapticEngine* engine; +// +// static void initializeVibrate(void) { +// if (!CHHapticEngine.capabilitiesForHardware.supportsHaptics) { +// return; +// } +// +// NSError* error = nil; +// engine = [[CHHapticEngine alloc] initAndReturnError:&error]; +// if (error) { +// return; +// } +// +// [engine startAndReturnError:&error]; +// if (error) { +// return; +// } +// } +// +// static void vibrate(double duration) { +// if (!engine) { +// return; +// } +// +// @autoreleasepool { +// NSDictionary* hapticDict = @{ +// CHHapticPatternKeyPattern: @[ +// @{ +// CHHapticPatternKeyEvent: @{ +// CHHapticPatternKeyEventType:CHHapticEventTypeHapticContinuous, +// CHHapticPatternKeyTime:@0.0, +// CHHapticPatternKeyEventDuration:[NSNumber numberWithDouble:duration], +// CHHapticPatternKeyEventParameters:@[ +// @{ +// CHHapticPatternKeyParameterID: CHHapticEventParameterIDHapticIntensity, +// CHHapticPatternKeyParameterValue: @1.0, +// }, +// ], +// }, +// }, +// ], +// }; +// +// NSError* error = nil; +// CHHapticPattern* pattern = [[CHHapticPattern alloc] initWithDictionary:hapticDict +// error:&error]; +// if (error) { +// return; +// } +// +// id player = [engine createPlayerWithPattern:pattern +// error:&error]; +// if (error) { +// return; +// } +// +// [player startAtTime:0 error:&error]; +// if (error) { +// NSLog(@"3, %@", [error localizedDescription]); +// return; +// } +// } +// } +// +import "C" + +import ( + "sync" + "time" +) + +func init() { + C.initializeVibrate() +} + +var vibrationM sync.Mutex + +func (u *UserInterface) Vibrate(duration time.Duration) { + vibrationM.Lock() + defer vibrationM.Unlock() + + C.vibrate(C.double(float64(duration) / float64(time.Second))) +} diff --git a/vibrate.go b/vibrate.go index 1af70df14..948d33aad 100644 --- a/vibrate.go +++ b/vibrate.go @@ -21,7 +21,6 @@ import ( // Vibrate vibrates the device. // // Vibrate works on mobiles and browsers. -// On browsers, StrongManitude and WeakMagnitude might be ignored. // // Vibrate is concurrent-safe. func Vibrate(duration time.Duration) {