FingerTips Personalizer Framework (Personalizer Home)

FingerTips Personalizer Framework, Application Programming Interface

C++/MSXML 4.0sp2 Edition

2006


Table of Contents

1. Introduction
1.1. What You Must Know
1.2. Personalizer API System Requirements
1.3. Including FingerTips Personalizer API in Your Project
1.4. Instantiating Classes
1.5. Passing Objects to Personalizer Methods
1.6. The Flow in General
2. Bootstrapping
2.1. Unaware Mode
2.2. Exceptions
2.3. On Strings and Unicode
3. Personalizer Classes
3.1. Tuner (Singleton)
3.2. PreferencesManager (Singleton)
3.3. LibraryManager (Singleton)
3.4. Profile
3.5. Option
3.6. Binding
3.7. Control
3.8. Sequence
3.9. SequenceElement
3.10. SupportedOption
3.11. SupportedAction
3.12. ActionDefinition
3.13. OptionDefinition
3.14. OptionTypeDefinition
4. Preferences Tagging

Chapter 1. Introduction

1.1. What You Must Know

This manual is a work in progress.

Treat Personalizer exactly the way you have always treated homegrown configuration components. It may behave differently under the hood, and the information your game provides to it will have an unusual impact on subsequent games of the same genre, but in the end Personalizer API simply stores and retrieves configuration settings for you.

Personalizer is not intended for use in real time. This means that you should not read and write preferences with gameplay underway; unless the gamer explicitly requests a reconfiguration, such as through bringing up the Options menu. Although in-memory operations that Personalizer performs may be adequately fast for your game, the safe solution is to call Personalizer methods outside the actual gameplay.

Personalizer Visual Tuner, the visual tool used to prepare configuration metadata for your game, will generate the so called code snippets when you save the project. These snippets set a good example of how you should work with Personalizer API and can serve as the starting point for the Personalizer-related code in your game. This manual contains a more extensive explanation of Personalizer C++ API's features.

If you are the person responsible for packaging the game or creating the game's installer, please refer to other documentation for information on redistributables and relevant system requirements.

The only linking option for FingerTips Personalizer C++ API is run-time dynamic linking. The API code is included in the Personalizer Redistributable Core as a DLL which loads and unloads at run-time on your request. This conserves memory and simplifies updates of the API code. If a bug is found and fixed in the API, the Personalizer Redistributable Core needs to be updated, but not your game.

Personalizer API's namespace literal is personalizer. You can either save typing by using the using directive or qualify names of the API classes (personalizer::Profile, personalizer::Tuner, and so on). You can also shorten the literal through namespace aliasing (consult your C++ handbook or the Internet.)

For accessing countable structures such as profiles, options, bindings, sequences, sequence elements, and controls, use 1-based indices. For example, to retrieve the first option by its index, request option number 1, not number 0.

1.2. Personalizer API System Requirements

These are the system requirements for developing applications with FingerTips Personalizer C++ API:

  • Compilers. Any Microsoft Visual C++ compiler should work, starting with version 6.0.

    [Note]Note

    Other C++ compilers may also work, although no extensive testing has been done in this area. Wrappers for other languages are in consideration.

  • Operating Systems. Personalizer C++ API is expected to work on Windows 98, Windows Me, Windows NT4, Windows 2000, Windows XP, Windows Vista, and Windows Server editions.

1.3. Including FingerTips Personalizer API in Your Project

  1. When you install Personalizer Development Kit, it deploys Personalizer API header files under a location such as "C:\Program Files\Software Species\Personalizer\include". Your actual path may vary, of course. Add this path to the list of paths that the C++ compilers searches for included files.

  2. If you choose to write your own bootstrap code for Personalizer, include header files personalizer.hpp and DLLExports.hpp:

    #include <personalizer/personalizer.hpp>
    #include <personalizer/DLLExports.hpp>
    	    

    In code snippets generated by Personalizer Visual Tuner, these includes are already in place.

  3. Personalizer C++ API is implemented as a set of C++ classes. Since exporting C++ classes from a DLL is quite a nuisance (read about C++ name mangling, if interested), we used the following well-known approach. Every exportable class has a matching pure virtual interface. The DLL exports two helper functions: CreateClass and GetSingletonPointer. CreateClass returns instances of regular objects which you can cast as pointers to interfaces, and GetSingletonPointer returns pointers to singleton classes in the same fashion. At runtime, you need to load the Personalizer DLL using the Windows function LoadLibrary, obtain function pointers to CreateClass and GetSingletonPointer, and use these pointers to create the Personalizer objects as needed.

    Don't worry if this sounds complicated, the examples and autogenerated snippets will help you out quickly.

1.4. Instantiating Classes

There are two general kinds of classes in the Personalizer API: singleton classes and reflections classes.

Singleton classes (Tuner, PreferencesManager, LibraryManager) are limited to a single instance each, as the name suggests. They exist at all times and serve to interface between the game and the preferences memory. You can access these instances, but you cannot create them.

Since you don't create singleton classes directly, you must first obtain a pointer to such class in order to call its methods. Personalizer DLL exports function GetSingletonPointer that returns pointers to Personalizer singleton classes.

