Skip to content

Commit

Permalink
wip: these feedbacks can do variables now too
Browse files Browse the repository at this point in the history
  • Loading branch information
Julusian committed Jun 28, 2023
1 parent b098cc1 commit fae6f58
Show file tree
Hide file tree
Showing 11 changed files with 97 additions and 54 deletions.
4 changes: 2 additions & 2 deletions lib/Controls/ControlTypes/Button/Base.js
Original file line number Diff line number Diff line change
Expand Up @@ -259,12 +259,12 @@ export default class ButtonControlBase extends ControlBase {

/**
* Propagate variable changes
* @param {Array<string>} allChangedVariables - variables with changes
* @param {Set<string>} allChangedVariables - variables with changes
* @access public
*/
onVariablesChanged(allChangedVariables) {
if (this.last_draw_variables) {
for (const variable of allChangedVariables) {
for (const variable of allChangedVariables.values()) {
if (this.last_draw_variables.has(variable)) {
this.logger.silly('variable changed in bank ' + this.controlId)

Expand Down
12 changes: 6 additions & 6 deletions lib/Controls/Controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -919,13 +919,11 @@ class ControlsController extends CoreBase {
* @param {Array} removedVariables - variables that have been removed
* @access public
*/
onVariablesChanged(changedVariables, removedVariables) {
const allChangedVariables = [...removedVariables, ...Object.keys(changedVariables)]

onVariablesChanged(allChangedVariables, changedVariables, removedVariables) {
// Inform triggers of the change
this.triggers.emit('variables_changed', new Set(allChangedVariables))
this.triggers.emit('variables_changed', allChangedVariables)

if (allChangedVariables.length > 0) {
if (allChangedVariables.size > 0) {
for (const control of Object.values(this.#controls)) {
if (typeof control.onVariablesChanged === 'function') {
control.onVariablesChanged(allChangedVariables)
Expand Down Expand Up @@ -1034,10 +1032,12 @@ class ControlsController extends CoreBase {
/**
* Update values for some feedbacks
* @param {string} instanceId
* @param {object} result - object containing new values for the feedbacks that have changed
* @param {Array} result - object containing new values for the feedbacks that have changed
* @access public
*/
updateFeedbackValues(instanceId, result) {
if (result.length === 0) return

const values = {}

for (const item of result) {
Expand Down
24 changes: 8 additions & 16 deletions lib/Graphics/Preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,23 +71,22 @@ class GraphicsPreview extends CoreBase {
client.leave(PreviewPageRoom(pageNumber))
})

client.onPromise('preview:button-reference:subscribe', (id, location, options, useVariables) => {
client.onPromise('preview:button-reference:subscribe', (id, location, options) => {
const fullId = `${client.id}::${id}`

if (this.#bankReferencePreviews.get(fullId)) throw new Error('Session id is already in use')

// Do a resolve of the reference for the starting image
const result = ParseInternalControlReference(this, location, options, useVariables)
const result = ParseInternalControlReference(this, location, options, true)

// Track the subscription, to allow it to be invalidated
this.#bankReferencePreviews.set(fullId, {
id,
location,
options,
resolvedLocation: result.location,
referencedVariableIds: new Set(result.referencedVariables),
referencedVariableIds: Array.from(result.referencedVariables),
client,
useVariables,
})

return result.location ? this.graphics.getBank(result.location).buffer : null
Expand Down Expand Up @@ -131,27 +130,20 @@ class GraphicsPreview extends CoreBase {
}
}

onVariablesChanged(changedVariables, removedVariables) {
const allChanged = [...Object.keys(changedVariables), ...removedVariables]

onVariablesChanged(allChanged, changedVariables, removedVariables) {
// Lookup any sessions
for (const previewSession of this.#bankReferencePreviews.values()) {
if (!previewSession.referencedVariableIds || previewSession.referencedVariableIds.length == 0) continue
if (!previewSession.referencedVariableIds || !previewSession.referencedVariableIds.length) continue

const matchingChangedVariable = allChanged.some((variable) => previewSession.referencedVariableIds.has(variable))
const matchingChangedVariable = previewSession.referencedVariableIds.some((variable) => allChanged.has(variable))
if (!matchingChangedVariable) continue

// Resolve the new location
const result = ParseInternalControlReference(
this,
previewSession.location,
previewSession.options,
previewSession.useVariables
)
const result = ParseInternalControlReference(this, previewSession.location, previewSession.options, true)

const lastResolvedLocation = previewSession.resolvedLocation

previewSession.referencedVariableIds = new Set(result.referencedVariables)
previewSession.referencedVariableIds = Array.from(result.referencedVariables)
previewSession.resolvedLocation = result.location

if (!result.location) {
Expand Down
4 changes: 2 additions & 2 deletions lib/Instance/Host.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,8 @@ class ModuleHost {
* Send a list of changed variables to all active instances.
* This will trigger feedbacks using variables to be rechecked
*/
onVariablesChanged(changed_variables, removed_variables) {
const changedVariableIds = [...Object.keys(changed_variables), ...removed_variables]
onVariablesChanged(all_changed_variables, changed_variables, removed_variables) {
const changedVariableIds = Array.from(all_changed_variables)

for (const child of this.children.values()) {
if (child.handler && child.isReady) {
Expand Down
10 changes: 6 additions & 4 deletions lib/Instance/Variable.js
Original file line number Diff line number Diff line change
Expand Up @@ -319,10 +319,12 @@ class InstanceVariable extends CoreBase {

#emitVariablesChanged(changed_variables, removed_variables) {
if (Object.keys(changed_variables).length > 0 || removed_variables.length > 0) {
this.internalModule.variablesChanged(changed_variables, removed_variables)
this.controls.onVariablesChanged(changed_variables, removed_variables)
this.instance.moduleHost.onVariablesChanged(changed_variables, removed_variables)
this.preview.onVariablesChanged(changed_variables, removed_variables)
const all_changed_variables = new Set([...removed_variables, ...Object.keys(changed_variables)])

this.internalModule.onVariablesChanged(all_changed_variables, changed_variables, removed_variables)
this.controls.onVariablesChanged(all_changed_variables, changed_variables, removed_variables)
this.instance.moduleHost.onVariablesChanged(all_changed_variables, changed_variables, removed_variables)
this.preview.onVariablesChanged(all_changed_variables, changed_variables, removed_variables)
}
}
}
Expand Down
29 changes: 25 additions & 4 deletions lib/Internal/Controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,10 @@ export default class InternalController extends CoreBase {
}

if (value !== undefined) {
feedback.referencedVariables = 'referencedVariables' in value ? value.referencedVariables : null

// We are done
return value
return 'value' in value ? value.value : value
}
}
}
Expand Down Expand Up @@ -324,12 +326,31 @@ export default class InternalController extends CoreBase {
}
}
}
// HACK - Can we avoid having everything make calls into this or its children?
variablesChanged(changed_variables, removed_variables) {

onVariablesChanged(all_changed_variables, changed_variables, removed_variables) {
// Inform all fragments
for (const fragment of this.fragments) {
if (typeof fragment.variablesChanged === 'function') {
fragment.variablesChanged(changed_variables, removed_variables)
fragment.variablesChanged(all_changed_variables, changed_variables, removed_variables)
}
}

const newValues = []

// Lookup feedbacks
for (const [id, feedback] of this.feedbacks.entries()) {
if (!feedback.referencedVariables || !feedback.referencedVariables.length) continue

// Check a referenced variable was changed
if (!feedback.referencedVariables.some((variable) => all_changed_variables.has(variable))) continue

newValues.push({
id: id,
controlId: feedback.controlId,
value: this.#feedbackGetValue(feedback),
})
}

this.registry.controls.updateFeedbackValues('internal', newValues)
}
}
57 changes: 43 additions & 14 deletions lib/Internal/Controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,15 +163,16 @@ export default class Controls extends CoreBase {
}

#fetchLocationAndControlId(options, pressLocation, useVariableFields) {
let theLocation = ParseInternalControlReference(this, pressLocation, options, useVariableFields).location
const result = ParseInternalControlReference(this, pressLocation, options, useVariableFields)

// TODO - validate theLocation

const theControlId = theLocation ? this.page.getControlIdAt(theLocation) : undefined
const theControlId = result.location ? this.page.getControlIdAt(result.location) : undefined

return {
theControlId,
theLocation,
theLocation: result.location,
referencedVariables: Array.from(result.referencedVariables),
}
}

Expand Down Expand Up @@ -458,7 +459,7 @@ export default class Controls extends CoreBase {
description: 'Imitate the style of another button',
showButtonPreview: true,
options: [
...CHOICES_FEEDBACK_LOCATION,
...CHOICES_ACTION_LOCATION,
{
id: 'properties',
label: 'Properties',
Expand Down Expand Up @@ -541,7 +542,11 @@ export default class Controls extends CoreBase {

executeFeedback(feedback) {
if (feedback.type === 'bank_style') {
const { theLocation } = this.#fetchLocationAndControlId(feedback.options, feedback.location)
const { theLocation, referencedVariables } = this.#fetchLocationAndControlId(
feedback.options,
feedback.location,
true
)

if (
!feedback.location ||
Expand All @@ -553,14 +558,20 @@ export default class Controls extends CoreBase {
theLocation.row === feedback.location.row)
) {
// Don't recurse on self
return {}
return {
referencedVariables,
value: {},
}
}

const render = this.graphics.getBank(theLocation)
if (render?.style) {
if (!feedback.options.properties) {
// TODO populate these properties instead
return cloneDeep(render.style)
return {
value: cloneDeep(render.style),
referencedVariables,
}
} else {
const newStyle = {}

Expand All @@ -569,13 +580,19 @@ export default class Controls extends CoreBase {
}

// Return cloned resolved style
return cloneDeep(newStyle)
return {
value: cloneDeep(newStyle),
referencedVariables,
}
}
} else {
return {}
return {
referencedVariables,
value: {},
}
}
} else if (feedback.type === 'bank_pushed') {
const { theControlId } = this.#fetchLocationAndControlId(feedback.options, feedback.location)
const { theControlId, referencedVariables } = this.#fetchLocationAndControlId(feedback.options, feedback.location)

const control = this.controls.getControl(theControlId)
if (control) {
Expand All @@ -586,9 +603,15 @@ export default class Controls extends CoreBase {
isPushed = control.getActiveStepIndex() !== 0
}

return isPushed
return {
referencedVariables,
value: isPushed,
}
} else {
return false
return {
referencedVariables,
value: false,
}
}
} else if (feedback.type == 'bank_current_step') {
const { theControlId } = this.#fetchLocationAndControlId(feedback.options, feedback.location)
Expand All @@ -597,9 +620,15 @@ export default class Controls extends CoreBase {

const control = this.controls.getControl(theControlId)
if (control && typeof control.getActiveStepIndex === 'function') {
return control.getActiveStepIndex() + 1 === theStep
return {
referencedVariables,
value: control.getActiveStepIndex() + 1 === theStep,
}
} else {
return false
return {
referencedVariables,
value: false,
}
}
}
}
Expand Down
3 changes: 1 addition & 2 deletions lib/Internal/Variables.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,13 +178,12 @@ export default class Variables extends CoreBase {
delete this.#variableSubscriptions[feedback.id]
}

variablesChanged(changed_variables, removed_variables) {
variablesChanged(all_changed_variables, changed_variables, removed_variables) {
/**
* Danger: It is important to not do any debounces here.
* Doing so will cause triggers which are 'on variable change' with a condition to check the variable value to break
*/

const all_changed_variables = new Set([...removed_variables, ...Object.keys(changed_variables)])
const affected_ids = []
for (const [id, names] of Object.entries(this.#variableSubscriptions)) {
for (const name of names) {
Expand Down
2 changes: 1 addition & 1 deletion webui/src/Controls/ActionSetEditor.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ function ActionTableRow({

{location && showButtonPreview && (
<div className="cell-bank-preview">
<OptionButtonPreview location={location} options={action.options} useVariables={true} />
<OptionButtonPreview location={location} options={action.options} />
</div>
)}

Expand Down
2 changes: 1 addition & 1 deletion webui/src/Controls/FeedbackEditor.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ function FeedbackEditor({

{location && showButtonPreview && (
<div className="cell-bank-preview">
<OptionButtonPreview location={location} options={feedback.options} useVariables={false} />
<OptionButtonPreview location={location} options={feedback.options} />
</div>
)}

Expand Down
4 changes: 2 additions & 2 deletions webui/src/Controls/OptionButtonPreview.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import { useDeepCompareEffect } from 'use-deep-compare'
* @param {string} param.location where this preview is located (if any)
* @returns
*/
export function OptionButtonPreview({ location, options, useVariables }) {
export function OptionButtonPreview({ location, options }) {
const socket = useContext(SocketContext)

const [image, setImage] = useState(null)
useDeepCompareEffect(() => {
const id = nanoid()
socketEmitPromise(socket, 'preview:button-reference:subscribe', [id, location, options, useVariables])
socketEmitPromise(socket, 'preview:button-reference:subscribe', [id, location, options])
.then((newImage) => {
console.log('got image', newImage)
setImage(newImage ? dataToButtonImage(newImage) : newImage)
Expand Down

0 comments on commit fae6f58

Please sign in to comment.