Jump to content

Programming Reference:Environment Class

From BCI2000 Wiki
Revision as of 18:01, 27 February 2007 by Mellinger (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Your code's Environment

In each BCI2000 module, there exist system wide parameters and states as described in the project outline document. In this implementation, access to parameters and states is mediated through a class Environment. This class provides functions for convenient access to parameters and states, and transparently handles a number of error conditions that might occur. The services provided by the Environment class interface are available to all classes that inherit from it. For GenericFilter descendants, this is automatically the case; for other classes, you need to explicitly state the inheritance as in

#include "UEnvironment.h"
...
MyClass : private Environment

  ...
};

Access to Parameters and States

From any code inside MyClass, you may then read or set parameter and state values simply by writing

int numberOfItems = Parameter( "NumberOfItems" );
float listValue = Parameter( "ListParam" )( index );
float matrixValue = Parameter( "MatrixParam" )( index1, index2 );
float nestedMatrixValue
  = Parameter( "NestedMatrices" )( index1, index2 )( index3, index4 );
short feedbackState = State( "Feedback" );
State( "Feedback" ) = 0;

If you try accessing a parameter or state that does not exist, an appropriate error message will be sent to bcierr, so you don't need to handle this type of error explicitly. For a greater independence between modules, it is sometimes desirable to read a parameter or state if it exists, and use a default value otherwise. You achieve this behavior by writing

int numberOfItems = OptionalParameter( defaultValue, "NumberOfItems"
);
short itiState = OptionalState( 0, "IntertrialInterval" );

Working around Borland VCL Inheritance Restrictions

Due to some non-standard conventions in Borland's VCL library, you cannot create a VCL class such as a TForm descendant that also inherits from Environment -- the compiler will report an error if you try. As a work-around, you might declare an Environment subclass inside your VCL TForm child declaration, and create a single instance mEnv of this subclass as a member of your class, using it to access the Environment functions as in

MyForm : public TForm

  ...
  private:
    class MyFormEnvironment : private Environment
    {
      public:
        MyFormEnvironment( MyForm& parent );
        void Preflight() const;
        void Initialize();
    } mEnv;
};

...

MyForm::MyFormEnvironment( MyForm& parent )
: mParent( parent )

  BEGIN_PARAMETER_DEFINITIONS
    "UsrTask int MyParam= 1 1 0 5 // my parameter",
  END_PARAMETER_DEFINITIONS


...

void
MyForm::Initialize()

  mEnv.Initialize();


void
MyForm::MyFormEnvironment::Initialize()

  mParent.mMyParam = Parameter( "MyParam" );

This should work in situations where your code's class model is centered around VCL form classes. When writing new code, you might consider basing your class model on functionality, and use VCL forms merely for input and output -- instantiating, populating, and deleting them as you need them, such that the BCI2000 Environment interfacing is done from your own classes, independently of the VCL's special requirements.


See also: Error Handling