Reflection classes are regular classes. You can create objects of these classes by numbers whenever you need them. Reflection classes are used to transfer preferences and library information across the boundary of the interface created with singleton classes. Personalizer DLL exports function CreateClass that creates reflection objects.

The following snippets demonstrate the approach to creating instances of Personalizer classes. Function types pCreateClass and pGetSingletonPointer are declared in header DLLExports.hpp.

Example 1.1. Obtaining pointers to exported helper functions

	// function fCreateClass will create instances of regular Personalizer classes
	static pCreateClass fCreateClass = 0;
	
	// function fGetSingletonPtr will obtain pointers to singleton Personalizer classes
	static pGetSingletonPointer fGetSingletonPtr = 0;
	
	HINSTANCE personalizer_dll = 0;
	
	// ... call LoadLibrary here to load the Personalizer DLL
	
	// obtain pointers to exported DLL functions
	fCreateClass = reinterpret_cast<pCreateClass>(GetProcAddress(personalizer_dll, "CreateClass"));
	
	fGetSingletonPtr = reinterpret_cast<pGetSingletonPointer>(GetProcAddress(personalizer_dll, "GetSingletonPointer"));
	// 
	

Example 1.2. Obtaining pointer to a singleton class

	try
	{
	  // obtain a pointer to the Tuner singleton
	  personalizer::ITunerPtr pITuner
	    = static_cast<personalizer::ITunerPtr>((*fGetSingletonPointer())(CLS_Singleton_Tuner));
	
	  // call Tuner::bootstrap
	  pITuner -> bootstrap(...);
	}
	catch (...)
	{
	}
	

Example 1.3. Instantiating objects of regular classes

	try
	{
	  // create an Option object
	  personalizer::IOptionPtr pIOption 
	    = static_cast<personalizer::IOptionPtr>((*fCreateClass())(CLS_Option));

	  // call Option::set
	  pIOption -> set(...);
	}
	catch (...)
	{
	}
	

As you see, creation of Personalizer objects follows a simple pattern. Here is the generic syntax for creating an object:

	  I[class name]Ptr [object name] = static_cast<I[class name]>(fCreateClass([class identifier]));
	
and the generic syntax for obtaining a singleton instance pointer:
	  I[class name]Ptr [pointer name] = static_cast<I[class name]>(fGetSingletonPtr([class identifier]));
	

The following table lists class identifiers (CLS_[class name]) and corresponding class interface pointers (I[classname]Ptr) that you should use when creating Personalizer objects. Also note that Personalizer objects' constructors may throw exceptions; do wrap creation statements in try/catch blocks.

Identifier / Pointer TypeDescriptionUse With
CLS_Profile/IProfilePtrUse to create an instance of class Profile.CreateClass
CLS_Sequence/ISequencePtrUse to create an instance of class Sequence.CreateClass
CLS_SequenceElement/ISequenceElementPtrUse to create an instance of class SequenceElement.CreateClass
CLS_Option/IOptionPtrUse to create an instance of class Option.CreateClass
CLS_Binding/IBindingPtrUse to create an instance of class Binding.CreateClass
CLS_Control/IControlPtrUse to create an instance of class Control.CreateClass
CLS_ActionDefinition/IActionDefinitionPtrUse to create an instance of class ActionDefinition.CreateClass
CLS_OptionDefinition/IOptionDefinitionPtrUse to create an instance of class OptionDefinition.CreateClass
CLS_OptionTypeDefinition/IOptionTypeDefinitionPtrUse to create an instance of class OptionTypeDefinition.CreateClass
CLS_SupportedOption/ISupportedOptionPtrUse to create an instance of class SupportedAction.CreateClass
CLS_SupportedAction/ISupportedActionPtrUse to create an instance of class SupportedAction.CreateClass
CLS_Singleton_PreferencesManager/IPreferencesManagerPtrUse to obtain a pointer to singleton class PreferencesManager.GetSingletonPointer
CLS_Singleton_LibraryManager/ILibraryManagerPtrUse to obtain a pointer to singleton class LibraryManager.GetSingletonPointer
CLS_Singleton_Tuner/ITunerPtrUse to obtain a pointer to singleton class Tuner.GetSingletonPointer

The following sections contains short references for Personalizer classes and methods. It is intended to serve as a simple overview of Personalizer's capabilities. If you need more detailed information on the methods listed here, please use the Doxygen-generated reference included in the Personalizer Development Kit.

1.5. Passing Objects to Personalizer Methods

Since regular Personalizer classes, such as Option and Binding, are instantiated as pointers to interfaces, you should use a suitable casting syntax when passing objects to Personalizer methods. All Personalizer methods receive instances of Personalizer objects by reference. The syntax to use is easier to understand from this example:

	  // create an Option object
	  IOptionPtr setting = static_cast<IOptionPtr>(fCreateClass(CLS_Option));

	  // profileIt is an iterator pointing to a profile
	  // getOption expects a reference to Option
	  profileIt -> getOption((Option&)(*setting), L"MusicVolume");
	

