Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
99 commits
Select commit Hold shift + click to select a range
1d129d7
refactor: organize scene files
ryankauk Apr 1, 2023
ec15916
feat: add midi control to lfo period
ryankauk Apr 3, 2023
be567ce
feat: make engine midi more dynamic and organize react midi
ryankauk Apr 3, 2023
82bc049
refactor: organize engine midi
ryankauk Apr 3, 2023
6d1fb7e
fix: midi imports
ryankauk Apr 3, 2023
8d7b928
refactor: move midi action type to feature
ryankauk Apr 3, 2023
0eb4282
refactor: organize redux midi actions
ryankauk Apr 3, 2023
5ad1803
refactor: midi redux device state
ryankauk Apr 3, 2023
6e38df8
refactor: organize midi shared
ryankauk Apr 3, 2023
ebfa580
refactor: make all midi parameters inferred
ryankauk Apr 3, 2023
1412bd1
fix: circular type reference
ryankauk Apr 3, 2023
01386df
fix: types and path alias
ryankauk Apr 3, 2023
1c5bb51
refactor: dmx engine
ryankauk Apr 4, 2023
b2b8e03
refactor: dmx react
ryankauk Apr 4, 2023
95fa18f
refactor: dmx shared
ryankauk Apr 4, 2023
4374b86
refactor: dmx redux
ryankauk Apr 4, 2023
84c99c7
refactor: move midi types
ryankauk Apr 4, 2023
0f7cdef
refactor: led react
ryankauk Apr 4, 2023
e224028
refactor: shared led
ryankauk Apr 4, 2023
474f0c6
refactor: led engine
ryankauk Apr 4, 2023
58b6907
refactor: led redux
ryankauk Apr 4, 2023
5c30805
fix: types
ryankauk Apr 4, 2023
55798f7
refactor: rename sidebar
ryankauk Apr 4, 2023
489172d
refactor: cleanup menu bars
ryankauk Apr 4, 2023
5b18e2d
refactor: modulators shared
ryankauk Apr 4, 2023
8a96f08
refactor: modulators react
ryankauk Apr 4, 2023
66289fb
refactor: convert pages to nextjs like format
ryankauk Apr 4, 2023
b5f272b
refactor: ui icons
ryankauk Apr 4, 2023
9846555
refactor: ui images and error boundary
ryankauk Apr 4, 2023
fa924c1
refactor: ui hooks
ryankauk Apr 4, 2023
a642ac2
refactor: ui design system
ryankauk Apr 4, 2023
8bbb3c3
refactor: visualizer
ryankauk Apr 4, 2023
b0cc769
refactor: math utils
ryankauk Apr 4, 2023
6f4d25e
refactor: utils base colors
ryankauk Apr 4, 2023
1d80273
refactor: threejs images
ryankauk Apr 4, 2023
6dbc0d0
refactor: filesaving engine
ryankauk Apr 4, 2023
ea9436c
refactor: filesaving react
ryankauk Apr 4, 2023
8ce34fe
refactor: filesaving save load button
ryankauk Apr 4, 2023
3fa0d20
refactor: duration util
ryankauk Apr 4, 2023
98007aa
refactor: organize scene react
ryankauk Apr 4, 2023
137baaa
refactor: scenes engine
ryankauk Apr 4, 2023
989ad36
refactor: organize scenes shared
ryankauk Apr 4, 2023
eeaeca8
refactor: organize file saving shared
ryankauk Apr 4, 2023
cfb17e2
refactor: visualizer engine
ryankauk Apr 4, 2023
33b6599
refactor: organize menu
ryankauk Apr 4, 2023
f6789ae
refactor: organize devices react
ryankauk Apr 4, 2023
bc7439c
refactor: organize devices shared
ryankauk Apr 4, 2023
199f605
refactor: organize shared dmx params
ryankauk Apr 4, 2023
f4ba65b
refactor: bpm shared
ryankauk Apr 4, 2023
6a90522
refactor: bpm shared
ryankauk Apr 4, 2023
62a0d95
refactor: bpm engine
ryankauk Apr 4, 2023
956c7be
refactor: utils rolling average
ryankauk Apr 4, 2023
86130a4
refactor: ui theme
ryankauk Apr 4, 2023
0fb8051
refactor: cleanup unused
ryankauk Apr 4, 2023
f0daeff
refactor: remove unused
ryankauk Apr 4, 2023
ee11487
refactor: logging
ryankauk Apr 4, 2023
ae34100
refactor: shared util
ryankauk Apr 4, 2023
d8639a3
refactor: new project filesaving
ryankauk Apr 4, 2023
9f7aa9e
refactor: global shared engine
ryankauk Apr 4, 2023
d5040ce
refactor: global shared redux
ryankauk Apr 4, 2023
85005db
refactore: global shared
ryankauk Apr 4, 2023
275d89d
refactor: bpm link
ryankauk Apr 4, 2023
25e3f5e
refactor: cleanup renderer index
ryankauk Apr 4, 2023
5aae70e
refactor: engine cleanup
ryankauk Apr 4, 2023
251cfea
refactor: api calls
ryankauk Apr 4, 2023
6f70dff
refactor: add dispose to engine
ryankauk Apr 4, 2023
dbcf2f4
fix: queries and mutations
ryankauk Apr 4, 2023
9cfffa2
fix: control state types
ryankauk Apr 4, 2023
379cbf6
refactor: cleanup disposeables
ryankauk Apr 4, 2023
54ec74a
refactor: rename ipc
ryankauk Apr 4, 2023
974c1d2
refactor: fixtures redux
ryankauk Apr 4, 2023
238c353
refactor: cleanup fixture configuration react
ryankauk Apr 4, 2023
0ec36ef
refactor: easier fixture api
ryankauk Apr 4, 2023
d01ebff
refactor: setup channel config
ryankauk Apr 5, 2023
71992f6
refactor: params feature
ryankauk Apr 5, 2023
a1ab270
refactor: revert params types for now
ryankauk Apr 5, 2023
3412196
refactor: more strict params
ryankauk Apr 5, 2023
9b88dee
feat: uniform api
ryankauk Apr 5, 2023
52d7152
remove: param dependancy from modulation engine
ryankauk Apr 5, 2023
01a3eda
refactor: consolidate channel react components into single config
ryankauk Apr 5, 2023
83acee4
refactor: dmxOut
ryankauk Apr 5, 2023
dec72ee
refactor: dmx engine
ryankauk Apr 5, 2023
61f0879
refactor: more cleanup
ryankauk Apr 5, 2023
272083b
fix: actions circular dep
ryankauk Apr 6, 2023
d85df73
fix: channel react circular dep
ryankauk Apr 6, 2023
79530b6
fix: store causing firebase analytics issue
ryankauk Apr 6, 2023
ce864e3
fix: midi overlay styling
ryankauk Apr 6, 2023
4017c63
refactor: replace slider overlay
ryankauk Apr 6, 2023
30caa76
refactor: midi overlay
ryankauk Apr 7, 2023
3ada1c6
Merge branch 'fixture-db' into dmx-refactor
spensbot Apr 8, 2023
2a61239
refactor: fixture library errors
ryankauk Apr 8, 2023
aa50abb
fix: types for generic params
ryankauk Apr 8, 2023
e552262
fix: types
ryankauk Apr 8, 2023
72479b2
fix: reductions type
ryankauk Apr 8, 2023
39e9248
fix: midi config type
ryankauk Apr 9, 2023
65aadb7
fix: no output params
ryankauk Apr 10, 2023
3eb03d1
refactor: more cleanup
ryankauk Apr 10, 2023
70a00d7
refactor: draggable number
ryankauk Apr 11, 2023
e745941
refactor: use draggable number
ryankauk Apr 11, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
5 changes: 5 additions & 0 deletions .erb/configs/webpack.config.base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import webpack from 'webpack'
import webpackPaths from './webpack.paths'
import { dependencies as externals } from '../../release/app/package.json'
import path from 'path'
import { TsconfigPathsPlugin } from 'tsconfig-paths-webpack-plugin'

