Have you ever found yourself wishing you that you could specify parameters for non-global variables in Codea? If so, you’re in luck. I’ve just released a new library for Codea that allows binding parameters to any table’s variables, not just _G. It works by creating proxy global variables for all of an object’s parameters, feeding those into Codea’s parameter.* functions, and updating those variables every frame to reflect the tracked variable’s value. tparameter usage should already feel familiar to you, as it is designed to be as similar as possible to Codea’s parameter class. However there are a couple of differences: you specify a name for the parameter (for example the class name of the object bound to the parameter, or some other identifying string), as well as the table that contains the variable you wish to parameterize. For example:
function MyClass:init()
self.x = 10
-- parameter for self.x
tparameter.integer('MyClass', self, 'x', 0, 100)
end
tparameter tracks all of the tables that have specified parameters, and adds them to the parameter selector where they can be selected. To select, slide the selector slider to the parameters you wish to see, and hit the ‘SELECT’ button. When an object is selected, the parameter list reloads with that object’s parameters, so that you can tweak them.
The main features of tparameter are listed below.
##Metavariables
For all parameter types except for ‘action’ and ‘method’, when creating a tparameter, you can parameterize metavariables (i.e. variables of variables). For example, you could parameterize just the ‘r’ component of a color:
function MyClass:init()
self.color = color()
tparameter.integer('MyClass', self, 'color.r', 0, 255)
end
This is done by specifying an ‘index path’ to your metavariable. In the above example, ‘color.r’ is the index path to self.color.r. You can also specify array indices in your index path:
function MyClass:init()
self.array = {'Codea', 'is', 'awesome'}
tparameter.text('MyClass', self, 'array[2]')
end
If you need to specify a numeric string as an index, use the ‘.’ in your index path instead of []:
function MyClass:init()
self.list = {}
self.list['1'] = 10
tparameter.integer('MyClass', self, 'list.1')
end
##New parameter types
In addition to the normal parameter types, tparameter also allows specifying new ‘pseudo-parameters’. These are:
method : like action, but calls a member function on an object instead of a regular function
itext, ntext : like ‘text’, but for strictly numeric values; converts entered values to integers/numbers.
##can be used with _G
Since you can’t really use Codea’s parameter class if you are using tparameter due to the way tparameter must frequently clear and reload the parameter list, tparameter provides special consideration when creating parameters for the _G table. Usage is straightforward:
function setup()
myGlobalInt = 50
tparameter.integer('Global', _G, 'myGlobalInt', 0, 100)
end
A parameter list will be created for _G with the name ‘Global’. Simply select this list in the parameter inspector, and you can modify your globals just like you would using Codea’s parameter class. When _G is specified as the table, the variables specified are truly global variables. In the above example, the parameter operates on the global variable ‘myGlobalInt’. Metavariables may be specified for parameters on _G.
##other features:
- using tparameter.notify, you can specify that your object would like to know when it’s been highlight/selected in the inspector. You can use this to do things like modify the visual state of the highlighted/selected object, making it easier to tell exactly which object you are choosing.
- all tparameters except ‘action’ and ‘method’ can specify optional callback functions when the variable values change (just like Codea’s parameters)
- parameter lists for an object can have multiple names. This is especially useful when creating parameters for subclasses of classes that also create parameters. For example:
MyClass = class()
function MyClass:init()
self.value1 = 10
tparameter.integer('MyClass', self, 'value1', 0, 100)
end
MySubClass = class()
function MySubClass:init()
MyClass.init(self)
self.value2 = 20
tparameter.integer('MySubClass', self, 'value2', 0, 100)
end
The parameter list for this object will now contain ids with the names “MyClass” and “MySubClass”. In the parameter inspector, the names of the parameter variables will be _MyClass_value1 and _MySubClass_value2 respectively.
A note about tparameter.watch
Currently there is a bug in Codea where ‘watch’ parameters in a long list of parameters will crash the app. As a workaround for now,
tparameter.watch actually uses a parameter.text, but modifying the text in the window will not change the watched variable’s value.
Example project containing source
An example Codea project containing the tparameter class (and it’s dependencies, ‘memoize’ and ‘Timer’) can be found here:
https://gist.github.com/apendley/5401761
I tried to flesh out the example to illustrate all of the features of tparameter, but I’m sure there are details that have slipped my mind. Feel free to ask me any questions about it, I’ll do my best to answer them.