As you can see, the idea is to dereference the pointer to the interface and cast the interface as class reference.

[Note]Note

If you have an idea of a nicer way to do this, and the solution does not involve macros, just send us a message saying so.

1.6. The Flow in General

Almost every game written for PCs follows certain configuration patterns. The implementations of the configuration process may differ (within limits), but the patterns persist.

In particular, the very first thing to do after basic initialization is to load the configuration profile and read in all settings. After that, it may be required to change some of the settings in response to explicit user requests. Finally, the settings must persist across runs of the game, that is, must be saved on disk for subsequent loading.

Depending on the complexity of the game and requirements imposed on those game screens where manual configuration happens, other tasks may be added, such as creating multiple profiles for different users of the game.

Personalizer relieves game developer of the chores related to internals of configuration components, but it still requires some programming to implement the common configuration patterns. Here is the basic procedure that you should follow.

  1. Perform bootstrapping. During bootstrapping, you load the Personalizer DLL into memory (LoadLibrary), obtain pointers to helper functions exported by the DLL, obtain pointer to singleton class Tuner and call method Tuner::bootstrap.

    The inner mechanics of Tuner::bootstrap are fairly complex and unimportant; what concerns you is that this method ultimately identifies and records the profile that contains preferences related to your game.

  2. Extract preferences. Obtain pointer to singleton class PreferencesManager and read settings from the identified profile into memory. You can also modify settings as needed and create additional profiles.

  3. Free the resources. When you are done working with preferences, call Tuner::release to unload preferences from memory and FreeLibrary to unload the Personalizer DLL. This conserves memory. You can call Tuner::bootstrap again as required. Note that Tuner::bootstrap may be a bit slow, but only the very first time your game calls it. Because Personalizer memorizes the profile selected as the source of configuration information for your game, subsequent identification of that profile happens much faster.

The following chapters present Personalizer classes and contain many examples of actual use.

Chapter 2. Bootstrapping

Table of Contents

2.1. Unaware Mode
2.2. Exceptions
2.3. On Strings and Unicode

2.1. Unaware Mode

When you perform system diagnostics by calling the API bootstrap method, API hopes to find the preferences memory files under a predefined location, which is fixed for every operating system. If the preferences memory is broken, the API will try to restore files from a snapshot. If snapshot restoration fails or the preferences memory is simply absent, the API falls back to the so called Unaware Mode.

In Unaware Mode, there is only one virtual profile filled with your game's default settings. You can retrieve the settings and change them, and the virtual profile will be incorporated back into preferences memory as soon as Personalizer redistributeable core is reinstalled. Because Unaware Mode defies the very principles of Personalizer, the game is advised to execute the redistributable core installer as soon as possible; ideally, the very moment the API reports being in Unaware Mode. After the preferences memory is in place, you can reinitialize the API.

2.2. Exceptions

This API tries to be conscious about dumping problems into client code's lap. We throw exceptions only for cases of serious errors that do or may prevent the Framework from operating properly. Most of these exceptions will be raised early on, if ever, on the stage where you initialize the API and obtain basic pointers. During normal workflow there is little need to try/catch things, although it is a recommended approach for any code. However, there is need to track system's reactions to your calls.

2.3. On Strings and Unicode

This API uses Unicode internally for everything except the file and path names. This means you must also use wide strings for all strings that you pass to API methods or receive from API methods.

We called the Unicode strings typedef ClassicString. If this surprises you, think of Classic as Traditional. Before computers, strings could contain any characters at all. Thus, ClassicString.

[Note]Note

Currently, Personalizer API defines a Unicode string as std::basic_string<wchar_t>.

Chapter 3. Personalizer Classes

3.1. Tuner (Singleton)

Class Tuner is responsible for initializing and unitializing the framework. It also incapsulates the game configuration metadata that Personalizer relies upon in its operation.

Before you can do anything useful with Personalizer, you must bootstrap the framework by calling Tuner::bootstrap. After you are done working with preferences, bring the framework down by calling Tuner::release. For more elaborate information about bootstrapping, refer to Chapter 2, Bootstrapping.

By calling Tuner methods such as supportedOptions() and supportedActions(), you can access configuration metadata created in Personalizer Visual Tuner and loaded through a call to Tuner::bootstrap.

Table 3.1. Class Tuner Methods Summary

