MethodController:
Filter:
MethodController/Classes (extension) | MethodControllerQuark

MethodController
ExtensionExtension

A Controller that links a method ( usually a getter or a setter) to another Object like a View or Synth

Description

A MethodController is a Controller Class that links a Model to multiple Views.

The class is a generalization of the CV class from the Conductor Quark.

The data stored in the Model is accessed by getter and setter methods chosen when the MethodController is created.

MethodController:value gets the Models data.

The View is accessed by getter and setter methods chosen when the View is linked to the controller.

Often the data in a Model is of a specific type and has a specific range because of that it makes sense to associate it with a ControlSpec.

The unmaped value of the models data ( in the range 0 to 1) can be accessed by the MethodController:input.

This allows us to map the data to the 0 to 1 range often used in Views.

If the data in the Model can not be easily specified but the views should make use of of their own interpretation of the data a spec can be provided to the link method.

The setter methods can be derived from the getter methods.

The default getter method is value.

To be able to access elements of an Array it is possible to define a getter or setter with initial arguments.

A shortcut for this is provided by the forArray classmethod.

The MethodController becomes a dependant of the Model and the linked Objects, if a link is set up. When a link is released (unlink) these dependancies are removed. Views usually remove themselves from the Dictionary onClose. (This behaviour would break if someone make use of the onClose variable and overwrites the function that got put there) To avoid memory leaks links have to be unlinked.

Class Methods

.new

Create a MethodController

Arguments:

model

The Object that holds the data

modelget

Symbol, Array or Function that is used to get the data from the model.

A Symbol of the name of the method that gets the data. default is \value.

a Array of the form [a Symbol, ... args] to be able to get data from the Model with methods with multiple arguments like [\at, 0].

or

a Function a function that gets as first argument the model for Example { |m|m.value*2 }.

modelset

Nil, Symbol, Array or Function that is used to get the data from the model.

If no modelset is specified modelget.asSetter is called. This works well with symbols.

a Symbol of the name of the method that sets the data. default is modelset.asSetter i.e. \value_ .

a Array of the form [a Symbol, ... args] to be able to set data in the Model with methods with multiple arguments like [\at, 0].

or

a Function a function that gets as first argument the Model and as a second argument the value for example { |m, v|m.value = v/2 }.

spec

A ControlSpec that specifies the data of the Model. The spec is used to unmap the data to the 0 to 1 range used by many Views. The default value is a NonSpec a spec that does not specify anything.

updateObjectOnChange

This argument is true or false. default value is true. If the Model has a ObjectController as a dependant it might be reasonable to assume that the controller needs update after data in the model changed therefore the ObjectController is called. If this behavious is not undesirable the variable can be set to false.

msg

msg is the msg used to identify the specific parameter that is updated in the Model.

if model.changed( msg) is called the MethodController is updated.

usually msg is derived from the modelget variable.

if modelget is a symbol msg is that Symbol.

if modelget is a array a msg is derived from that Array [\at, 0] becomes \at_0_ .

if modelget is a function the msg is the symbol \methodControllerSync .

Returns:

a MethodController

.forArray

If the Model is an Array or similar ArrayedCollection that where data is accessed through \at and \put this method simplifies the specification of getter and setter.

Arguments:

model

the model

pos

The position of the data in the model that is accessed. resulting in a getter array of the form [\at, pos] and a setter array of the form [\put, pos]

spec

a ControlSpec

updateObjectOnChange

default is true

msg

default is derived from the getter method \at_pos_

Returns:

a MethodController

Instance Methods

.input

getter gets the unmaped data from the model ( making use of the spec of the MethodController)

setter maps and sets the data in the model ( making use of the spec of the MethodController)

Arguments:

val

Usually a number in the range 0 to 1

Returns:

if a ControlSpec is specified the getter usually returns a number in the range 0 to 1

.value

getter gets the data from the model.

setter sets the data in the model.

Arguments:

val

Returns:

the data from the model.

.next

calls MethodController: -value for compatibility with Streams

.link

shortcut for linkInput

.linkInput

Links to a object ( often a View ) so that the object is updated on a models change.

Linking means here a bidirectional connection.

The object/view gets the model as unmaped by the provided spec.

Model gets the object/views state as mapped by the provided spec.

This link makes use of the MethodController: -input method.

Arguments:

obj

Object to be linked often a View.

objget

Method used to get data from the View.

Default is \value.

Either Symbol, Array, or Function ( see MethodController: *new modelget)

objset

Method used to set data in the View.

Default is \value_.

Either Symbol, Array, or Function ( see MethodController: *new modelget)

spec

A ControlSpec that can be used to map the values returned by MethodController: -input to the range of the View()