const configuration: webpack.Configuration = {
externals: [...Object.keys(externals || {})],
Expand Down Expand Up @@ -47,6 +49,9 @@ const configuration: webpack.Configuration = {
new webpack.EnvironmentPlugin({
NODE_ENV: 'production',
}),
new TsconfigPathsPlugin({
baseUrl: path.join(__dirname, '../..'), // path to tsconfig.json directory
}) as any,
],
}

Expand Down
2 changes: 1 addition & 1 deletion .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"recommendations": ["dbaeumer.vscode-eslint", "EditorConfig.EditorConfig"]
"recommendations": ["dbaeumer.vscode-eslint", "EditorConfig.EditorConfig", "esbenp.prettier-vscode"]
}
919 changes: 865 additions & 54 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"package": "ts-node ./.erb/scripts/clean.js dist && npm run build && electron-builder build --publish never",
"rebuild": "electron-rebuild --parallel --types prod,dev,optional --module-dir release/app",
"start": "ts-node ./.erb/scripts/check-port-in-use.js && npm run start:renderer",
"start:main": "cross-env NODE_ENV=development electronmon -r ts-node/register/transpile-only .",
"start:main": "cross-env NODE_ENV=development electronmon -r ts-node/register/transpile-only -r tsconfig-paths/register .",
"start:preload": "cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.preload.dev.ts",
"start:renderer": "cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack serve --config ./.erb/configs/webpack.config.renderer.dev.ts",
"start:visualizer": "cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack serve --config ./.erb/configs/webpack.config.visualizer.dev.ts",
Expand All @@ -35,6 +35,7 @@
"@emotion/styled": "^11.8.1",
"@mui/icons-material": "^5.8.2",
"@mui/material": "^5.8.2",
"@radix-ui/react-popover": "1.0.5",
"@reduxjs/toolkit": "^1.8.2",
"@sentry/react": "^7.0.0",
"@sentry/tracing": "^7.0.0",
Expand Down Expand Up @@ -116,6 +117,8 @@
"ts-jest": "^28.0.2",
"ts-loader": "^9.3.0",
"ts-node": "^10.7.0",
"tsconfig-paths": "^4.2.0",
"tsconfig-paths-webpack-plugin": "^4.0.1",
"typescript": "^4.6.4",
"url-loader": "^4.1.1",
"webpack": "^5.72.1",
Expand Down
9 changes: 9 additions & 0 deletions src/app.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export const AppConfig = {
midi: {
throttledWaitMS: 1000 / 60,
updateIntervalMS: 1000,
},
dmx: {
updateIntervalMS: 1000,
},
}
42 changes: 42 additions & 0 deletions src/features/bpm/engine/Link.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import TapTempoEngine from './TapTempoEngine'
import { TimeState } from '../shared/TimeState'
import NodeLink from 'node-link'