Method NameDescription
bootstrapInitializes the FingerTips Personalizer Application Programming Interface. Initialization has several stages, from locating the Personalizer files to creating profile containing settings for your game. The in-between gory details should not generally bother you. Just remember that bootstrap can throw an exception indication that no preferences memory exists on the computer or some other critial error has occurred. You can find a good commented example of calling bootstrap in the code fragments generated by Personalizer Visual Tuner when you save the project.
releaseBrings down the framework. You should call this method when your game and/or the user is done working with preferences. release unloads preferences memory. The bootstrap/release pair of methods is reentrant: you can call them repeatedly as many times as required.
getOriginReturns the unique origin line that you (or the person responsible for Personalizer-related configuration metadata) have specified in Personalizer Visual Tuner. This method is not of much use, it is a helper used by other Personalizer classes. It is exposed for completeness of access to configuration metadata.
getGameTitleReturns the game title that you (or the person responsible for Personalizer-related configuration metadata) have specified in Personalizer Visual Tuner.
isModeAwareReturns true if the API has found preferences memory on disk and has loaded it into memory; false otherwise. The Personalizer-unaware mode is when Personalizer fails to find a valid preferences memory, but still creates a profile specific to your game. The profile initially contains default settings and bindings derived from configuration metadata created in Personalizer Visual Tuner. The user can change the settings as usual, but an unaware profile will not become part of preferences memory (and, therefore, will not participate in profile matching) until Personalizer Redistributable Core is reinstalled. We recommend to reinstall the core automatically whenever Personalizer falls into unaware mode. Remember to unload Personalizer DLL first.
supportedActionsReturns a reference to STL map that maps qualified names of supported actions to SupportedAction objects. By iterating over elements of the map, you can access customization metadata for actions created in Personalizer Visual Tuner.
supportedOptionsReturns a reference to STL map that maps qualified names of supported options to SupportedOption objects. By iterating over elements of the map, you can access customization metadata for options created in Personalizer Visual Tuner.
customActionsReturns a reference to STL map that maps names of custom actions to ActionDefinition objects. By iterating over elements of the map, you can access definitions of custom (game-specific) actions created in Personalizer Visual Tuner.
customOptionsReturns a reference to STL map that maps names of custom options to OptionDefinition objects. By iterating over elements of the map, you can access definitions of custom (game-specific) options created in Personalizer Visual Tuner.
customOptionTypesReturns a reference to STL map that maps names of custom option types to OptionTypeDefinition objects. By iterating over elements of the map, you can access definitions of custom option types created in Personalizer Visual Tuner.

The following code snippet demonstrates what you can do with Tuner's methods. The code prints out complete configuration metadata for your game. The possibility to extract configuration metadata is interesting, because, if you feel like, you can write subroutines for your game that would automatically generate setup screens from metadata created in Personalizer Visual Tuner.

Example 3.1. Extracting Configuration Metadata


	  // ... bootstraping skipped ...
	  std::wcout << L"Game title: " << pITuner -> getGameTitle() << std::endl;
	  std::wcout << L"Game origin: " << pITuner -> getOrigin() << std::endl;
	  
	  // obtain references to metadata maps
	  SupportedActions &mySupportedActions = pITuner -> supportedActions();
	  SupportedOptions &mySupportedOptions = pITuner -> supportedOptions();
	  CustomActions &myCustomActions = pITuner -> customActions();
	  CustomOptions &myCustomOptions = pITuner -> customOptions();

	  std::wcout << L"The game has " << myCustomActions.size() << L" custom actions" << std::endl;
	  std::wcout << L"The game has " << myCustomOptions.size() << L" custom options" <<std::endl;
	  std::wcout << L"Total supported game actions: " << mySupportedActions.size() << std::endl;
	  std::wcout << L"Total supported game options: " << mySupportedOptions.size() << std::endl;

	  // dump info about supported options
	  /** At this point, all the supported options must already be in the library, so we are safe in 
	  ** assuming that retrieval of definitions by name will work and work as expected.
	  **/

	  // create an instance of OptionDefinition
	  personalizer::IOptionDefinitionPtr optionDef 
	      = static_cast<IOptionDefinitionPtr>((*fCreateClass())(CLS_OptionDefinition));

	  // for every option the game supports
	  for (SupportedOptions::iterator soIt = mySupportedOptions.begin();
	       soIt != mySupportedOptions.end();
	       ++soIt)
	  {
	    ClassicString optionName = (soIt -> second).getName();

	    pILibraryManager -> getOptionDefinition((OptionDefinition&)(*optionDef), optionName);

	    // print out option name and its custom caption
	    // custom captions are identical to names if undefined
	    std::wcout << std::endl << L"Option " << optionDef -> getName()
	               << " (" << optionDef -> getCustomName() << std::endl;

	    std::wcout <<                L"       is of value type " << optionDef -> getOptionType() << std::endl;

	    if ((soIt -> second).hasDefault())
	      {
	        std::wcout <<            L"       Its default value is: " << (soIt -> second).getDefault() << std::endl;
	      }
	  
	    if ((soIt -> second).getGrade() > 0)
	      {
	        std::wcout <<            L"       Graded as: " << (soIt -> second).getGrade() << std::endl;
	      }
          }
	  // you can do the same for actions
	  // you can also explore custom option types
	  // and even interpret the classes of actions and options

	

3.2. PreferencesManager (Singleton)

After a succussful call to Tuner::bootstrap you can work with preferences memory and libraries. Class PreferencesManager provides high-level methods for managing preferences memory.

You can obtain iterators pointing to configuration profiles, create and remove profiles, save changes in the preferences memory and revert to the on-disk version of the preferences memory.

PreferencesManager also exposes a utility method, unmanglePersonalizerName, that the game must use on names of actions and options before displaying them to the gamer. Personalizer names cannot contain spaces, hence the necessity to preprocess them before display.