.linkValue

links a object ( often a View) to the Model via the value methods of the controller.

Arguments:

obj

Object to be linked often a View.

objget

Method used to get data from the View.

Default is \value.

Either Symbol, Array, or Function ( see MethodController: *new modelget)

objset

Method used to set data in the View.

Default is \value_.

Either Symbol, Array, or Function ( see MethodController: *new modelget)

spec

A ControlSpec that can be used to map the values returned by MethodController: -value to the range of the View()

.linkInputFrom

In some cases only a onedirectional connection is needed.

linkInputFrom updates the model from the linked View.

For details on the arguments look at MethodController: -linkInput.

.linkValueFrom

In some cases only a onedirectional connection is needed.

linkInputFrom updates the model from the linked View.

For details on the arguments look at MethodController: -linkValue.

.linkInputTo

In some cases only a onedirectional connection is needed.

linkInputTo updates the linked View from the model.

For details on the arguments look at MethodController: -linkInput.

.linkValueTo

In some cases only a onedirectional connection is needed.

linkValueTo updates the linked View from the model.

For details on the arguments look at MethodController: -linkValue.

.update

update is called by model.changed( msg).

.updateLinks

if the model might have changed but one is not sure one can use this method to update the linked Views.

.unlink

releases or unlinks the obj.

unlink is assiged to be called by View:onClose automatically if View:onClose is not overwritten by another function. If the Object is not a View it has to be called explicitly to avoid memory leaks.

Arguments:

obj

object to be released

.remove

Remove this MethodController from its models dependancy. If all links are released it is called. Because calling MethodController:update would be of no use.

.replaceModel

replaces the model

Arguments:

newModel

Model to replace the old model.

Examples

A color chooser.

to make clear the value of this class I create three windows that are updated seamlessly.

It makes use of the ObjectController class.

An Array of frequencies

This example is like the previous a color chooser. But in this case the model is not a color itself but rather an array of 3 frequencies. This example aims to make clear why I implemented MethodController and its link functions with two specs.

Button

In the following I introduce a few examples for commonly used Views

CheckBox

Knob, Slider, NumberBox, LevelIndicator

RangeSlider

Slider2D

MultiSliderView

Because MultiSliderView returns an Array we need an object that holds an Array.

A List similar to a Ref holding an Array as a reference.

EnvelopeView

Unfortunately EnvelopeView is not really a view of an envelope but rather a View of a connected dots.

In this case the EnvelopeView is just only displays the Envelop. The Slider2D changes the Env.

This is not the most reasonable example but it showed me that it must be possible to hook more than one controller to a View.

PopUpMenu

The following is similar to the SV of the Conductor Quark.

ListView

StaticText, TextField

The following is similar to the TV of the Conductor Quark.

link to Object

It is possible to link objects that are not Views but in this case

not a view

replaceModel

link to Synth

This is basically stolen from CV from the Conductor and/or CVCenter Quark ( including the documentation).

Synths specify initial values of parameters as a flat Array of pairs consisting of a name and its initial value:

"Extended argument arrays" allow MethodControllers to be used in place of the initial value. This is the standard syntax for establishing connections between MethodControllers and a server. In an extended argument array, the MethodController's value can be altered before being sent, multiple MethodController's can determine the value to be sent, and the value to be sent can be determined by a function ( here freq is just meant as an example key):

value[freq: 440]
MethodController[freq: aMethodController]
altered MethodController[freq: [aMethodController, aMethodController.midicps]]
combination[freq: [[aMethodController, bMethodController], aMethodController.midicps + bMethodController]]
function[freq: [aMethodController, { aMethodController.midicps.value + 33.rand }]]

For example, the method Synth: *controls is identical to Synth: *new except the args parameter is extended:

basic MethodController connection

modified MethodController connection

multiple modified connection

In the previous two examples, the modifying expression is actually a combination of Streams altered with binary and unary operators. This is concise, but in some cases, it may be necessary to use a Function to define the modification.

NOTE: Within a function definition it is necessary to explicitly extract the value of the MethodController using a value message.

Simple Synth

A simple synth controlling GUI

Synth with start button

In this example a synth is started by a button and released. the button is representing if the synth is running or not.

MIDI

to link a midifunc to a controller is so simple that i don't know what to describe about it.

MIDIIn.doNoteOnAction( 1, 1, 128.rand, 128.rand); // spoof

TODO and stuff

more complex views:

Final stuff

My implementation is shaped by my use of CV but because I aimed for a implementation that is clear to me I simplified code to use cases that I know this means especially that i didn't implemented links to Node, NodeProxy, and Bus. For the case you have use cases for that please feel free to contact me.