From 6e3eba8ef78a23cbbb9de280ccf95164981b0913 Mon Sep 17 00:00:00 2001 From: Xephoidia Date: Wed, 23 Oct 2024 21:00:54 -0400 Subject: [PATCH 01/18] Add basic outline for individual actuator control --- src/game/components/GameVibrator.tsx | 3 ++ .../components/ToyActuatorSettings.tsx | 26 ++++++++++++ src/settings/components/ToySettings.tsx | 27 ++++++++++++ src/settings/components/VibratorSettings.tsx | 5 ++- src/utils/toyactuator.tsx | 41 +++++++++++++++++++ src/utils/vibrator.tsx | 12 +++++- 6 files changed, 111 insertions(+), 3 deletions(-) create mode 100644 src/settings/components/ToyActuatorSettings.tsx create mode 100644 src/settings/components/ToySettings.tsx create mode 100644 src/utils/toyactuator.tsx diff --git a/src/game/components/GameVibrator.tsx b/src/game/components/GameVibrator.tsx index 7ed42337..5239bf1f 100644 --- a/src/game/components/GameVibrator.tsx +++ b/src/game/components/GameVibrator.tsx @@ -22,6 +22,9 @@ export const GameVibrator = () => { useEffect(() => { const { intensity, pace, devices, mode } = data.current; + devices.forEach(device => + device.actuators.forEach(() => console.log('actuator activated')) + ); switch (stroke) { case Stroke.up: switch (mode) { diff --git a/src/settings/components/ToyActuatorSettings.tsx b/src/settings/components/ToyActuatorSettings.tsx new file mode 100644 index 00000000..27fef654 --- /dev/null +++ b/src/settings/components/ToyActuatorSettings.tsx @@ -0,0 +1,26 @@ +// import { useActuatorSettings } from '../../utils' +import { ToyActuator } from '../../utils/toyactuator'; +import { PropsWithChildren } from 'react'; +// import { Vibrator } from '../../utils/vibrator'; +import { SettingsTile } from '../../common'; +import { SettingsDescription } from '../../common/SettingsDescription'; + +export interface ToySettingsProps + extends PropsWithChildren> { + toyActuator: ToyActuator; +} + +export const ToyActuatorSettings: React.FC = ({ + toyActuator, +}) => { + const actuatorType = toyActuator.actuatorType; + const index = toyActuator.index; + + return ( + + + This component is not yet supported. + + + ); +}; diff --git a/src/settings/components/ToySettings.tsx b/src/settings/components/ToySettings.tsx new file mode 100644 index 00000000..49d6e9c1 --- /dev/null +++ b/src/settings/components/ToySettings.tsx @@ -0,0 +1,27 @@ +import { Vibrator } from '../../utils/vibrator'; +import { ToyActuatorSettings } from './ToyActuatorSettings'; +import { SettingsTile } from '../../common'; +import { PropsWithChildren } from 'react'; +import { type ToyActuator } from '../../utils/toyactuator'; +import { SettingsDescription } from '../../common/SettingsDescription'; + +export interface ToySettingsProps + extends PropsWithChildren> { + key: number; + device: Vibrator; +} + +export const ToySettings: React.FC = ({ key, device }) => { + return ( +
  • + + + Change the settings for each controllable component on your toy. + + {device.actuators.map((a: ToyActuator) => ( + + ))} + +
  • + ); +}; diff --git a/src/settings/components/VibratorSettings.tsx b/src/settings/components/VibratorSettings.tsx index 89e0216b..1c144f2a 100644 --- a/src/settings/components/VibratorSettings.tsx +++ b/src/settings/components/VibratorSettings.tsx @@ -20,6 +20,7 @@ import styled from 'styled-components'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faGear } from '@fortawesome/free-solid-svg-icons'; import { AnimatePresence, motion } from 'framer-motion'; +import { ToySettings } from './ToySettings'; const StyledDeviceList = styled.ul` list-style: none; @@ -169,7 +170,9 @@ export const VibratorSettings = () => { <> {devices.length > 0 ? ( - devices.map((device, index) =>
  • {device.name}
  • ) + devices.map((device: Vibrator, index: number) => ( + + )) ) : (
  • No devices found
  • )} diff --git a/src/utils/toyactuator.tsx b/src/utils/toyactuator.tsx new file mode 100644 index 00000000..4391b052 --- /dev/null +++ b/src/utils/toyactuator.tsx @@ -0,0 +1,41 @@ +import { type GenericDeviceMessageAttributes, ActuatorType } from 'buttplug'; +import { createStateProvider } from './state'; + +export enum ActuatorMode { + alwaysOn = 'alwaysOn', + alwaysOff = 'alwaysOff', + activeUp = 'activeUp', + activeDown = 'activeDown', +} + +export class ToyActuator { + index: number; + actuatorType: ActuatorType; + intensity: number = 0; + pace: number = 0; + + constructor(attributes: GenericDeviceMessageAttributes) { + this.actuatorType = attributes.ActuatorType; + this.index = attributes.Index; + } +} + +export class VibrationActuator extends ToyActuator {} + +export interface ToyActuatorSettings { + index: number; + actuatorType: ActuatorType; + mode: ActuatorMode; +} + +export const { + Provider: ActuatorProvider, + useProvider: useActuator, + useProviderSelector: useActuatorValue, +} = createStateProvider({ + defaultData: { + index: -1, + actuatorType: ActuatorType.Unknown, + mode: ActuatorMode.activeUp, + }, +}); diff --git a/src/utils/vibrator.tsx b/src/utils/vibrator.tsx index fe17d2d9..8c019415 100644 --- a/src/utils/vibrator.tsx +++ b/src/utils/vibrator.tsx @@ -1,6 +1,7 @@ import { createStateProvider } from './state'; import { ButtplugClient, type ButtplugClientDevice } from 'buttplug'; import { wait } from './wait'; +import { type ToyActuator, VibrationActuator } from './toyactuator'; export enum VibrationMode { constant = 'constant', @@ -9,8 +10,15 @@ export enum VibrationMode { export class Vibrator { private commandId = 0; - - constructor(private readonly device: ButtplugClientDevice) {} + actuators: ToyActuator[] = []; + + constructor(private readonly device: ButtplugClientDevice) { + console.log(device.vibrateAttributes); + device.vibrateAttributes.forEach( + attribute => + (this.actuators = [...this.actuators, new VibrationActuator(attribute)]) + ); + } async setVibration(intensity: number): Promise { ++this.commandId; From 9ca6c32e31f84fcef79316d1f03baa74a4e7102b Mon Sep 17 00:00:00 2001 From: Xephoidia Date: Thu, 24 Oct 2024 20:39:57 -0400 Subject: [PATCH 02/18] Make actuator object update with UI --- .../components/ToyActuatorSettings.tsx | 62 ++++++++++++++++--- src/utils/toyactuator.tsx | 39 +++++++----- 2 files changed, 78 insertions(+), 23 deletions(-) diff --git a/src/settings/components/ToyActuatorSettings.tsx b/src/settings/components/ToyActuatorSettings.tsx index 27fef654..bc988afd 100644 --- a/src/settings/components/ToyActuatorSettings.tsx +++ b/src/settings/components/ToyActuatorSettings.tsx @@ -1,9 +1,16 @@ // import { useActuatorSettings } from '../../utils' -import { ToyActuator } from '../../utils/toyactuator'; -import { PropsWithChildren } from 'react'; +import { + ToyActuator, + VibrationActuator, + ActuatorMode, + ActuatorModeLabels, +} from '../../utils/toyactuator'; +import { PropsWithChildren, useState } from 'react'; // import { Vibrator } from '../../utils/vibrator'; import { SettingsTile } from '../../common'; import { SettingsDescription } from '../../common/SettingsDescription'; +import { Dropdown } from '../../common/Dropdown'; +import { ActuatorType } from 'buttplug'; export interface ToySettingsProps extends PropsWithChildren> { @@ -13,14 +20,55 @@ export interface ToySettingsProps export const ToyActuatorSettings: React.FC = ({ toyActuator, }) => { - const actuatorType = toyActuator.actuatorType; - const index = toyActuator.index; + return ( + + {(() => { + switch (toyActuator.actuatorType) { + case ActuatorType.Vibrate: + return ; + default: + return ; + } + })()} + + ); +}; + +export const VibratorActuatorSettings: React.FC = ({ + toyActuator, +}) => { + const vibratorActuator = toyActuator as VibrationActuator; + const descriptor = `${vibratorActuator.actuatorType}_${vibratorActuator.index}`; + const [mode, setMode] = useState(vibratorActuator.mode); return ( - +
    - This component is not yet supported. + Select when this component will activate. - + { + const newMode = value as ActuatorMode; + setMode(newMode); + vibratorActuator.setMode(newMode); + }} + options={Object.values(ActuatorMode).map(value => ({ + value, + label: ActuatorModeLabels[value], + }))} + /> +
    + ); +}; + +export const UnknownActuatorSettings = () => { + return ( + + This component is not currently supported. + ); }; diff --git a/src/utils/toyactuator.tsx b/src/utils/toyactuator.tsx index 4391b052..23ee6585 100644 --- a/src/utils/toyactuator.tsx +++ b/src/utils/toyactuator.tsx @@ -1,5 +1,4 @@ import { type GenericDeviceMessageAttributes, ActuatorType } from 'buttplug'; -import { createStateProvider } from './state'; export enum ActuatorMode { alwaysOn = 'alwaysOn', @@ -8,7 +7,14 @@ export enum ActuatorMode { activeDown = 'activeDown', } -export class ToyActuator { +export const ActuatorModeLabels: Record = { + [ActuatorMode.alwaysOn]: 'Always On', + [ActuatorMode.alwaysOff]: 'Always Off', + [ActuatorMode.activeUp]: 'Active on Upstroke', + [ActuatorMode.activeDown]: 'Active on Downstroke', +}; + +export class ToyActuator implements ToyActuatorSettings { index: number; actuatorType: ActuatorType; intensity: number = 0; @@ -20,22 +26,23 @@ export class ToyActuator { } } -export class VibrationActuator extends ToyActuator {} +export class VibrationActuator + extends ToyActuator + implements VibrationActuatorSettings +{ + mode: ActuatorMode = ActuatorMode.activeUp; + + setMode(newMode: ActuatorMode) { + this.mode = newMode; + console.log(`${this.actuatorType} ${this.index} mode set to ${newMode}`); + } +} + +export interface VibrationActuatorSettings { + mode: ActuatorMode; +} export interface ToyActuatorSettings { index: number; actuatorType: ActuatorType; - mode: ActuatorMode; } - -export const { - Provider: ActuatorProvider, - useProvider: useActuator, - useProviderSelector: useActuatorValue, -} = createStateProvider({ - defaultData: { - index: -1, - actuatorType: ActuatorType.Unknown, - mode: ActuatorMode.activeUp, - }, -}); From 2fd0e951db2d424ce9fde2f6c165a144dd284584 Mon Sep 17 00:00:00 2001 From: Xephoidia Date: Thu, 24 Oct 2024 22:08:11 -0400 Subject: [PATCH 03/18] Add basic toyActuator functionality in game --- src/game/components/GameVibrator.tsx | 56 ++++++++++++++++++++-------- src/utils/toyactuator.tsx | 5 +-- src/utils/vibrator.tsx | 4 +- 3 files changed, 45 insertions(+), 20 deletions(-) diff --git a/src/game/components/GameVibrator.tsx b/src/game/components/GameVibrator.tsx index 5239bf1f..c60d1eb8 100644 --- a/src/game/components/GameVibrator.tsx +++ b/src/game/components/GameVibrator.tsx @@ -2,6 +2,8 @@ import { useEffect, useState } from 'react'; import { GamePhase, Stroke, useGameValue } from '../GameProvider'; import { useAutoRef, useVibratorValue, VibrationMode, wait } from '../../utils'; import { useSetting } from '../../settings'; +import { ActuatorType } from 'buttplug'; +import { ActuatorMode, VibrationActuator } from '../../utils/toyactuator'; export const GameVibrator = () => { const [stroke] = useGameValue('stroke'); @@ -22,28 +24,50 @@ export const GameVibrator = () => { useEffect(() => { const { intensity, pace, devices, mode } = data.current; + console.log(`${pace} ${mode}`); devices.forEach(device => device.actuators.forEach(() => console.log('actuator activated')) ); - switch (stroke) { - case Stroke.up: - switch (mode) { - case VibrationMode.constant: { - const strength = intensity / 100; - devices.forEach(device => device.setVibration(strength)); + devices.forEach(device => { + const vibrationArray: number[] = []; + device.actuators.forEach(actuator => { + switch (actuator.actuatorType) { + case ActuatorType.Vibrate: + { + const vibrationActuator = actuator as VibrationActuator; + let vibrationValue = 0; + switch (vibrationActuator.mode) { + case ActuatorMode.activeUp: + if (stroke == Stroke.up) { + vibrationValue = intensity / 100; + } else { + vibrationValue = 0; + } + break; + case ActuatorMode.activeDown: + if (stroke == Stroke.down) { + vibrationValue = intensity / 100; + } else { + vibrationValue = 0; + } + break; + case ActuatorMode.alwaysOn: + vibrationValue = intensity / 100; + break; + case ActuatorMode.alwaysOff: + break; + } + vibrationArray[vibrationActuator.index] = vibrationValue; + } break; - } - case VibrationMode.thump: { - const length = (1 / pace) * 1000; - const strength = Math.max(0.25, intensity / 100); - devices.forEach(device => device.thump(length, strength)); + default: break; - } } - break; - case Stroke.down: - break; - } + }); + if (vibrationArray.length > 0) { + device.setVibration(vibrationArray); + } + }); }, [data, stroke]); useEffect(() => { diff --git a/src/utils/toyactuator.tsx b/src/utils/toyactuator.tsx index 23ee6585..bd263c7e 100644 --- a/src/utils/toyactuator.tsx +++ b/src/utils/toyactuator.tsx @@ -17,8 +17,6 @@ export const ActuatorModeLabels: Record = { export class ToyActuator implements ToyActuatorSettings { index: number; actuatorType: ActuatorType; - intensity: number = 0; - pace: number = 0; constructor(attributes: GenericDeviceMessageAttributes) { this.actuatorType = attributes.ActuatorType; @@ -31,15 +29,16 @@ export class VibrationActuator implements VibrationActuatorSettings { mode: ActuatorMode = ActuatorMode.activeUp; + intensity: number = 0; setMode(newMode: ActuatorMode) { this.mode = newMode; - console.log(`${this.actuatorType} ${this.index} mode set to ${newMode}`); } } export interface VibrationActuatorSettings { mode: ActuatorMode; + intensity: number; } export interface ToyActuatorSettings { diff --git a/src/utils/vibrator.tsx b/src/utils/vibrator.tsx index 8c019415..50f1e271 100644 --- a/src/utils/vibrator.tsx +++ b/src/utils/vibrator.tsx @@ -20,9 +20,11 @@ export class Vibrator { ); } - async setVibration(intensity: number): Promise { + async setVibration(intensity: number | number[]): Promise { ++this.commandId; + console.log(`setting intensity to ${intensity}`); await this.device.vibrate(intensity); + console.log(`finished setting intensity to ${intensity}`); } async thump(timeout: number, intensity = 1): Promise { From a8eea4d2cdccebbb1125760c96a723275eeba9a0 Mon Sep 17 00:00:00 2001 From: Xephoidia Date: Mon, 28 Oct 2024 23:40:25 -0400 Subject: [PATCH 04/18] Add intensity range to vibrator control --- src/game/components/GameVibrator.tsx | 34 +++--------- .../components/ToyActuatorSettings.tsx | 38 +++++++++++++ src/utils/toyactuator.tsx | 54 ++++++++++++++++++- 3 files changed, 96 insertions(+), 30 deletions(-) diff --git a/src/game/components/GameVibrator.tsx b/src/game/components/GameVibrator.tsx index c60d1eb8..1cff0681 100644 --- a/src/game/components/GameVibrator.tsx +++ b/src/game/components/GameVibrator.tsx @@ -1,9 +1,8 @@ import { useEffect, useState } from 'react'; -import { GamePhase, Stroke, useGameValue } from '../GameProvider'; +import { GamePhase, useGameValue } from '../GameProvider'; import { useAutoRef, useVibratorValue, VibrationMode, wait } from '../../utils'; import { useSetting } from '../../settings'; import { ActuatorType } from 'buttplug'; -import { ActuatorMode, VibrationActuator } from '../../utils/toyactuator'; export const GameVibrator = () => { const [stroke] = useGameValue('stroke'); @@ -33,32 +32,11 @@ export const GameVibrator = () => { device.actuators.forEach(actuator => { switch (actuator.actuatorType) { case ActuatorType.Vibrate: - { - const vibrationActuator = actuator as VibrationActuator; - let vibrationValue = 0; - switch (vibrationActuator.mode) { - case ActuatorMode.activeUp: - if (stroke == Stroke.up) { - vibrationValue = intensity / 100; - } else { - vibrationValue = 0; - } - break; - case ActuatorMode.activeDown: - if (stroke == Stroke.down) { - vibrationValue = intensity / 100; - } else { - vibrationValue = 0; - } - break; - case ActuatorMode.alwaysOn: - vibrationValue = intensity / 100; - break; - case ActuatorMode.alwaysOff: - break; - } - vibrationArray[vibrationActuator.index] = vibrationValue; - } + vibrationArray[actuator.index] = actuator.getOutput?.( + stroke, + intensity, + pace + ) as number; break; default: break; diff --git a/src/settings/components/ToyActuatorSettings.tsx b/src/settings/components/ToyActuatorSettings.tsx index bc988afd..6ee41cca 100644 --- a/src/settings/components/ToyActuatorSettings.tsx +++ b/src/settings/components/ToyActuatorSettings.tsx @@ -11,6 +11,8 @@ import { SettingsTile } from '../../common'; import { SettingsDescription } from '../../common/SettingsDescription'; import { Dropdown } from '../../common/Dropdown'; import { ActuatorType } from 'buttplug'; +import { Space } from '../../common/Space'; +import { SettingsLabel } from '../../common/SettingsLabel'; export interface ToySettingsProps extends PropsWithChildren> { @@ -42,6 +44,8 @@ export const VibratorActuatorSettings: React.FC = ({ const vibratorActuator = toyActuator as VibrationActuator; const descriptor = `${vibratorActuator.actuatorType}_${vibratorActuator.index}`; const [mode, setMode] = useState(vibratorActuator.mode); + const [min, setMin] = useState(vibratorActuator.minIntensity); + const [max, setMax] = useState(vibratorActuator.maxIntensity); return (
    @@ -61,6 +65,40 @@ export const VibratorActuatorSettings: React.FC = ({ label: ActuatorModeLabels[value], }))} /> + + + Change the range of intensity for this component. + + From + { + const newMin = +value; + if (newMin > vibratorActuator.maxIntensity) return; + setMin(newMin); + vibratorActuator.setMinIntensity(newMin); + }} + options={vibratorActuator.intensityRange.map(value => ({ + value: `${value}`, + label: `${(value * 100).toFixed(0)}%`, + }))} + /> + To + { + const newMax = +value; + if (newMax < vibratorActuator.minIntensity) return; + setMax(newMax); + vibratorActuator.setMaxIntensity(newMax); + }} + options={vibratorActuator.intensityRange.map(value => ({ + value: `${value}`, + label: `${(value * 100).toFixed(0)}%`, + }))} + />
    ); }; diff --git a/src/utils/toyactuator.tsx b/src/utils/toyactuator.tsx index bd263c7e..55d2ae14 100644 --- a/src/utils/toyactuator.tsx +++ b/src/utils/toyactuator.tsx @@ -1,4 +1,5 @@ import { type GenericDeviceMessageAttributes, ActuatorType } from 'buttplug'; +import { Stroke } from '../game/GameProvider'; export enum ActuatorMode { alwaysOn = 'alwaysOn', @@ -22,6 +23,8 @@ export class ToyActuator implements ToyActuatorSettings { this.actuatorType = attributes.ActuatorType; this.index = attributes.Index; } + + getOutput?(stroke: Stroke, intensity: number, pace: number): unknown; } export class VibrationActuator @@ -29,16 +32,63 @@ export class VibrationActuator implements VibrationActuatorSettings { mode: ActuatorMode = ActuatorMode.activeUp; - intensity: number = 0; + minIntensity: number = 0; + maxIntensity: number = 1.0; + intensityRange: number[] = []; + + constructor(attributes: GenericDeviceMessageAttributes) { + super(attributes); + const intensityStep = 100 / attributes.StepCount / 100.0; + for (let i = 0; i <= attributes.StepCount; ++i) { + this.intensityRange[i] = intensityStep * i; + } + } setMode(newMode: ActuatorMode) { this.mode = newMode; } + + setMinIntensity(newMin: number) { + this.minIntensity = newMin; + } + + setMaxIntensity(newMax: number) { + this.maxIntensity = newMax; + } + + override getOutput(stroke: Stroke, intensity: number) { + let output = this.minIntensity; + switch (this.mode) { + case ActuatorMode.activeUp: + if (stroke == Stroke.up) { + output = this.mapToRange(intensity / 100); + } + break; + case ActuatorMode.activeDown: + if (stroke == Stroke.down) { + output = this.mapToRange(intensity / 100); + } + break; + case ActuatorMode.alwaysOn: + output = this.mapToRange(intensity / 100); + break; + case ActuatorMode.alwaysOff: + output = 0; + break; + } + return output; + } + + mapToRange(input: number): number { + const slope = this.maxIntensity - this.minIntensity; + return this.minIntensity + slope * input; + } } export interface VibrationActuatorSettings { mode: ActuatorMode; - intensity: number; + minIntensity: number; + maxIntensity: number; } export interface ToyActuatorSettings { From cc88f0ef8328347e7559713e23503e5bd12f5741 Mon Sep 17 00:00:00 2001 From: Xephoidia Date: Tue, 29 Oct 2024 18:06:43 -0400 Subject: [PATCH 05/18] Fix vibe activating when it shouldn't --- src/utils/toyactuator.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/utils/toyactuator.tsx b/src/utils/toyactuator.tsx index 55d2ae14..7d6662eb 100644 --- a/src/utils/toyactuator.tsx +++ b/src/utils/toyactuator.tsx @@ -57,7 +57,7 @@ export class VibrationActuator } override getOutput(stroke: Stroke, intensity: number) { - let output = this.minIntensity; + let output = 0; switch (this.mode) { case ActuatorMode.activeUp: if (stroke == Stroke.up) { @@ -73,7 +73,6 @@ export class VibrationActuator output = this.mapToRange(intensity / 100); break; case ActuatorMode.alwaysOff: - output = 0; break; } return output; From 4290fa3b0a2bc2efa847cc1193814dc27818f66e Mon Sep 17 00:00:00 2001 From: Xephoidia Date: Tue, 29 Oct 2024 18:24:10 -0400 Subject: [PATCH 06/18] Revert "Fix vibe activating when it shouldn't" This reverts commit cc88f0ef8328347e7559713e23503e5bd12f5741. --- src/utils/toyactuator.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/utils/toyactuator.tsx b/src/utils/toyactuator.tsx index 7d6662eb..55d2ae14 100644 --- a/src/utils/toyactuator.tsx +++ b/src/utils/toyactuator.tsx @@ -57,7 +57,7 @@ export class VibrationActuator } override getOutput(stroke: Stroke, intensity: number) { - let output = 0; + let output = this.minIntensity; switch (this.mode) { case ActuatorMode.activeUp: if (stroke == Stroke.up) { @@ -73,6 +73,7 @@ export class VibrationActuator output = this.mapToRange(intensity / 100); break; case ActuatorMode.alwaysOff: + output = 0; break; } return output; From c49e4b78222590b8dc638cfad8b0c53ee7477032 Mon Sep 17 00:00:00 2001 From: Xephoidia Date: Tue, 29 Oct 2024 21:16:15 -0400 Subject: [PATCH 07/18] Remove VibrationMode and thump --- src/game/components/GameVibrator.tsx | 40 +++++++++++----------------- src/settings/SettingsProvider.tsx | 4 +-- src/utils/toyactuator.tsx | 1 + src/utils/vibrator.tsx | 17 ++---------- 4 files changed, 20 insertions(+), 42 deletions(-) diff --git a/src/game/components/GameVibrator.tsx b/src/game/components/GameVibrator.tsx index 1cff0681..db18dcf0 100644 --- a/src/game/components/GameVibrator.tsx +++ b/src/game/components/GameVibrator.tsx @@ -1,7 +1,6 @@ import { useEffect, useState } from 'react'; import { GamePhase, useGameValue } from '../GameProvider'; -import { useAutoRef, useVibratorValue, VibrationMode, wait } from '../../utils'; -import { useSetting } from '../../settings'; +import { useAutoRef, useVibratorValue, wait } from '../../utils'; import { ActuatorType } from 'buttplug'; export const GameVibrator = () => { @@ -9,21 +8,18 @@ export const GameVibrator = () => { const [intensity] = useGameValue('intensity'); const [pace] = useGameValue('pace'); const [phase] = useGameValue('phase'); - const [mode] = useSetting('vibrations'); const [devices] = useVibratorValue('devices'); const data = useAutoRef({ intensity, pace, devices, - mode, }); const [currentPhase, setCurrentPhase] = useState(phase); useEffect(() => { - const { intensity, pace, devices, mode } = data.current; - console.log(`${pace} ${mode}`); + const { intensity, pace, devices } = data.current; devices.forEach(device => device.actuators.forEach(() => console.log('actuator activated')) ); @@ -32,6 +28,7 @@ export const GameVibrator = () => { device.actuators.forEach(actuator => { switch (actuator.actuatorType) { case ActuatorType.Vibrate: + console.log(`Actual intensity: ${intensity}`); vibrationArray[actuator.index] = actuator.getOutput?.( stroke, intensity, @@ -49,26 +46,21 @@ export const GameVibrator = () => { }, [data, stroke]); useEffect(() => { - const { devices, mode } = data.current; + const { devices } = data.current; if (currentPhase == phase) return; - if ([GamePhase.break, GamePhase.pause].includes(phase)) { - devices.forEach(device => device.setVibration(0)); - } - if (phase === GamePhase.climax) { - (async () => { - for (let i = 0; i < 15; i++) { - const strength = Math.max(0, 1 - i * 0.067); - switch (mode) { - case VibrationMode.constant: - devices.forEach(device => device.setVibration(strength)); - break; - case VibrationMode.thump: - devices.forEach(device => device.thump(400, strength)); - break; + switch (phase) { + case GamePhase.pause: + case GamePhase.break: + devices.forEach(device => device.stop()); + break; + case GamePhase.climax: + (async () => { + for (let i = 0; i < 15; i++) { + const strength = Math.max(0, 1 - i * 0.067); + devices.forEach(device => device.setVibration(strength)); + await wait(400); } - await wait(400); - } - })(); + })(); } setCurrentPhase(phase); }, [data, currentPhase, phase]); diff --git a/src/settings/SettingsProvider.tsx b/src/settings/SettingsProvider.tsx index 64816ec0..14aa216b 100644 --- a/src/settings/SettingsProvider.tsx +++ b/src/settings/SettingsProvider.tsx @@ -1,6 +1,6 @@ import { useCallback } from 'react'; import { GameEvent, GameHypnoType, PlayerBody, PlayerGender } from '../types'; -import { createLocalStorageProvider, VibrationMode } from '../utils'; +import { createLocalStorageProvider } from '../utils'; import { interpolateWith } from '../utils/translate'; export interface Settings { @@ -18,7 +18,6 @@ export interface Settings { body: PlayerBody; highRes: boolean; videoSound: boolean; - vibrations: VibrationMode; } export const defaultSettings: Settings = { @@ -36,7 +35,6 @@ export const defaultSettings: Settings = { body: PlayerBody.penis, highRes: false, videoSound: false, - vibrations: VibrationMode.thump, }; const settingsStorageKey = 'settings'; diff --git a/src/utils/toyactuator.tsx b/src/utils/toyactuator.tsx index 55d2ae14..33afe810 100644 --- a/src/utils/toyactuator.tsx +++ b/src/utils/toyactuator.tsx @@ -76,6 +76,7 @@ export class VibrationActuator output = 0; break; } + console.log(`Setting ${this.actuatorType} ${this.index} to ${output}`); return output; } diff --git a/src/utils/vibrator.tsx b/src/utils/vibrator.tsx index 50f1e271..936391b6 100644 --- a/src/utils/vibrator.tsx +++ b/src/utils/vibrator.tsx @@ -1,15 +1,8 @@ import { createStateProvider } from './state'; import { ButtplugClient, type ButtplugClientDevice } from 'buttplug'; -import { wait } from './wait'; import { type ToyActuator, VibrationActuator } from './toyactuator'; -export enum VibrationMode { - constant = 'constant', - thump = 'thump', -} - export class Vibrator { - private commandId = 0; actuators: ToyActuator[] = []; constructor(private readonly device: ButtplugClientDevice) { @@ -21,19 +14,13 @@ export class Vibrator { } async setVibration(intensity: number | number[]): Promise { - ++this.commandId; console.log(`setting intensity to ${intensity}`); await this.device.vibrate(intensity); console.log(`finished setting intensity to ${intensity}`); } - async thump(timeout: number, intensity = 1): Promise { - const id = ++this.commandId; - await this.device.vibrate(intensity); - await wait(timeout); - if (id === this.commandId) { - await this.device.stop(); - } + async stop() { + await this.device.stop(); } get name(): string { From 82779d42a41102d41254a37e891ad65abc9ec5cb Mon Sep 17 00:00:00 2001 From: Xephoidia Date: Tue, 29 Oct 2024 22:17:51 -0400 Subject: [PATCH 08/18] Fix util and component exporting --- src/settings/components/ToyActuatorSettings.tsx | 2 +- src/settings/components/ToySettings.tsx | 2 +- src/settings/components/index.ts | 1 + src/utils/index.ts | 1 + 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/settings/components/ToyActuatorSettings.tsx b/src/settings/components/ToyActuatorSettings.tsx index 6ee41cca..e9fb402f 100644 --- a/src/settings/components/ToyActuatorSettings.tsx +++ b/src/settings/components/ToyActuatorSettings.tsx @@ -4,7 +4,7 @@ import { VibrationActuator, ActuatorMode, ActuatorModeLabels, -} from '../../utils/toyactuator'; +} from '../../utils'; import { PropsWithChildren, useState } from 'react'; // import { Vibrator } from '../../utils/vibrator'; import { SettingsTile } from '../../common'; diff --git a/src/settings/components/ToySettings.tsx b/src/settings/components/ToySettings.tsx index 49d6e9c1..b736050e 100644 --- a/src/settings/components/ToySettings.tsx +++ b/src/settings/components/ToySettings.tsx @@ -2,7 +2,7 @@ import { Vibrator } from '../../utils/vibrator'; import { ToyActuatorSettings } from './ToyActuatorSettings'; import { SettingsTile } from '../../common'; import { PropsWithChildren } from 'react'; -import { type ToyActuator } from '../../utils/toyactuator'; +import { type ToyActuator } from '../../utils'; import { SettingsDescription } from '../../common/SettingsDescription'; export interface ToySettingsProps diff --git a/src/settings/components/index.ts b/src/settings/components/index.ts index bf45d051..bd935953 100644 --- a/src/settings/components/index.ts +++ b/src/settings/components/index.ts @@ -10,3 +10,4 @@ export * from './ServiceSettings'; export * from './TradeSettings'; export * from './VibratorSettings'; export * from './WalltakerSettings'; +export * from './ToySettings'; diff --git a/src/utils/index.ts b/src/utils/index.ts index c0c1952b..171bbb0e 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -13,3 +13,4 @@ export * from './state'; export * from './translate'; export * from './vibrator'; export * from './wait'; +export * from './toyactuator'; From f0802455cacf1e7b8f955d1bcaa7e1f8c5fa593f Mon Sep 17 00:00:00 2001 From: Xephoidia Date: Tue, 29 Oct 2024 22:24:21 -0400 Subject: [PATCH 09/18] Rename Vibrator class to ToyClient --- src/game/components/GameVibrator.tsx | 4 ++-- src/index.tsx | 6 +++--- src/settings/components/ToySettings.tsx | 4 ++-- src/settings/components/VibratorSettings.tsx | 16 ++++++++-------- src/utils/vibrator.tsx | 14 +++++++------- 5 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/game/components/GameVibrator.tsx b/src/game/components/GameVibrator.tsx index db18dcf0..3bd8d70c 100644 --- a/src/game/components/GameVibrator.tsx +++ b/src/game/components/GameVibrator.tsx @@ -1,6 +1,6 @@ import { useEffect, useState } from 'react'; import { GamePhase, useGameValue } from '../GameProvider'; -import { useAutoRef, useVibratorValue, wait } from '../../utils'; +import { useAutoRef, useToyClientValue, wait } from '../../utils'; import { ActuatorType } from 'buttplug'; export const GameVibrator = () => { @@ -8,7 +8,7 @@ export const GameVibrator = () => { const [intensity] = useGameValue('intensity'); const [pace] = useGameValue('pace'); const [phase] = useGameValue('phase'); - const [devices] = useVibratorValue('devices'); + const [devices] = useToyClientValue('devices'); const data = useAutoRef({ intensity, diff --git a/src/index.tsx b/src/index.tsx index 6273059e..4e7e171f 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -4,7 +4,7 @@ import { App } from './app/App.tsx'; import './index.css'; import { SettingsProvider, ImageProvider } from './settings'; import { E621Provider } from './e621'; -import { VibratorProvider } from './utils'; +import { ToyClientProvider } from './utils'; import { LocalImageProvider } from './local/LocalProvider.tsx'; ReactDOM.createRoot(document.getElementById('root')!).render( @@ -12,11 +12,11 @@ ReactDOM.createRoot(document.getElementById('root')!).render( - + - + diff --git a/src/settings/components/ToySettings.tsx b/src/settings/components/ToySettings.tsx index b736050e..9125b9d9 100644 --- a/src/settings/components/ToySettings.tsx +++ b/src/settings/components/ToySettings.tsx @@ -1,4 +1,4 @@ -import { Vibrator } from '../../utils/vibrator'; +import { ToyClient } from '../../utils/vibrator'; import { ToyActuatorSettings } from './ToyActuatorSettings'; import { SettingsTile } from '../../common'; import { PropsWithChildren } from 'react'; @@ -8,7 +8,7 @@ import { SettingsDescription } from '../../common/SettingsDescription'; export interface ToySettingsProps extends PropsWithChildren> { key: number; - device: Vibrator; + device: ToyClient; } export const ToySettings: React.FC = ({ key, device }) => { diff --git a/src/settings/components/VibratorSettings.tsx b/src/settings/components/VibratorSettings.tsx index 1c144f2a..1b387b28 100644 --- a/src/settings/components/VibratorSettings.tsx +++ b/src/settings/components/VibratorSettings.tsx @@ -11,7 +11,7 @@ import { SettingsLabel, Spinner, } from '../../common'; -import { defaultTransition, useVibratorValue, Vibrator } from '../../utils'; +import { defaultTransition, useToyClientValue, ToyClient } from '../../utils'; import { ButtplugBrowserWebsocketClientConnector, ButtplugClientDevice, @@ -41,10 +41,10 @@ const StyledUrlFields = styled.div` `; export const VibratorSettings = () => { - const [client] = useVibratorValue('client'); - const [connection, setConnection] = useVibratorValue('connection'); - const [devices, setDevices] = useVibratorValue('devices'); - const [error, setError] = useVibratorValue('error'); + const [client] = useToyClientValue('client'); + const [connection, setConnection] = useToyClientValue('connection'); + const [devices, setDevices] = useToyClientValue('devices'); + const [error, setError] = useToyClientValue('error'); const [loading, setLoading] = useState(false); const [host, setHost] = useState('127.0.0.1'); @@ -74,10 +74,10 @@ export const VibratorSettings = () => { await client.connect(new ButtplugBrowserWebsocketClientConnector(url)); await client.startScanning(); client.devices.forEach(e => - setDevices(devices => [...devices, new Vibrator(e)]) + setDevices(devices => [...devices, new ToyClient(e)]) ); client.addListener('deviceadded', (device: ButtplugClientDevice) => { - setDevices(devices => [...devices, new Vibrator(device)]); + setDevices(devices => [...devices, new ToyClient(device)]); }); client.addListener('deviceremoved', (device: ButtplugClientDevice) => { setDevices(devices => devices.filter(e => e.name !== device.name)); @@ -170,7 +170,7 @@ export const VibratorSettings = () => { <> {devices.length > 0 ? ( - devices.map((device: Vibrator, index: number) => ( + devices.map((device: ToyClient, index: number) => ( )) ) : ( diff --git a/src/utils/vibrator.tsx b/src/utils/vibrator.tsx index 936391b6..b437e94e 100644 --- a/src/utils/vibrator.tsx +++ b/src/utils/vibrator.tsx @@ -2,7 +2,7 @@ import { createStateProvider } from './state'; import { ButtplugClient, type ButtplugClientDevice } from 'buttplug'; import { type ToyActuator, VibrationActuator } from './toyactuator'; -export class Vibrator { +export class ToyClient { actuators: ToyActuator[] = []; constructor(private readonly device: ButtplugClientDevice) { @@ -28,18 +28,18 @@ export class Vibrator { } } -export interface VibratorSettings { +export interface ToyClientSettings { client: ButtplugClient; connection?: string; - devices: Vibrator[]; + devices: ToyClient[]; error?: string; } export const { - Provider: VibratorProvider, - useProvider: useVibrators, - useProviderSelector: useVibratorValue, -} = createStateProvider({ + Provider: ToyClientProvider, + useProvider: useToyClients, + useProviderSelector: useToyClientValue, +} = createStateProvider({ defaultData: { client: new ButtplugClient('JOI.how'), devices: [], From b739954d5860a0ea98625804061b035b51afba67 Mon Sep 17 00:00:00 2001 From: Xephoidia Date: Tue, 29 Oct 2024 22:26:09 -0400 Subject: [PATCH 10/18] Rename files to match new class names --- src/game/components/{GameVibrator.tsx => GameToyClient.tsx} | 0 src/game/components/index.ts | 2 +- .../components/{VibratorSettings.tsx => ToyClientSettings.tsx} | 0 src/settings/components/ToySettings.tsx | 2 +- src/settings/components/index.ts | 2 +- src/utils/index.ts | 2 +- src/utils/{vibrator.tsx => toyclient.tsx} | 0 7 files changed, 4 insertions(+), 4 deletions(-) rename src/game/components/{GameVibrator.tsx => GameToyClient.tsx} (100%) rename src/settings/components/{VibratorSettings.tsx => ToyClientSettings.tsx} (100%) rename src/utils/{vibrator.tsx => toyclient.tsx} (100%) diff --git a/src/game/components/GameVibrator.tsx b/src/game/components/GameToyClient.tsx similarity index 100% rename from src/game/components/GameVibrator.tsx rename to src/game/components/GameToyClient.tsx diff --git a/src/game/components/index.ts b/src/game/components/index.ts index 4cb0ba1e..85a504e0 100644 --- a/src/game/components/index.ts +++ b/src/game/components/index.ts @@ -10,5 +10,5 @@ export * from './GameMeter'; export * from './GamePace'; export * from './GameSettings'; export * from './GameSound'; -export * from './GameVibrator'; +export * from './GameToyClient'; export * from './GameWarmup'; diff --git a/src/settings/components/VibratorSettings.tsx b/src/settings/components/ToyClientSettings.tsx similarity index 100% rename from src/settings/components/VibratorSettings.tsx rename to src/settings/components/ToyClientSettings.tsx diff --git a/src/settings/components/ToySettings.tsx b/src/settings/components/ToySettings.tsx index 9125b9d9..35e53448 100644 --- a/src/settings/components/ToySettings.tsx +++ b/src/settings/components/ToySettings.tsx @@ -1,4 +1,4 @@ -import { ToyClient } from '../../utils/vibrator'; +import { ToyClient } from '../../utils/toyclient'; import { ToyActuatorSettings } from './ToyActuatorSettings'; import { SettingsTile } from '../../common'; import { PropsWithChildren } from 'react'; diff --git a/src/settings/components/index.ts b/src/settings/components/index.ts index bd935953..6ad87f60 100644 --- a/src/settings/components/index.ts +++ b/src/settings/components/index.ts @@ -8,6 +8,6 @@ export * from './PaceSettings'; export * from './PlayerSettings'; export * from './ServiceSettings'; export * from './TradeSettings'; -export * from './VibratorSettings'; +export * from './ToyClientSettings'; export * from './WalltakerSettings'; export * from './ToySettings'; diff --git a/src/utils/index.ts b/src/utils/index.ts index 171bbb0e..8adf0ce5 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -11,6 +11,6 @@ export * from './setters'; export * from './sound'; export * from './state'; export * from './translate'; -export * from './vibrator'; +export * from './toyclient'; export * from './wait'; export * from './toyactuator'; diff --git a/src/utils/vibrator.tsx b/src/utils/toyclient.tsx similarity index 100% rename from src/utils/vibrator.tsx rename to src/utils/toyclient.tsx From 3f7fd3e0df10f492c73f3551db5c84806ef9ce24 Mon Sep 17 00:00:00 2001 From: Xephoidia Date: Tue, 29 Oct 2024 23:14:46 -0400 Subject: [PATCH 11/18] Code cleanup --- src/game/components/GameToyClient.tsx | 30 +++++++++++++++++++++------ src/utils/toyactuator.tsx | 1 - src/utils/toyclient.tsx | 3 --- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/game/components/GameToyClient.tsx b/src/game/components/GameToyClient.tsx index 3bd8d70c..83dad8c4 100644 --- a/src/game/components/GameToyClient.tsx +++ b/src/game/components/GameToyClient.tsx @@ -1,6 +1,11 @@ import { useEffect, useState } from 'react'; import { GamePhase, useGameValue } from '../GameProvider'; -import { useAutoRef, useToyClientValue, wait } from '../../utils'; +import { + useAutoRef, + useToyClientValue, + wait, + VibrationActuator, +} from '../../utils'; import { ActuatorType } from 'buttplug'; export const GameVibrator = () => { @@ -20,15 +25,11 @@ export const GameVibrator = () => { useEffect(() => { const { intensity, pace, devices } = data.current; - devices.forEach(device => - device.actuators.forEach(() => console.log('actuator activated')) - ); devices.forEach(device => { const vibrationArray: number[] = []; device.actuators.forEach(actuator => { switch (actuator.actuatorType) { case ActuatorType.Vibrate: - console.log(`Actual intensity: ${intensity}`); vibrationArray[actuator.index] = actuator.getOutput?.( stroke, intensity, @@ -57,7 +58,24 @@ export const GameVibrator = () => { (async () => { for (let i = 0; i < 15; i++) { const strength = Math.max(0, 1 - i * 0.067); - devices.forEach(device => device.setVibration(strength)); + devices.forEach(device => { + const vibrationArray: number[] = []; + device.actuators.forEach(actuator => { + switch (actuator.actuatorType) { + case ActuatorType.Vibrate: { + const vibrationActuator = actuator as VibrationActuator; + vibrationArray[actuator.index] = + vibrationActuator.mapToRange(strength); + break; + } + default: + break; + } + if (vibrationArray.length > 0) { + device.setVibration(vibrationArray); + } + }); + }); await wait(400); } })(); diff --git a/src/utils/toyactuator.tsx b/src/utils/toyactuator.tsx index 33afe810..55d2ae14 100644 --- a/src/utils/toyactuator.tsx +++ b/src/utils/toyactuator.tsx @@ -76,7 +76,6 @@ export class VibrationActuator output = 0; break; } - console.log(`Setting ${this.actuatorType} ${this.index} to ${output}`); return output; } diff --git a/src/utils/toyclient.tsx b/src/utils/toyclient.tsx index b437e94e..88ee2dd5 100644 --- a/src/utils/toyclient.tsx +++ b/src/utils/toyclient.tsx @@ -6,7 +6,6 @@ export class ToyClient { actuators: ToyActuator[] = []; constructor(private readonly device: ButtplugClientDevice) { - console.log(device.vibrateAttributes); device.vibrateAttributes.forEach( attribute => (this.actuators = [...this.actuators, new VibrationActuator(attribute)]) @@ -14,9 +13,7 @@ export class ToyClient { } async setVibration(intensity: number | number[]): Promise { - console.log(`setting intensity to ${intensity}`); await this.device.vibrate(intensity); - console.log(`finished setting intensity to ${intensity}`); } async stop() { From 12cb8432857675a6765e99f6b8c34b938bbe434e Mon Sep 17 00:00:00 2001 From: Xephoidia Date: Wed, 30 Oct 2024 19:50:59 -0400 Subject: [PATCH 12/18] Move business logic into ToyClient class --- src/game/components/GameToyClient.tsx | 53 +++------------------------ src/utils/toyclient.tsx | 51 ++++++++++++++++++++++++-- 2 files changed, 53 insertions(+), 51 deletions(-) diff --git a/src/game/components/GameToyClient.tsx b/src/game/components/GameToyClient.tsx index 83dad8c4..3e091161 100644 --- a/src/game/components/GameToyClient.tsx +++ b/src/game/components/GameToyClient.tsx @@ -1,12 +1,6 @@ import { useEffect, useState } from 'react'; import { GamePhase, useGameValue } from '../GameProvider'; -import { - useAutoRef, - useToyClientValue, - wait, - VibrationActuator, -} from '../../utils'; -import { ActuatorType } from 'buttplug'; +import { useAutoRef, useToyClientValue } from '../../utils'; export const GameVibrator = () => { const [stroke] = useGameValue('stroke'); @@ -26,23 +20,7 @@ export const GameVibrator = () => { useEffect(() => { const { intensity, pace, devices } = data.current; devices.forEach(device => { - const vibrationArray: number[] = []; - device.actuators.forEach(actuator => { - switch (actuator.actuatorType) { - case ActuatorType.Vibrate: - vibrationArray[actuator.index] = actuator.getOutput?.( - stroke, - intensity, - pace - ) as number; - break; - default: - break; - } - }); - if (vibrationArray.length > 0) { - device.setVibration(vibrationArray); - } + device.actuate(stroke, intensity, pace); }); }, [data, stroke]); @@ -55,30 +33,9 @@ export const GameVibrator = () => { devices.forEach(device => device.stop()); break; case GamePhase.climax: - (async () => { - for (let i = 0; i < 15; i++) { - const strength = Math.max(0, 1 - i * 0.067); - devices.forEach(device => { - const vibrationArray: number[] = []; - device.actuators.forEach(actuator => { - switch (actuator.actuatorType) { - case ActuatorType.Vibrate: { - const vibrationActuator = actuator as VibrationActuator; - vibrationArray[actuator.index] = - vibrationActuator.mapToRange(strength); - break; - } - default: - break; - } - if (vibrationArray.length > 0) { - device.setVibration(vibrationArray); - } - }); - }); - await wait(400); - } - })(); + devices.forEach(device => device.climax()); + // (async () => { + // })(); } setCurrentPhase(phase); }, [data, currentPhase, phase]); diff --git a/src/utils/toyclient.tsx b/src/utils/toyclient.tsx index 88ee2dd5..caf64843 100644 --- a/src/utils/toyclient.tsx +++ b/src/utils/toyclient.tsx @@ -1,6 +1,12 @@ import { createStateProvider } from './state'; -import { ButtplugClient, type ButtplugClientDevice } from 'buttplug'; +import { + ButtplugClient, + type ButtplugClientDevice, + ActuatorType, +} from 'buttplug'; import { type ToyActuator, VibrationActuator } from './toyactuator'; +import { Stroke } from '../game/GameProvider'; +import { wait } from '../utils'; export class ToyClient { actuators: ToyActuator[] = []; @@ -12,8 +18,47 @@ export class ToyClient { ); } - async setVibration(intensity: number | number[]): Promise { - await this.device.vibrate(intensity); + async actuate(stroke: Stroke, intensity: number, pace: number) { + const vibrationArray: number[] = []; + this.actuators.forEach(actuator => { + switch (actuator.actuatorType) { + case ActuatorType.Vibrate: + vibrationArray[actuator.index] = actuator.getOutput?.( + stroke, + intensity, + pace + ) as number; + break; + default: + break; + } + }); + if (vibrationArray.length > 0) { + this.device.vibrate(vibrationArray); + } + } + + async climax() { + for (let i = 0; i < 15; i++) { + const strength = Math.max(0, 1 - i * 0.067); + const vibrationArray: number[] = []; + this.actuators.forEach(actuator => { + switch (actuator.actuatorType) { + case ActuatorType.Vibrate: { + const vibrationActuator = actuator as VibrationActuator; + vibrationArray[actuator.index] = + vibrationActuator.mapToRange(strength); + break; + } + default: + break; + } + if (vibrationArray.length > 0) { + this.device.vibrate(vibrationArray); + } + }); + await wait(400); + } } async stop() { From cd81e55320b38634811f5c70c015d79e2c0f7989 Mon Sep 17 00:00:00 2001 From: Xephoidia Date: Wed, 30 Oct 2024 20:09:23 -0400 Subject: [PATCH 13/18] Remove commented out code --- src/game/components/GameToyClient.tsx | 2 -- src/settings/components/ToyActuatorSettings.tsx | 2 -- 2 files changed, 4 deletions(-) diff --git a/src/game/components/GameToyClient.tsx b/src/game/components/GameToyClient.tsx index 3e091161..c10b793b 100644 --- a/src/game/components/GameToyClient.tsx +++ b/src/game/components/GameToyClient.tsx @@ -34,8 +34,6 @@ export const GameVibrator = () => { break; case GamePhase.climax: devices.forEach(device => device.climax()); - // (async () => { - // })(); } setCurrentPhase(phase); }, [data, currentPhase, phase]); diff --git a/src/settings/components/ToyActuatorSettings.tsx b/src/settings/components/ToyActuatorSettings.tsx index e9fb402f..7b14f0ff 100644 --- a/src/settings/components/ToyActuatorSettings.tsx +++ b/src/settings/components/ToyActuatorSettings.tsx @@ -1,4 +1,3 @@ -// import { useActuatorSettings } from '../../utils' import { ToyActuator, VibrationActuator, @@ -6,7 +5,6 @@ import { ActuatorModeLabels, } from '../../utils'; import { PropsWithChildren, useState } from 'react'; -// import { Vibrator } from '../../utils/vibrator'; import { SettingsTile } from '../../common'; import { SettingsDescription } from '../../common/SettingsDescription'; import { Dropdown } from '../../common/Dropdown'; From f7eb610332cc8ca32ad6a07c1c0e8b1f14131de9 Mon Sep 17 00:00:00 2001 From: Xephoidia Date: Fri, 1 Nov 2024 17:02:25 -0400 Subject: [PATCH 14/18] Fix unsupported actuators not being found --- src/utils/toyclient.tsx | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/utils/toyclient.tsx b/src/utils/toyclient.tsx index caf64843..626c75b4 100644 --- a/src/utils/toyclient.tsx +++ b/src/utils/toyclient.tsx @@ -4,7 +4,7 @@ import { type ButtplugClientDevice, ActuatorType, } from 'buttplug'; -import { type ToyActuator, VibrationActuator } from './toyactuator'; +import { ToyActuator, VibrationActuator } from './toyactuator'; import { Stroke } from '../game/GameProvider'; import { wait } from '../utils'; @@ -16,6 +16,18 @@ export class ToyClient { attribute => (this.actuators = [...this.actuators, new VibrationActuator(attribute)]) ); + device.linearAttributes.forEach( + attribute => + (this.actuators = [...this.actuators, new ToyActuator(attribute)]) + ); + device.oscillateAttributes.forEach( + attribute => + (this.actuators = [...this.actuators, new ToyActuator(attribute)]) + ); + device.rotateAttributes.forEach( + attribute => + (this.actuators = [...this.actuators, new ToyActuator(attribute)]) + ); } async actuate(stroke: Stroke, intensity: number, pace: number) { From d01b2241eadfc7d16ec23e52e61ffb385512f599 Mon Sep 17 00:00:00 2001 From: Xephoidia Date: Fri, 1 Nov 2024 22:10:08 -0400 Subject: [PATCH 15/18] Update Settings labels to fit new functionality --- src/settings/components/ToyClientSettings.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/settings/components/ToyClientSettings.tsx b/src/settings/components/ToyClientSettings.tsx index 1b387b28..d43a37e5 100644 --- a/src/settings/components/ToyClientSettings.tsx +++ b/src/settings/components/ToyClientSettings.tsx @@ -96,7 +96,7 @@ export const VibratorSettings = () => { }, [client, connection, host, port, setConnection, setDevices, setError]); return ( - + { } > - Use compatible device during your game + Use compatible devices during your game Date: Sun, 3 Nov 2024 16:43:41 -0500 Subject: [PATCH 16/18] Fix devices being counted multiple times --- src/settings/components/ToyClientSettings.tsx | 20 ++++++++++++++++--- src/settings/components/ToySettings.tsx | 11 +++++----- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/settings/components/ToyClientSettings.tsx b/src/settings/components/ToyClientSettings.tsx index d43a37e5..8af00244 100644 --- a/src/settings/components/ToyClientSettings.tsx +++ b/src/settings/components/ToyClientSettings.tsx @@ -15,6 +15,7 @@ import { defaultTransition, useToyClientValue, ToyClient } from '../../utils'; import { ButtplugBrowserWebsocketClientConnector, ButtplugClientDevice, + ButtplugClient, } from 'buttplug'; import styled from 'styled-components'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; @@ -41,7 +42,7 @@ const StyledUrlFields = styled.div` `; export const VibratorSettings = () => { - const [client] = useToyClientValue('client'); + const [client, setClient] = useToyClientValue('client'); const [connection, setConnection] = useToyClientValue('connection'); const [devices, setDevices] = useToyClientValue('devices'); const [error, setError] = useToyClientValue('error'); @@ -60,6 +61,7 @@ export const VibratorSettings = () => { if (connection) { try { await client.disconnect(); + setClient(new ButtplugClient('JOI.how')); } catch (e) { setError(String(e)); } finally { @@ -83,6 +85,9 @@ export const VibratorSettings = () => { setDevices(devices => devices.filter(e => e.name !== device.name)); }); client.addListener('disconnect', () => { + client.removeListener('deviceadded'); + client.removeListener('deviceremoved'); + client.removeListener('disconnect'); setDevices([]); setConnection(undefined); }); @@ -93,7 +98,16 @@ export const VibratorSettings = () => { } finally { setLoading(false); } - }, [client, connection, host, port, setConnection, setDevices, setError]); + }, [ + client, + connection, + host, + port, + setClient, + setConnection, + setDevices, + setError, + ]); return ( @@ -171,7 +185,7 @@ export const VibratorSettings = () => { {devices.length > 0 ? ( devices.map((device: ToyClient, index: number) => ( - + )) ) : (
  • No devices found
  • diff --git a/src/settings/components/ToySettings.tsx b/src/settings/components/ToySettings.tsx index 35e53448..5dd12ceb 100644 --- a/src/settings/components/ToySettings.tsx +++ b/src/settings/components/ToySettings.tsx @@ -7,19 +7,18 @@ import { SettingsDescription } from '../../common/SettingsDescription'; export interface ToySettingsProps extends PropsWithChildren> { - key: number; device: ToyClient; } -export const ToySettings: React.FC = ({ key, device }) => { +export const ToySettings: React.FC = ({ device }) => { return ( -
  • - - +
  • + + Change the settings for each controllable component on your toy. {device.actuators.map((a: ToyActuator) => ( - + ))}
  • From 5f193d0e0576e703b16dc4d357f672ad7c6f6a33 Mon Sep 17 00:00:00 2001 From: Xephoidia Date: Fri, 22 Nov 2024 20:50:48 -0500 Subject: [PATCH 17/18] Fix GameToyClient naming mismatch --- src/game/GamePage.tsx | 4 ++-- src/game/components/GameToyClient.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/game/GamePage.tsx b/src/game/GamePage.tsx index 3a245977..95855d2d 100644 --- a/src/game/GamePage.tsx +++ b/src/game/GamePage.tsx @@ -12,7 +12,7 @@ import { GameWarmup, GameEmergencyStop, GameSettings, - GameVibrator, + GameToyClient, } from './components'; import { GameProvider } from './GameProvider'; @@ -89,7 +89,7 @@ export const GamePage = () => { - + diff --git a/src/game/components/GameToyClient.tsx b/src/game/components/GameToyClient.tsx index c10b793b..be59eb0a 100644 --- a/src/game/components/GameToyClient.tsx +++ b/src/game/components/GameToyClient.tsx @@ -2,7 +2,7 @@ import { useEffect, useState } from 'react'; import { GamePhase, useGameValue } from '../GameProvider'; import { useAutoRef, useToyClientValue } from '../../utils'; -export const GameVibrator = () => { +export const GameToyClient = () => { const [stroke] = useGameValue('stroke'); const [intensity] = useGameValue('intensity'); const [pace] = useGameValue('pace'); From 0df5bb68442ac87bda65dc1928eb5e986e045542 Mon Sep 17 00:00:00 2001 From: Xephoidia Date: Sun, 24 Nov 2024 12:59:51 -0500 Subject: [PATCH 18/18] Move toy logic into its own folder --- src/game/components/GameToyClient.tsx | 3 ++- src/index.tsx | 2 +- src/settings/components/ToyActuatorSettings.tsx | 2 +- src/settings/components/ToyClientSettings.tsx | 3 ++- src/settings/components/ToySettings.tsx | 3 +-- src/toy/index.ts | 2 ++ src/{utils => toy}/toyactuator.tsx | 0 src/{utils => toy}/toyclient.tsx | 3 +-- src/utils/index.ts | 2 -- 9 files changed, 10 insertions(+), 10 deletions(-) create mode 100644 src/toy/index.ts rename src/{utils => toy}/toyactuator.tsx (100%) rename src/{utils => toy}/toyclient.tsx (96%) diff --git a/src/game/components/GameToyClient.tsx b/src/game/components/GameToyClient.tsx index be59eb0a..61a009b2 100644 --- a/src/game/components/GameToyClient.tsx +++ b/src/game/components/GameToyClient.tsx @@ -1,6 +1,7 @@ import { useEffect, useState } from 'react'; import { GamePhase, useGameValue } from '../GameProvider'; -import { useAutoRef, useToyClientValue } from '../../utils'; +import { useAutoRef } from '../../utils'; +import { useToyClientValue } from '../../toy'; export const GameToyClient = () => { const [stroke] = useGameValue('stroke'); diff --git a/src/index.tsx b/src/index.tsx index 4e7e171f..2030b7cb 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -4,7 +4,7 @@ import { App } from './app/App.tsx'; import './index.css'; import { SettingsProvider, ImageProvider } from './settings'; import { E621Provider } from './e621'; -import { ToyClientProvider } from './utils'; +import { ToyClientProvider } from './toy'; import { LocalImageProvider } from './local/LocalProvider.tsx'; ReactDOM.createRoot(document.getElementById('root')!).render( diff --git a/src/settings/components/ToyActuatorSettings.tsx b/src/settings/components/ToyActuatorSettings.tsx index 7b14f0ff..1920fb63 100644 --- a/src/settings/components/ToyActuatorSettings.tsx +++ b/src/settings/components/ToyActuatorSettings.tsx @@ -3,7 +3,7 @@ import { VibrationActuator, ActuatorMode, ActuatorModeLabels, -} from '../../utils'; +} from '../../toy'; import { PropsWithChildren, useState } from 'react'; import { SettingsTile } from '../../common'; import { SettingsDescription } from '../../common/SettingsDescription'; diff --git a/src/settings/components/ToyClientSettings.tsx b/src/settings/components/ToyClientSettings.tsx index 8af00244..fb74cda9 100644 --- a/src/settings/components/ToyClientSettings.tsx +++ b/src/settings/components/ToyClientSettings.tsx @@ -11,7 +11,8 @@ import { SettingsLabel, Spinner, } from '../../common'; -import { defaultTransition, useToyClientValue, ToyClient } from '../../utils'; +import { defaultTransition } from '../../utils'; +import { useToyClientValue, ToyClient } from '../../toy'; import { ButtplugBrowserWebsocketClientConnector, ButtplugClientDevice, diff --git a/src/settings/components/ToySettings.tsx b/src/settings/components/ToySettings.tsx index 5dd12ceb..0cd6f430 100644 --- a/src/settings/components/ToySettings.tsx +++ b/src/settings/components/ToySettings.tsx @@ -1,8 +1,7 @@ -import { ToyClient } from '../../utils/toyclient'; +import { ToyClient, type ToyActuator } from '../../toy'; import { ToyActuatorSettings } from './ToyActuatorSettings'; import { SettingsTile } from '../../common'; import { PropsWithChildren } from 'react'; -import { type ToyActuator } from '../../utils'; import { SettingsDescription } from '../../common/SettingsDescription'; export interface ToySettingsProps diff --git a/src/toy/index.ts b/src/toy/index.ts new file mode 100644 index 00000000..79cc0468 --- /dev/null +++ b/src/toy/index.ts @@ -0,0 +1,2 @@ +export * from './toyactuator'; +export * from './toyclient'; diff --git a/src/utils/toyactuator.tsx b/src/toy/toyactuator.tsx similarity index 100% rename from src/utils/toyactuator.tsx rename to src/toy/toyactuator.tsx diff --git a/src/utils/toyclient.tsx b/src/toy/toyclient.tsx similarity index 96% rename from src/utils/toyclient.tsx rename to src/toy/toyclient.tsx index 626c75b4..959b5870 100644 --- a/src/utils/toyclient.tsx +++ b/src/toy/toyclient.tsx @@ -1,4 +1,3 @@ -import { createStateProvider } from './state'; import { ButtplugClient, type ButtplugClientDevice, @@ -6,7 +5,7 @@ import { } from 'buttplug'; import { ToyActuator, VibrationActuator } from './toyactuator'; import { Stroke } from '../game/GameProvider'; -import { wait } from '../utils'; +import { wait, createStateProvider } from '../utils'; export class ToyClient { actuators: ToyActuator[] = []; diff --git a/src/utils/index.ts b/src/utils/index.ts index 8adf0ce5..e1171d74 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -11,6 +11,4 @@ export * from './setters'; export * from './sound'; export * from './state'; export * from './translate'; -export * from './toyclient'; export * from './wait'; -export * from './toyactuator';