Table 3.2. Class PreferencesManager Methods Summary

Method NameDescription
profilesReturns a reference to STL map that maps unique profile identifiers (UIDs) to Profile objects. This map provides direct access to preferences memory and goes under alias PreferencesMemory.
createProfileCreates a new profile from the specified title and returns the new profile's unique identifier. createProfile is the only correct way to create new profiles, don't try to add profiles directly into preferences memory.
removeProfileRemoves a profile from preferences memory by its unique identifier.
getSelectedProfileUIDReturns the unique identifier of the currently selected profile.
getSelectedProfileIteratorReturns an iterator pointing to the currently selected profile. After a successful bootstrap, even in the unaware mode, Personalizer automatically creates and selects a profile that contains settings relevant to your game. You can quickly access that profile by calling getSelectedProfileIterator.
selectProfileLets you change the currently selected profile.
getProfileIteratorReturns a profile iterator for the specified unique profile identifier.
unmanglePersonalizerNameFor any name of a Personalizer library item (action or option), returns its equivalent suitable for presenting onscreen, within the game.
saveCommits changes in preferences memory to disk. Note that you only need to call save when either your game or your gamer changes the preferences memory explicitly. In all other scenarios, Personalizer will commit changes automatically.
revertReloads preferences memory from disk. All unsaved changes are lost.

3.3. LibraryManager (Singleton)

Class LibraryManager is a wrapper around libraries; many of its methods are of interest mainly to other API methods.

However, you can use LibraryManager to access library definitions of actions, options, and option types, as well as perform validation of option values.

Table 3.3. Class LibraryManager Methods Summary

Method NameDescription
actionExistsDetermines whether a definition exists in the library of actions for the specified action name.
optionExistsDetermines whether a definition exists in the library of options for the specified option name.
getActionDefinitionFor the specified name of an action, retrieves the corresponding definition from the library of actions.
getOptionDefinitionFor the specified name of an option, retrieves the corresponding definition from the library of options.
getOptionTypeDefinitionFor the specified name of an option type, retrieves the corresponding definition from the library of option types.
getOptionTypeFor the specified name of an option, retrieves its option type's regular expression.
optionIsValidDetermines whether the specified value is valid for the specified option.

3.4. Profile

Class Profile is a container for options, bindings, and sequences, plus some extra service information. Profile has more methods than any other Personalizer class; however, its methods are divided into related groups that follow roughly the same usage pattern.

In short, to retrieve and modify settings related to your game, you will use Profile's methods.

Note that you never need to create instances of Profile directly using the procedures outlined earlier in this document; instead, call PreferencesManager::createProfile.

Table 3.4. Class Profile Methods Summary

Method NameDescription
General
clearErases the profile's contents: options, bindings, sequences, tags, everything. Only the unique profile identifier is left intact. For example, if you need to reset your game's profile to developer defaults (instead of reusing existing preferences), which you may need because of a gamer's request, perform clear first, then perform sequential retrieval and storing of options and bindings your game supports. See ... for an example.
getUIDReturns the profile unique identifier.
getTitleReturns the profile title.
setTitleSets the profile title.
Options
countOptionsReturns the number of options set in the profile.
getOptionRetrieves an option by either its 1-based serial number or by its name.
setOptionCreates or modifies an existing option.
unsetOptionRemoves the specified option from the profile in question.
Bindings
countBindingsReturns the number of bindings set in the profile.
getBindingRetrieves a binding by either its 1-based serial number or by the action name.
putBindingputBinding has two overloaded variants. The first one overwrites existing bindings at specific 1-based serial numbers. The second, for a given binding, overwrites the binding for that action if one exists or simply adds the binding into the profile in question.
unbindActionFrom the profile in question, removes the binding for the specified action.
Sequences
countSequencesReturns the number of sequences in this profile.
getSequenceRetrieves a sequence by its 1-based serial number. If you sequentially retrieve all sequences by serial numbers, getSequence first returns the sequences from the profile you are working with, then inherited sequences in the order determined by profile search chains. See FingerTips Personalizer, Framework Design for more information on profile search chains.
createSequenceCreates a new sequence and returns its serial number.
updateSequenceReplaces the existing sequence (identified by 1-based its serial number) with the provided one.
eraseSequenceErases a sequence identified by the 1-based serial number.
Preferences Tagging
readTagReturns the value associated with the specified tag name from either Core Origin or the game's origin. For a detailed discussion of preferences tagging, see Chapter 4, Preferences Tagging.
writeTagSets of modifies the value associated with the specified tag name in either Core Origin or the game's origin. For a detailed discussion of preferences tagging, see Chapter 4, Preferences Tagging.
clearTagRemoves the tag/value pair for the specified tag name in either Core Origin or the game's origin. For a detailed discussion of preferences tagging, see Chapter 4, Preferences Tagging.

3.5. Option

Class Option contains information related to a single option setting. You will need Option objects to retrieve options defined in profiles, to define new options, and also to modify existing option definitions.

One option definition may contain several values in the order of decreasing preference. You can obtain an option's value as a whole or you can retrieve distinct preference values and optionally perform on-the-fly conversion to a more convenient data type.

