ParameterView Module
Functions and values
| Function or value | Description |
Full Usage:
addParamComponent newCompSpec dispatch compId
Parameters:
NewParamCompSpec
dispatch : Msg -> Unit
compId : ComponentId
Returns: Unit
|
|
Full Usage:
addParamComponents newCompSpecs dispatch compId
Parameters:
NewParamCompSpec list
dispatch : Msg -> Unit
compId : ComponentId
Returns: Unit
|
|
|
Every instance of a sheet binds every parameter that sheet declares. Placing an instance establishes that - customComponentParamPopup asks for a value for each parameter - but a parameter added to a sheet that ALREADY has instances would leave every one of them binding nothing. An unbound parameter is a state the design deliberately does not have: it elaborates at the sheet's own declared value, which is a fact about the sheet and not about the instance, and it makes "default" into a concept the user has to reason about. This is the mirror of removeParamFromInstances, which drops a deleted parameter's binding from every instance across the project, and it works the same way: LoadedComponent canvases only, since a sheet cannot instantiate itself and so the open sheet's own canvas can hold no instance of it. The value bound is the one just declared, so nothing about the design changes - that is exactly what an unbound parameter elaborated to. What changes is that the binding exists, can be seen and edited, and, being a literal, is what the bind-to-top offer fires on: following an outer parameter of the same name is then offered on each instance rather than having to be found. No slot is created, because a literal needs none (see updateParamSlot). The work itself is ParameterAnalysis.bindParamOnInstances, which is a function of the loaded components alone and so can be tested without building a Model; this only reaches it.
|
|
|
|
Apply accepted bind-to-top offers: create the parameters and bindings of their chains, update the open sheet's symbols to match, and persist. A sheet whose file was in step with memory is written through immediately; the open sheet (whose canvas belongs to the draw block) is marked as needing saving instead, so accepting an offer never silently commits unrelated circuit edits. |
|
Give each pasted component the parameter slot expressions of the component it was copied from, so that a pasted copy stays parameterised rather than freezing at whatever value it was showing. Slots are keyed by component id, and a paste mints new ids, so without this the parameterisation is silently lost. A slot is only copied when every parameter it refers to is declared on this sheet: pasting into a sheet that does not declare them would otherwise leave a slot referring to nothing, which breaks the invariant that every parameter used on a sheet is defined on it.
|
Full Usage:
customComponentParamPopup childLdc place model dispatch
Parameters:
LoadedComponent
place : ParamBindings -> NewParamCompSpec list -> unit
model : Model
dispatch : Msg -> unit
|
A popup asking for a value for every parameter the sheet inside a custom component declares, raised when an instance is placed. Placing an instance without asking would silently freeze the child sheet's defaults into it - the stale-chain problem - so the choice is made explicitly instead. Where the sheet the instance is being placed on declares a parameter of the same name, a button binds to that parameter rather than entering a value, and the two then stay in step. `place` receives the bindings to put on the instance and the slots to create for it.
|
|
|
|
|
|
|
|
|
Full Usage:
evaluateConstraints paramBindings exprSpecs
Parameters:
ParamBindings
exprSpecs : ConstrainedExpr list
Returns: Result<Unit, ParamConstraint list>
|
Evaluates a list of constraints got from slots against a set of parameter bindings to check what values of param are allowed. Pure: the constraints that are not met are returned, not dispatched. This used to send a notification from inside a List.filter, and one of its two callers is editParameterBox's isDisabled - which the popup asks, while rendering, whether its button should be greyed out. A constraint that could not be evaluated would have dispatched from there, re-rendered, and dispatched again. It also sent SetPopupDialogText, which is where some popups keep the text the user is typing. Everything the caller has to say is carried in the ParamConstraint it gets back, which is where the caller already looks for it: a bound that cannot be worked out comes back as a constraint whose message says so.
|
|
The grammar of the box above it, offered as a link that opens into the box's own field. Belongs to a box rather than to the pane. It appeared once at the foot of the pane, where it explained boxes several inches above it and was read as a footnote to the whole component; and it showed on the sheet-properties pane, which has no box to type an expression into at all. Two conditions, and both matter. The open sheet must declare a property - with none, an expression can only be arithmetic on numbers the user has already typed, so the grammar is advertising a feature with no use. And the field must have focus, which CSS decides with :focus-within: the link is one line, but a line under every width box in the pane is a line nobody asked for until they are actually typing in one. A `details` with its marker taken off, so the link is a link and the disclosure state costs nothing to keep: it opens and closes by itself and remembers nothing between selections, which is right for a reference someone reads once.
|
|
|
Full Usage:
getDefaultParamDefs loadedComponent
Parameters:
LoadedComponent
Returns: ParamDefinitions
|
|
Full Usage:
getDefaultParams loadedComponent
Parameters:
LoadedComponent
Returns: ParamBindings
|
|
|
|
Full Usage:
getParamDefs loadedComponent
Parameters:
LoadedComponent
Returns: ParameterDefs
|
|
Full Usage:
getParamSlots loadedComponent
Parameters:
LoadedComponent
Returns: ComponentSlotExpr
|
|
Full Usage:
instanceBindingProblem ldcs childSheet baseBindings name value
Parameters:
LoadedComponent list
childSheet : string
baseBindings : ParamBindings
name : ParamName
value : ParamInt
Returns: Result<unit, ParamError>
|
What is wrong, in the words of whoever the message was written for, with setting one parameter of an instance of `childSheet` to `value`. An instance binding used to be checked against nothing at all: the boxes that set one pass an empty constraint list, so the bounds a width must satisfy - at least one bit, at most maxIssieBusWidth - applied only to a value typed straight into a component's own box. Binding a child parameter to a hundred thousand sized the child's ports at a hundred thousand bits, and the first thing to object was the simulator allocating them. The bounds cannot be handed to paramInputField as a ParamConstraint list, which is why this is a function instead. They belong to the slots of the CHILD sheet, and are expressions in the CHILD's parameters; paramInputField evaluates its constraints in the parameters of the sheet the instance sits on, where those mean nothing. So the check resolves the child sheet at the bindings it would have - the same thing editParameterBox does for the open sheet, and the same constraints, derived by ComponentSlots.constraintsFor from each slot's own component. Only the slots that USE the parameter are checked. Every other slot is being evaluated at values this box is not setting, so a complaint from one would name the wrong box.
|
|
The open sheet's parameter data, which reads as empty on a sheet that declares none and is CREATED by writing to it. Composed through lcParameterDefs_, a lens, rather than lcParameterSlots_, a prism. Prism onto prism gives an optic whose setter silently does nothing when the outer get is None, so every write to a sheet with no parameter data yet was dropped - and that is precisely the sheet a first declaration goes to. Two write paths existed because of it: this one, and a hand-written one that special-cased None. There is one now.
|
Full Usage:
makeParamBindingEntryBoxes model comp custom dispatch
Parameters:
Model
comp : Component
custom : CustomComponentType
dispatch : Msg -> Unit
Returns: ReactElement
|
The values one custom component instance supplies for the parameters of the sheet inside it. One block per property, exactly as a built-in component's width is edited: an instance of a sheet is not a different kind of thing from a Register, and the pane should not make it look like one. Each block heads itself with the property's name and its declared description - compulsory precisely so that it can be read where the value is chosen. The name is the CHILD sheet's name for the property, and identifies which slot is being set; it is not a name that can be used in the box, since an instance binding is an expression in the properties of the sheet the instance SITS ON. It is shown because a block with a description and no name says nothing about which of several properties is being set. Properties come out in Map order, which is alphabetical by name. With one property - the case component libraries are built around - there is nothing to order. With several the sequence is arbitrary from the user's side, and nothing records an authored order to use instead; that is accepted rather than solved.
|
|
The open sheet's parameter data has just changed. Nothing in the canvas need have changed with it: declaring a parameter, writing its description, or giving a slot an expression that works out to the width already shown all leave the canvas identical. UpdateHelpers.currentSheetIsOutOfDate compares only the canvas, so without this the save button stays dark, switching sheets does not save, and the work is silently dropped. LoadedComponentIsOutOfDate is the flag that survives: SavedSheetIsOutOfDate is recomputed from it on every draw block message, and is set here too only so that the button responds before the next such message arrives. Saving the sheet clears both. The work is ParameterAnalysis.markSheetOutOfDate, which is a function of the loaded components alone and so can be tested without building a Model; this only reaches it.
|
|
|
Full Usage:
modifyDeclaredParam project paramName change dispatch
Parameters:
Project
paramName : string
change : ParamDefinitions -> ParamDefinitions
dispatch : Msg -> unit
|
Declare a parameter on the open sheet, change what it is declared as, or delete it. The one path that writes what a sheet DECLARES. It used to take a discriminated union choosing between this and writing a slot, but nothing ever constructed the second case: slots are written by updateParamSlot, through the model, which is where the properties boxes already are. The sheet's parameter data is reached through lcParameterDefs_, so a sheet that declares nothing yet needs no special case: it reads as empty and writing to it creates the record.
|
|
|
Full Usage:
paramInputField model prompt defaultValue currentValue currentExpr constraints extraCheck comp compSlotName dispatch
Parameters:
Model
prompt : string
defaultValue : ParamInt
currentValue : Option<ParamInt>
currentExpr : Option<ParamExpression>
constraints : ParamConstraint list
extraCheck : (ParamInt -> Result<unit, ParamError>) option
comp : Component option
compSlotName : CompSlotName
dispatch : Msg -> unit
Returns: ReactElement
|
|
Full Usage:
paramPrompt nameStr definition
Parameters:
string
definition : ParamDefinition
Returns: string
|
|
|
|
Full Usage:
portWidthsOfInstance ldcs parentBindings childSheet instanceBindings
Parameters:
LoadedComponent list
parentBindings : ParamBindings
childSheet : string
instanceBindings : ParamBindings
Returns: Map<string, int>
|
The port widths an instance of `childSheet` has when it binds its parameters as given. The work is CanvasExtractor.signatureOfInstance's, which is the one place that knows what an instance's ports are; this only turns its answer into the label-to-width map that updateCustomComponent wants. The label comes from the child sheet's Input or Output COMPONENT, not from the `IO` slot that sets its width, so a port renamed since its slot was created is still sized by that slot - see ParameterTypes.sameSlotName.
|
|
Bring every sheet into line with what its design sets its parameters to.
The recomputation itself is pure (ParameterAnalysis.propagateParameterValues); this is the part
that has to touch the world, and it treats the open sheet differently from the rest because its
canvas is not in LoadedComponents but in the draw block:
- a CLOSED sheet whose values changed is rewritten and written to its file at once, because
only the open sheet is ever allowed to be unsaved. A sheet that cannot be written - a
library component, which belongs to its library - is still brought into line in memory, so
that looking at it shows the right thing, but its file is left alone and it is not called
unsaved: the difference is derived and there is nothing for the user to save;
- the OPEN sheet's values are pushed through the same symbol-change path the properties pane
uses, so symbol size, ports and geometry are recomputed rather than patched, and the change
joins that sheet's undo history like any other edit.
|
|
|
|
A binding of a parameter of `sheetName` on an instance of that sheet no longer means anything once the parameter has gone, so drop it from every other sheet in the project. Bindings live in two places: the instance's own ParameterBindings, and a CustomCompParam slot of the sheet the instance sits on.
|
|
What a slot is called where the user has to recognise it: the field of the component that the expression fills. Written once, because the message that refuses to delete a property and the table of parameterised components both name the same thing and had drifting copies of this. "Width", not "Buswidth": the properties box it names is labelled "Width (bits)", and the developer's word for the slot means nothing to whoever is being asked to go and change it.
|
Full Usage:
topSheetChoiceCheck model
Parameters:
Model
Returns: ((Msg -> unit) -> Model -> ReactElement) option
|
A popup asking the user to choose the top sheet, or None. It fires only when several top-level sheets exist, none has been chosen, and they disagree about the parameter values the opened sheet displays with - roughly once per project. It never blocks opening. Cancelling records the project in Model.TopSheetChoiceDeclined and the question is not asked for it again, so the popup can never nag.
|
|
|
Full Usage:
updateComponentSlots dispatch model compIdStr slotValues
Parameters:
Msg -> unit
model : Model
compIdStr : string
slotValues : (CompSlotName * ParamInt) list
|
Push the values of the parameterised slots of ONE component onto the canvas. All of a component's slots are applied together because two of the messages replace a whole field of the component type - a SplitN's width and LSB lists, a custom component's parameter bindings - and are built here from `model`, which is a snapshot: issued one slot at a time they would overwrite each other, leaving all but the last slot at its old value. (ChangeWidth and ChangeInputValue read the live symbol and so do not have this problem.)
|
Full Usage:
updateComponents newBindings model dispatch
Parameters:
ParamBindings
model : Model
dispatch : Msg -> Unit
Returns: Unit
|
|
Full Usage:
updateCustomComponent labelToEval newBindings comp
Parameters:
Map<string, int>
newBindings : ParamBindings
comp : Component
Returns: Component
|
|
Full Usage:
updateParamSlot slot exprSpec model
Parameters:
ParamSlot
exprSpec : ConstrainedExpr
model : Model
Returns: Model
|
|
|
|