|
So far, this documentation has described how a single config can specify specific parameters for a scene and how this technique can be applied to create simple configs. Not all of the configs included with SoftSkies, however, behave this way. Instead, the included configs are typically separated into three groups: "component configs" (like those described in the previous section), which specify a subset of parameters for a scene; "super-configs", which choose and combine component configs; and "interface configs" which setup interface elements but which do not change any scene settings. Though component configs can specify any set of scene parameters, the standard set of component configs are further divided into the groups "Colors" and "Backgrounds". This approach allows for far more diversity of cloud scenes. It lets the visualizer dynamically choose from a library of components and combine them into unique scenes based on a user's wishes.
Component picking is accomplished using a scheme based on "meta-tags", which specify general information about the appearence or "feeling" of a component. The super-configs use these meta-tags to assemble diverse components into coherent scenes. A super-config, might, for example, specify that a user is interested only in bright, fast moving scenes with abstract backgrounds. Instead of keeping a list of specific configs which provide this specific combonation of features, the meta-tags system allows the super-config to find all matching components dynamically.
The Configs Directory Structure
Before going into detail on each config type is written, the structure of the "Configs" directory is discussed. If you wish to work with a config which interacts with other configs, you'll need to familiarize with how the different categories of configs are organized. Though the structure defined here is not strictly enforced, the convention should be followed so that user-authored configs can be found and executed by the SoftSkies visualizer.
Directory: Configs
Any configs held in the top-level directory are considered super-configs. They are called directly from the visualizer in order to handle configuration. Typically, however, they do not perform configuration by themselves–they choose from component config files stored in subdirectories (described below).
Directory: Configs/Library
A directory containing utility Python files which perform frequently used tasks. These files should not be modified.
Directory: Configs/Backgrounds
A directory of component configs that specify background styles and imagery. If you design custom component configs which specify backgrounds, they should be placed in this directory.
Directory: Configs/Colors
A directory of component configs that specify color schemes. If you design custom component configs which specify color schemes, they should be placed in this directory.
Directory: Other subdirectories
A number of other subdirectories are used to stored resources used by specific configs. These folders should not typically be modified.
Slightly More Advanced Python
The concepts discussed below will require some additional Python knowledge. Again, this documentation is not intended as a general introduction to the Python language. Only the concepts required to implement SoftSkies configs are covered here. For a more general introduction to Python, see https://www.python.org.
Setting Python Variables
As configs become more complex, they may need to preform more advanced computations and store the result of such computation in Python variables. In Python, values are assigned to variables using the following syntaxt:
myVariable = 10
This example shows a variable set to a simple integer, but variables can be set to a wide variety of types including strings, numbers and dictionaries, as described below. More information on setting variables in Python can be found here.
Python Dictionaries
A "dictionary" in Python is a way to associate one piece of information (a "key") with another (a "value"), much in the way a real dictionary associates a word with its meaning. Dictionaries are used in SoftSkies to associate keywords with numerical values in order to specify meta-tags and meta-tag queries. In a meta-tag information dictionary or a meta-tag request dictionary, each meta-tag keyword is associated with a value indicating the keyword's importance. The specfics of meta-tag dictionaries are explained in more detail below. For the moment, however, we examine the syntax of a dictionary in Python. The first example below creates a dictionary with values for 3 different keys. Dictionaries can hold any number of elements, including 0. The second example shows an empty dictionary.
myQuery = { 'myKey1' : 1, 'myKey2' : 2, 'myKey3' : 3 }
myQuery = {}
More information on dictionaries in Python can be found here.
Defining Functions and "Callbacks"
This documentation has previously described how simple configs simply set parameters to specific values when they are run. More advanced config files, such as the super-configs may require more sophisticated interaction with the visualizer. In particular, these configs typically need to respond to requests or events from the engine or from other config files. These requests are handled by defining functions. Functions are named pieces of code which can be called by code elsewhere. Functions are defined in Python using the following syntax:
def functionName():
line-of-code-1
line-of-code-2
...
line-of-code-n
For example:
def myCallback():
SoundSpectrum.SetRGBColor( "cloud_color", 0, 0, 1 )
SoundSpectrum.SetParameter( "cloud_camera_angle", 0.0 )
In this example, we've defined a function called myCallback which will change some scene parameters when it is called. If this code were to appear in a config, then it could be triggered elsewhere by executing the myCallback function.
More information on functions in Python can be found here.
Writing Component Configs
As discussed previously, a component config simply sets a number of scene parameters in a certain way. In order for the component config to be picked by super-configs, however, some additional code is required. Component configs are picked based on the meta-tag qualities they exhibit. The Natural config, for example, does not keep a list of natural-looking components by name. Instead, it uses the "Natural" meta-tag to locate all of the components which fit the description. In this way, new component configs can be introduced at any time and the Natural config will find them. Additionally, super-configs can request multiple meta-tags in order to pick more specific components. A list of standard meta-tags used with SoftSkies is shown in the next section.
To make a component config work with meta-tag requests (and thus allow it to be picked, when appropriate, by existing super-configs), a config must define a method called getMetaTags() . getMetaTags() should return a dictionary defining the meta-information about the component config. The dictionary should contain a list of meta-tag keys and a values, on a scale from -5 to 5, representing how strongly they fit the tag. Meta-tags which do not have values in the dictionary are implicitly interpreted as 0–a meta-tag value of 0 indicates that the config is neutral with respect to a certain quality.
An example getMetaTags() function is shown below. These meta-tags indicate that the config is very bright, somewhat natural, but not very colorful.
def getMetaTags():
return { 'Bright' : 4, 'Natural' : 2, 'Colorful' : -3 }
For a given meta-tag describing a quality of the component config, the following table indicates how the tag value should be assigned.
Value |
Description |
5 |
Represents the quality perfectly |
4 |
Represents the quality well |
3 |
Represents the quality moderately |
2 |
Represents the quality somewhat |
1 |
Represents the quality slightly |
0 |
Neutral with respect to the quality |
-1 |
Represents the opposite of the quality slightly |
-2 |
Represents the opposite of the quality somewhat |
-3 |
Represents the opposite of the quality moderately |
-4 |
Represents the opposite of the quality well |
-5 |
Represents the opposite of the quality perfectly |
The classification of meta-tags in configs is not an exact science, but it's usually possible to give a good indication of whether a certain quality is fulfilled by a config. The goal is to simply give the super-configs some an indication of what a config is like without knowing exactly what it does.
Standard Meta-Tags for Included SoftSkies Configs
The following meta-tags are used for the config files distributed with SoftSkies. When creating your own configs, you can create and use any meta-tags you desire. Arbitrary meta-tags can be specified, though they are only effective if they are used by both component configs and super-configs. If a meta-tag appears in a component config, but is never requested by a super-config, the meta information for that tag will not be used.
- Bright: specifies whether a config produces light or dark imagery
- Natural: specifies whether a config produces natural or unnatural imagery
- Colorful: specifies whether a config produces colorful or non-colorful imagery
- SunSets: specifies whether a config can be classified as a sunset
- Storms: specifies whether a config can be classified as a storm
Writing Super-Configs
Super-Configs work by choosing and running component configs based on meta-queries. To choose component configs, a super-config will typically use the function SoundSpectrum.PickConfig() , and to execute the component, the super-config will typically call SoundSpectrum.RunFile() .
The function SoundSpectrum.PickConfig() expects two parameters: a string specifying the directory to search (relative to the Configs directory) and a dictionary describing the meta-query. The meta-query dictionary takes the same form as the dictionary returned by the getMetaTags() function described in the previous section: each dictionary key specifies a value indicating to importance of each meta-quality on a scale from -5 to 5. Positive values indicate that a quality is desirable while negative values indicate that the quality is undesirable. If a quality is not specified or its value is 0, the quality is not used in the search. SoundSpectrum.PickConfig() returns another dinctionary, which includes the name of the component config it picked with the key "Filename". The following example picks a color scheme from the "Colors" directory which is "Natural" but not too "Bright". The relative weights of the two tags specifies that the desire for a "Natural" config is more important than the desire for one that is not bright:
color = SoundSpectrum.PickConfig( 'Colors', { 'Natural' : 5, 'Bright' : -2 } )
Once a config has been chosen, it is executed using the function SoundSpectrum.RunFile() . To use SoundSpectrum.RunFile() , simply pass it the name of the file selected with SoundSpectrum.PickConfig() :
SoundSpectrum.RunFile( color[ 'Filename' ] )
Using these two functions, you can assemble a simple super config which picks and then executes component configs.
Super-Config Callback Functions
Code in the main body of a super-config file gets executed as soon as the config is loaded. So while we can now construct a config which generates a scene as soon as it is run, we cannot yet construct a config which creates new scene settings continuously. In order to generate custom new scene parameters each time a scene transition occurs, the super-config must provide callback methods. A callback method is a special Python method which is called internally from the SoftSkies engine in response to certain events. Callback methods have special names that the SoftSkies engine will look for, and if your config implements these methods, they will be called automatically when appropriate. By convention, all of the callback function names used by SoftSkies begin with "Handle". The standard SoftSkies callback function are described below.
HandleNewScene()
This function is called when a new scene is created. This function changes scene colors, backgrounds or any other parameter that the config controls. You should typically use a >HandleNewScene() to pick new semi-random scene parameters. That means that the function will change backgrounds or colors somewhat, while still maintaining the overall look and feel of your config.
Most of the standard configs implement this function to pick new component configs when the scene is changed. For certain configs, however, namely those that wish the allow a style to persist until it is explicitly changed (such as the SceneBuilder), this function may not make any changes to the scene.
HasCustomMenu()
This function must return 1 if a config has a custom menu associated with it. If this function is defined and returns 1, a config may add entries to the SoftSkies menu (and is expected to do so!). More detail on using custom menus is given in below in the section "Custom Interfaces".
An Example SuperConfig:
Combining the topics covered in the previous two sections, it is now possible to create a super-config which dynamically generates new scene parameters at every scene transition. To do so, a super-config will implement a HandleNewScene() callback function which picks and executes component configs based on some meta-tag query. A sample super-config, Natural.config, is shown below:
def HandleNewScene():
color = SoundSpectrum.PickConfig( 'Colors', { 'Natural' : 5 } )
background = SoundSpectrum.PickConfig( 'Backgrounds', { 'Natural' : 5 } )
SoundSpectrum.RunFile( color[ 'Filename' ] )
SoundSpectrum.RunFile( background[ 'Filename' ] )
print "Created new scene!"
HandleNewScene()
Code outside of function definitions is executed immediately and is considered to be initialization code for the config. In this case, the config the HandleNewScene() function immediately so that the config picks a new color and background as soon as it is executed. In addition, the HandleNewScene() function will be executed again each time the scene changes and new component configs will be picked. The HandleNewScene() function shown here uses the SoundSpectrum.PickConfig() method to choose component configs based on meta-queries and then executes them. As a final touch, this function will print out the message "Created new scene!" to the SoftSkies text console each time the scene is changed
Note that for some configs, it is undesirable to pick new colors and backgrounds at each new scene. In these cases, the config author may choose not to implement a HandleNewScene() function at all, and instead implement all config execution directly from the initialization code. Additionally, a config author may opt not to use SoundSpectrum.PickConfig() at all, and instead select predetermined component configs by name.
Custom Interfaces
A final feature of configs is the ability to modify the SoftSkies menu to allow users to interact with a config. The menu may be configured to allow users to navigate through available settings (as with the main "Skies Library", which is itself generate by a config file), or it may allow users to interact with a running config (as with the "Skies Builder", also a config!). In order to setup a custom interface with a config, your config must implement the callback function HasCustomMenu() , and the function must return 1. The functions used for creating custom interfaces are listed below and discussed in more detail in the section "The SoundSpectrum Config API"
SoundSpectrum.SetHelpImage( imagepath ) : sets the help image in the center of the screen
SoundSpectrum.AddButton( title, action [, iconpath ] ) : adds a button to the interface menu
SoundSpectrum.AddSlider( title, action, minvalue, maxvalue ) : adds a slider to the interface menu
SoundSpectrum.GetControlValue( object ) : returns the value of an interface object (created using SoundSpectrum.AddButton or SoundSpectrum.AddButton )
The Power of Python
So far this document has described the features that SoftSkies provides to allow interaction with the engine. What this documentation does not cover is the unlimited potential of the Python scripting language and how all of the features of Python can be used to further customize the SoftSkies experience. Python includes advanced support for text processing, file handling, networking and much more–all of these features can be used to create SoftSkies configs with unique behaviors.
- Download customized cloud settings from a webserver
- Upload information about a selected configs to a webserver
- Create a SoftSkies based RSS Reader
- Dynamically generate custom config files
- Interface with any other program or code you have!
The SoundSpectrum Config API
A number of utility functions are available for constructing customized SoftSkies configs. Collectively, these functions are part of the "Sound Spectrum Config API". The API functions are described below:
SoundSpectrum.RunFile( filename )
Executes the contents of a file. This function runs the commands in a file, though it does not activate the file as the active config. See the function SoundSpectrum.ActivateConfig below for information on this distinction.
The file filename must be specified relative to the Configs directory. |
SoundSpectrum.ActivateConfig( filename )
Specifies a new active config file. Like SoundSpectrum.RunFile() , this function runs a file. Unlike SoundSpectrum.RunFile() , however, this function also deactivates the current definitions of HandleNewScene() and HandleSceneDefaults() , meaning that a config effectively surrenders control to the new config. Even if the new config doesn't reimplement these functions, the existing method definitions will no longer be used.
The file filename must be specified relative to the Configs directory. |
SoundSpectrum.PickConfig( directory, querydict )
The directory to search is a simple string, relative to the Configs directory. The meta request querydict is structured as a Python dictionary primitive. The dictionary keys are the relavant meta-tags, and the corresponding values represent the relative weights of each tag, on a scale from -5 to 5. Positive values indicate that a quality is desirable while negative values indicate that the quality is undesirable.
The dictionary may contain as many or as few metatags as desired. All tags not specified have an implicit value of 0, or "No Preference".
The following example picks a color scheme from the Colors directory which is "Natural" but not too "Bright". The relative weights of the two tags specifies that the desire for a "Natural" config is more important than the desire for one that is not bright:
color = SoundSpectrum.PickConfig( 'Colors', { 'Natural' : 5, 'Bright' : -2 } )
The directory directory must be specified relative to the Configs directory. |
SoundSpectrum.SetHelpImage( imagepath )
Sets an image (a PNG or JPG, 600x400 or smaller) to be displayed with the currently active config. This image can be used to provide the user with information about the currently selected config.
The file imagepath must be specified relative to the Configs directory. |
SoundSpectrum.AddButton( title, action [, iconpath ] )
Adds a button to the current menu. The title of the button is specified by the title argument.
The action argument specifies the action to be taken when the button is clicked. The action may be either a quoted Python command (typically a call to a Python function), or a quoted filename to be executed. If a filename is used, it must be specified relative to the Configs directory.
The optional argument iconpath specifies the location of a PNG file which is used as the button's icon. The icon will be scaled appropriately, but for best results should be 75x75 pixels. The icon will be placed in a same circular button-box used by the standard SoftSkies menus, so the edges of the icon will be clipped.
The file iconpath must be specified relative to the Configs directory. |
SoundSpectrum.AddSlider( title, action, minvalue, maxvalue )
Adds a slider control to the current menu with the title given by the title argument. This function returns a variable used to refer to the slider later on. You will need to store this value in order to later retrieve the slider's value using the SoundSpectrum.GetControlValue() function described below.
The action argument specifies the action to be taken when the button is clicked. The action may be either a quoted Python command (typically a call to a Python function), or a quoted filename to be executed. If a filename is used, it must be specified relative to the Configs directory. The action will typically make a call to SoundSpectrum.GetControlValue() in order to retrieve the value set with the slider.
The minvalue and maxvalue parameters specify the minimum and maximum values of the slider. Selecting the graduations on the slider give a smooth gradient between the minvalue and maxvalue. |
SoundSpectrum.GetControlValue( control )
Returns the current value of the specified control (a value returned by SoundSpectrum.AddSlider ()).
|
For detailed examples of how these API calls are used, see the "Skies Designer" config located in "Configs/Library/Menus/Skies Designer.config".
|
|