Table 3.5. Class Option Methods Summary

Method NameDescription
clearErases contents of the Option object.
getOptionNameReturns the option name.
getHolisticValueReturns the holistic option value. Holistic option value is the whole value of the option that may consist of either one value or multiple preference values.
getPrimaryValueReturns the first value from a multivalue list or simply the option value as a string. E.g., if the option's internal value is "100", getPrimaryValue returns "100", and if the option's internal value is "English Russian Spanish", getPrimaryValue returns "English".
getPrimaryValueAsBooleanSame as getPrimaryValue, but assumes that the option has type Truth and tries to convert the primary value into boolean. Throws an exception if conversion fails.
getPrimaryValueAsIntSame as getPrimaryValue, but assumes that the option is of an integral type such as Percentage and tries to convert the primary value into long. Throws an exception if conversion fails.
getPrimaryValueAsDoubleSame as getPrimaryValue, but assumes that the option is of a floating point type such as Precision and tries to convert the primary value into double. Throws an exception if conversion fails.
setInitializes the Option object with a name/value pair where name is taken as a name of an existing option, and the value must be valid for that option. For an invalid name/value combination will throw an exception.
getEnclosingProfileUIDWhen retrieving an option from a profile, getOption marks the option as belonging to a certain profile by assigning the enclosing profile identifier. You can call getEnclosingProfileUID to obtain that identifier.
Preferences Tagging
readTagReturns the value associated with the specified tag name from either Core Origin or the game's origin. For a detailed discussion of preferences tagging, see Chapter 4, Preferences Tagging.
writeTagSets of modifies the value associated with the specified tag name in either Core Origin or the game's origin. For a detailed discussion of preferences tagging, see Chapter 4, Preferences Tagging.
clearTagRemoves the tag/value pair for the specified tag name in either Core Origin or the game's origin. For a detailed discussion of preferences tagging, see Chapter 4, Preferences Tagging.

3.6. Binding

Class Binding contains information related to a single binding. You will need Binding objects to retrieve bindings defined in profiles, to define new bindings, and also to modify existing binding definitions.

Table 3.6. Class Binding Methods Summary

Method NameDescription
clearErases contents of the Binding object.
getActionNameReturns the action name.
setActionNameSets the action name for the binding.
bindAssociates a single control with the action specified in the previous call to setActionName.
unbindUnbinds all controls.
countControlsReturns the number of controls associated with the action.
getControlRetrieves an associated control by its serial number.
getEnclosingProfileUIDWhen retrieving a binding from a profile, getBinding marks the binding as belonging to a certain profile by assigning the enclosing profile identifier. You can call getEnclosingProfileUID to obtain that identifier.
Preferences Tagging
readTagReturns the value associated with the specified tag name from either Core Origin or the game's origin. For a detailed discussion of preferences tagging, see Chapter 4, Preferences Tagging.
writeTagSets of modifies the value associated with the specified tag name in either Core Origin or the game's origin. For a detailed discussion of preferences tagging, see Chapter 4, Preferences Tagging.
clearTagRemoves the tag/value pair for the specified tag name in either Core Origin or the game's origin. For a detailed discussion of preferences tagging, see Chapter 4, Preferences Tagging.

3.7. Control

Class Control reflects a single control as defined in FingerTips Personalizer, Framework Design. Control is used with Binding and Sequence.

Table 3.7. Class Control Methods Summary

Method NameDescription
initializeInitializes the option from a vector of key mnemonics. For a complete list of available key mnemonics, see ...
setSets a component by its mnemonic. For example, if you need to add the Space key to a control, call Control::set(SPACE). For a complete list of available key mnemonics, see ...
unsetUnsets a component by its mnemonic. For example, if you need to unset Left Alt key, call Control::unset(LEFT_ALT). For a complete list of available key mnemonics, see ...
clearClears the control.
toStringReturns the string representation of the control. By default, control components are separated with string " + ". You can change the separator by passing an alternative separator string to this method.
Preferences Tagging
readTagReturns the value associated with the specified tag name from either Core Origin or the game's origin. For a detailed discussion of preferences tagging, see Chapter 4, Preferences Tagging.
writeTagSets of modifies the value associated with the specified tag name in either Core Origin or the game's origin. For a detailed discussion of preferences tagging, see Chapter 4, Preferences Tagging.
clearTagRemoves the tag/value pair for the specified tag name in either Core Origin or the game's origin. For a detailed discussion of preferences tagging, see Chapter 4, Preferences Tagging.

3.8. Sequence

Class Sequence stores a single sequence: associated controls, sequence elements, and preferences metadata.

Table 3.8. Class Sequence Methods Summary