export const createBpmController = () => {
const nodeLink = new NodeLink()

nodeLink.setIsPlaying(true)
nodeLink.enableStartStopSync(true)
nodeLink.enable(true)

const tapTempoEngine = new TapTempoEngine()

let _lastFrameTime = 0
// Todo: Desimate dt in this context
function getNextTimeState(): TimeState {
let currentTime = Date.now()
const dt = currentTime - _lastFrameTime

_lastFrameTime = currentTime

return {
...nodeLink.getSessionInfoCurrent(),
dt: dt,
quantum: 4.0,
}
}

function tapTempo() {
tapTempoEngine.tap((newBpm) => {
nodeLink.setTempo(newBpm)
})
}

return {
getNextTimeState,
tapTempo,
nodeLink,
}
}

export type BPMController = ReturnType<typeof createBpmController>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {DynamicSustainRollingAverage, dynamicSustain} from '../../shared/RollingAverage'
import {DynamicSustainRollingAverage, dynamicSustain} from '../../utils/RollingAverage'

const BPM_LIMIT = 1000
const SLEEP_TIME = 3000 // milliseconds between taps after which the engine resets
Expand Down
70 changes: 70 additions & 0 deletions src/features/bpm/engine/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { RealtimeState, initRealtimeState } from 'features/redux/realtimeStore'
import { TimeState } from '../shared/TimeState'
import { createBpmController } from './Link'
import { UserCommand } from 'features/shared/engine/ipc_channels'
export * from './Link'
export const createRealtimeManager = ({
next,
onUpdate,
}: {
next: (
previousState: { realtime: RealtimeState },
newStates: { time: TimeState }
) => RealtimeState
onUpdate: (newStates: { time: TimeState; realtime: RealtimeState }) => void
}) => {
const bpmController = createBpmController()
const realtimeStateRef: { current: RealtimeState } = {
current: initRealtimeState(),
}

const createRealtimeLoop = (callback: () => void) => {
const realtimeStateInterval = setInterval(callback, 1000 / 90)

return {
dispose() {
clearInterval(realtimeStateInterval)
},
}
}

return {
realtimeStateRef,
bpmController,
start() {
return createRealtimeLoop(() => {
const nextTimeState = bpmController.getNextTimeState()

realtimeStateRef.current = next(
{ realtime: realtimeStateRef.current },
{ time: nextTimeState }
)

onUpdate({ realtime: realtimeStateRef.current, time: nextTimeState })
})
},
}
}