Method NameDescription
clearClears the contents of the sequence.
getTitleReturns the optional sequence title.
setTitleSets the optional sequence title.
countControlsReturns the number of controls associated with the sequence.
getControlRetrieves an associated control by its serial number.
bindAssociates a single control with the sequence.
unbindUnbinds all controls.
countElementsReturns the number of elements in the sequence.
getElementRetrieves a sequence element by its 1-based serial number.
eraseElementErases a sequence element identified by the serial number.
insertElementInserts or appends an element to the sequence.
getEnclosingProfileUIDWhen retrieving a sequence from a profile, getBinding marks the sequence as belonging to a certain profile by assigning the enclosing profile identifier. You can call getEnclosingProfileUID to obtain that identifier.
Preferences Tagging
readTagReturns the value associated with the specified tag name from either Core Origin or the game's origin. For a detailed discussion of preferences tagging, see Chapter 4, Preferences Tagging.
writeTagSets of modifies the value associated with the specified tag name in either Core Origin or the game's origin. For a detailed discussion of preferences tagging, see Chapter 4, Preferences Tagging.
clearTagRemoves the tag/value pair for the specified tag name in either Core Origin or the game's origin. For a detailed discussion of preferences tagging, see Chapter 4, Preferences Tagging.

3.9. SequenceElement

SequenceElement is a hybrid class. Instances of SequenceElement act as either action calls or option settings, depending on context. Sequence elements are used to construct sequences and to retrieve sequences data.

Table 3.9. Class SequenceElement Methods Summary

Method NameDescription
getTypeDetermines the type of an sequence element: SEQUENCE_ELEMENT_OPTION, SEQUENCE_ELEMENT_CALL, or SEQUENCE_ELEMENT_UNDEFINED.
getOptionFor a SequenceElement object representing an option setting, returns both option name and the holistic option value.
getCallFor a SequenceElement representing an action call, returns action name, call flow type, and duration.
setToOptionInitializes the sequence element as an option.
setToCallInitializes the sequence element as an action call.
Preferences Tagging
readTagReturns the value associated with the specified tag name from either Core Origin or the game's origin. For a detailed discussion of preferences tagging, see Chapter 4, Preferences Tagging.
writeTagSets of modifies the value associated with the specified tag name in either Core Origin or the game's origin. For a detailed discussion of preferences tagging, see Chapter 4, Preferences Tagging.
clearTagRemoves the tag/value pair for the specified tag name in either Core Origin or the game's origin. For a detailed discussion of preferences tagging, see Chapter 4, Preferences Tagging.

3.10. SupportedOption

Class SupportedOption incapsulates configuration metadata for a single option that your game supports. You can access the map of supported options by calling Tuner::supportedOptions() (see Example 3.1.)

Table 3.10. Class SupportedOption Methods Summary

Method NameDescription
getNameReturns the name of the supported option.
getCustomNameReturns the custom name of the supported option if one has been specified in Personalizer Visual Tuner.
getCustomDescriptionReturns the custom description of the supported option if one has been specified in Personalizer Visual Tuner.
hasDefaultDetermines whether a default value has been specified for this option.
getDefaultReturns the default value as string.
isAcceptableValuePersonalizer Visual Tuner lets the user list a number of concrete valid values for an option. If such a list exists, unlisted values will be automatically filtered out when you retrieve options from profiles (by option names.) isAcceptableValue determines whether the value passed in the argument is acceptable.
getGradeReturns the grade if one has been defined for the option in Personalizer Visual Tuner. Returns 0 if no grade has been defined.

3.11. SupportedAction

Class SupportedAction incapsulates configuration metadata for a single action that your game supports. You can access the map of supported actions by calling Tuner::supportedActions() (see Example 3.1.)

Table 3.11. Class SupportedAction Methods Summary

Method NameDescription
getNameReturns the name of the supported action.
getCustomNameReturns the custom name of the supported action if one has been specified in Personalizer Visual Tuner.
getCustomDescriptionReturns the custom description of the supported action if one has been specified in Personalizer Visual Tuner.
countDefaultControlsReturns the number of default controls associated with the action.
getDefaultControlReturns a default Control by its index. The first control has index 1.

3.12. ActionDefinition

Class ActionDefinition incapsulates definition of a library action. Instances of ActionDefinition are used with LibraryManager to retrieve action definitions from the library of actions.

Table 3.12. Class ActionDefinition Methods Summary

Method NameDescription
getOriginReturns the origin the action comes from.
getNameReturns the name of the action, such as Attack. Note that the name must be unmangled if you intend to display it. Call PreferencesManager::unmanglePersonalizerName to unmangle a name.
getCustomNameReturns the custom name of the action which is an alternative caption that you can specify in Personalizer Visual Tuner. If you use configuration metadata to create setup screens and also pull game-specific captions over core Personalizer actions, use this method to obtain the alternative captions.
getDescriptionReturns the description text associated with the option.
getCustomDescriptionReturns the alternative description text associated with the action. This works similarly to custom name.
getActionClassReturns the class of the action.

3.13. OptionDefinition

Class OptionDefinition incapsulates definition of a library option. Instances of OptionDefinition are used with LibraryManager to retrieve option definitions from the library of option types.

Table 3.13. Class OptionDefinition Methods Summary

Method NameDescription
getOriginReturns the origin the option comes from.
getNameReturns the name of the option, such as MusicVolume. Note that the name must be unmangled if you intend to display it. Call PreferencesManager::unmanglePersonalizerName to unmangle a name.
getCustomNameReturns the custom name of the option which is an alternative caption that you can specify in Personalizer Visual Tuner. If you use configuration metadata to create setup screens and also pull game-specific captions over core Personalizer options, use this method to obtain the alternative captions.
getDescriptionReturns the description text associated with the option.
getCustomDescriptionReturns the alternative description text associated with the option. This works similarly to custom name.
getOptionTypeReturns the value type identifier for the option, such as Truth.
getOptionClassReturns the class of the option.

3.14. OptionTypeDefinition

Class OptionTypeDefinition incapsulates definition of a library option type. Instances of OptionTypeDefinition are used with LibraryManager to retrieve option type definitions from the library of option types.

Table 3.14. Class OptionTypeDefinition Methods Summary

Method NameDescription
getOriginReturns the origin the type comes from.
getNameReturns the name of the type, such as Percentage.
getDescriptionReturns the description text associated with the type.
getPatternReturns the regular expression that defines values valid for the type.
multivalueDetermines whether values of the type can contain multiple preferences in the order of decreasing preference.

Chapter 4. Preferences Tagging

Preferences memory structures - profiles, options, bindings, controls, sequences, and sequence elements - can carry arbitrary attributes in addition to their standard properties. These attributes are called tags and the process of using tags is called preferences tagging.

Tags are always origin-qualified; every tag belongs to either Core Origin or your game's origin. This allows to distinguish game-specific tags from tags that apply to all games. For instance, there is a standard tag Type that is intended for use with bindings. Type specifies execution model for in-game actions, its possible values are Single, Toggle, and Continuous. This tag is optional, but it can be used in profile matching, and the profile matching routines will request this tag from the core origin. On the other hand, a tag that you devise - such as the examplary tag Player which marks options and bindings as related to either player one or player two - must be requested from your game's origin.

You can attach tags to Personalizer structures, remove tags, and read value of existing tags. You can access both tags from your game's origin and tags from the core origin.

Classes Profile, Option, Binding, Control, Sequence, and SequenceElement all expose the same interface for preferences tagging. The three methods are: clearTag, readTag, and writeTag.

All three methods take origin indication as the last argument, and that argument is optional. By default, the methods work with tags specific to your game. If you need to work with standard tags from the core origin, specify TT_CORE as the last argument.

Example 4.1. Preferences Tagging

	
	// ... bootstrap skipped ...
	// obtain an iterator to the selected profile (unique profile identifier serves as the key, and
	// the corresponding Profile object is the value)
	PreferencesMemory::iterator selectedProfile = pIPreferencesManager -> getSelectedProfileIterator();
	
	// get the number of bindings in this profile
	unsigned long countBindings = (selectedProfile -> second).countBindings();

	// create a Binding object
	personalizer::IBindingPtr binding 
	    = static_cast&lt;personalizer::IBindingPtr&gt;((*fCreateClass())(CLS_Binding));

	// create a Control object
	personalizer::IControlPtr ctrl
	    = static_cast&lt;personalizer::IControlPtr&gt;((*fCreateClass())(CLS_Control));
	
	for (unsigned long b = 1; b <= countBindings; b++)
	{
	   (selectedProfile -> second).getBinding((Binding&)*binding, b);

	   // check whether our custom tag is present on bindings
	   // and set the tag if absent
	   if (binding -> readTag(L"CoolTimestamp") == Const::EMPTY_STRING)
	     {
	        binding -> writeTag(L"CoolTimestamp", L"JustUpdated");
	     }

	   // retrieve action type flag from controls
   	   // 
           unsigned long countControls = binding -> countControls();

	   for (unsigned long c = 1; c <= countControls; c++)
	   {
	      binding -> getControl((Control&)*ctrl, c);

	      // actionExecutionMode will hold an empy string, if absent, 
	      // or one of the action types: "Single", "Toggle", or "Continuous"
	      // NOTE the use of TT_CORE to access standard, non-game-specific, tags
	      ClassicString actionExecutionMode = ctrl -> readTag(L"Type", TT_CORE);

              // ... perform further actions based on the value of 
	      // ... actionExecutionMode
	   }

	   // removal example
	   binding -> writeTag(L"TagForRemoval", L"RemoveMe");
	   binding -> clearTag(L"TagForRemoval");

           // store the binding back to profile
	   (selectedProfile -> second).putBinding((Binding&)*binding, b);
	}
	
      

Some ideas for applying tags. 

  • When you have several similar in-game actions that only differ in one simple aspect, use tags to record that aspect in bindings. For example, instead of creating custom actions Select Hero #1, Select Hero #2, and so on to Select Hero #9, create one action Select Hero, bind nine controls to Select Hero and set a tag like "Number" on these controls to values from 1 to 9. Right now Personalizer Visual Tuner has no global support for tags, so you will have to create these bindings programmatically instead of Personalizer creating the defaults for you.

  • You can use tags to mark profiles created by your game. By setting a tag such as "CreatedBy" to any value on all profiles created by your game, you can support profile switching in the user interface.

FingerTips Personalizer Framework (Personalizer Home)