export type RealtimeManager = ReturnType<typeof createRealtimeManager>

export const onLinkUserCommand = (
command: UserCommand,
realtimeManager: RealtimeManager
) => {
const realtimeState = realtimeManager.realtimeStateRef.current
const { nodeLink, tapTempo } = realtimeManager.bpmController
if (command.type === 'IncrementTempo') {
nodeLink.setTempo(realtimeState.time.bpm + command.amount)
} else if (command.type === 'SetLinkEnabled') {
nodeLink.enable(command.isEnabled)
} else if (command.type === 'EnableStartStopSync') {
nodeLink.enableStartStopSync(command.isEnabled)
} else if (command.type === 'SetIsPlaying') {
nodeLink.setIsPlaying(command.isPlaying)
} else if (command.type === 'SetBPM') {
nodeLink.setTempo(command.bpm)
} else if (command.type === 'TapTempo') {
tapTempo()
}
}
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { TimeState, isNewPeriod } from './TimeState'
import { lerp } from '../math/util'
import { lerp } from '../../utils/math/util'
import { indexArray } from 'features/utils/util'

type Normalized = number

Expand Down Expand Up @@ -123,3 +124,32 @@ export function updateIndexes(

return nextState
}

export const getNewRandomizerState = ({
previousRandomizerState,
size,
beatsLast,
options,
timeState,
}: {
previousRandomizerState: RandomizerState
size: number
beatsLast: number
options: RandomizerOptions
timeState: TimeState
}) => {
let newRandomizerState = resizeRandomizer(
previousRandomizerState ?? initRandomizerState(),
size
)

newRandomizerState = updateIndexes(
beatsLast,
newRandomizerState,
timeState,
indexArray(size),
options
)

return newRandomizerState
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import styled from 'styled-components'
import { useControlSelector, useTypedSelector } from '../redux/store'
import { setConnectionsMenu } from '../redux/guiSlice'
import { useControlSelector, useTypedSelector } from '../../../../renderer/redux/store'
import { setConnectionsMenu } from '../../../ui/redux/guiSlice'
import { useDispatch } from 'react-redux'
import { setDmxConnectable, setMidiConnectable } from '../redux/controlSlice'
import { setDmxConnectable, setMidiConnectable } from '../../../../renderer/redux/controlSlice'
import CloseIcon from '@mui/icons-material/Close'
import IconButton from '@mui/material/IconButton'
import {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import styled from 'styled-components'
import IconButton from '@mui/material/IconButton'
import CopyIcon from '@mui/icons-material/ContentCopy'
import { useState } from 'react'
import useSafeCallback from 'renderer/hooks/useSafeCallback'
import useSafeCallback from 'features/ui/react/hooks/useSafeCallback'

function copyToClipboard(text: string) {
return navigator.clipboard.writeText(text)
Expand Down
File renamed without changes.
153 changes: 153 additions & 0 deletions src/features/dmx/channel.config.react.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import HSpad, { ColorChannelProps } from 'features/ui/react/base/HSpad'
import {
DmxNumberField,
Info,
Row,
createChannelComponents,
} from './react/fixtures/channels/editor/core'
import ColorPicker from 'features/ui/react/base/ColorPicker'
import Checkbox from 'features/ui/react/base/LabelledCheckbox'
import Input from 'features/ui/react/base/Input'
import styled from 'styled-components'
import { AxisDir, axisDirList } from './shared/dmxFixtures'
import Select from 'features/ui/react/base/Select'
import ColorMapChannel from './react/fixtures/channels/editor/ColorMapChannel'

const Sp2 = styled.div`
width: 1rem;
`

export const ChannelComponents = createChannelComponents({
color: ({ ch, updateChannel }) => {
const colorProps: ColorChannelProps = {
hue: ch.color.hue,
saturation: ch.color.saturation,
onChange: (newHue, newSaturation) => {
updateChannel({
type: 'color',
color: {
hue: newHue,
saturation: newSaturation,
},
})
},
}

return (
<>
{/* {getCustomColorChannelName(ch.color)} */}
<ColorPicker {...colorProps} />
<HSpad {...colorProps} />
</>
)
},
master: ({ ch, updateChannel }) => {
return (
<>
<DmxNumberField ch={ch} field="min" label="Min" />
<Sp2 />
<DmxNumberField ch={ch} field="max" label="MAX" />
<Sp2 />
<Checkbox
label="On/Off"
checked={ch.isOnOff}
onChange={(isOnOff) =>
updateChannel({
...ch,
isOnOff,
})
}
/>
</>
)
},
strobe: ({ ch }) => {
return (
<>
<DmxNumberField ch={ch} field="default_solid" label="Solid" />
<Sp2 />
<DmxNumberField ch={ch} field="default_strobe" label="Strobe" />
</>
)
},
axis: ({ ch, updateChannel }) => {
return (
<>
<Row>
<Info>Direction: </Info>
<Select
label="Direction:"
val={ch.dir}
items={axisDirList}
onChange={(newAxisDir) =>
updateChannel({
...ch,
dir: newAxisDir as AxisDir,
})
}
/>
</Row>
<Checkbox
label="Fine"
checked={ch.isFine}
onChange={(isFine) =>
updateChannel({
...ch,
isFine,
})
}
/>
{!ch.isFine && (
<>
<Sp2 />
<DmxNumberField ch={ch} field="min" label="Min" />
<Sp2 />
<DmxNumberField ch={ch} field="max" label="Max" />
</>
)}
</>
)
},
colorMap: ({ ch, channelIndex, fixtureID }) => {
return (
<ColorMapChannel
ch={ch}
fixtureID={fixtureID}
channelIndex={channelIndex}
/>
)
},
custom: ({ ch, updateChannel }) => {
return (
<>
<Input
value={ch.name}
onChange={(newName) =>
updateChannel({
...ch,
name: newName,
})
}
/>
<Checkbox
label="Controllable"
checked={ch.isControllable}
onChange={(isControllable) =>
updateChannel({
...ch,
isControllable,
})
}
/>
{ch.isControllable && (
<>
<Sp2 />
<DmxNumberField ch={ch} field="min" label="Min" />
<Sp2 />
<DmxNumberField ch={ch} field="max" label="Max" />
</>
)}
</>
)
},
})
Loading