company logo

C++ Context Class factory

In order to connect C++ context classes to the corresponding database resources, a context class factory has to be provided ( CreateContext() ). The factory must return a context class instance for each valid resource reference number (see examples below). When using ODE, the context class factory is generated by the ClassEditor or Designer . Otherwise it has to be implemented explicitly.

The CreateContext() function must an entry point in a dynamic library. Usually, separate libraries are provided for database context classes and GUI context classes. The name of context class library (except platform specific extensions) has to be defined in the resource database (database context library) and /or in the application's configuration or ini-file (option variables CTXI_DLL for database context library and PROJECT_DLL for GUI context library).

// Simple user-defined ContextClass factory

void *__cdecl CreateContext (int32 resid )

{

  void        *ctx_void = 0;

  switch ( resid ) {

    case 602630 : ctx_void = new cStdWizard();         break;

    case 603810 : ctx_void = new cStdOutputArea();     break;

    case 603811 : ctx_void = new cStdProjectTree();    break;

    // ...

    // more ltable entries

    // ...

    default     :

  }

}

// ContextClass factory generated by ClassEditor

void *__cdecl CreateContext (int32 resid )

{

  using namespace odabagui;

  typedef         int32 (* context_create_pointer)(BaseContext **);

  typedef         std::map<int32,context_create_pointer>  FunctionTable;

  static          FunctionTable   function_table;

  static          bool            initialized     = false;

  BaseContext                    *ctx_void        = NULL;

  if ( !initialized ) {

    function_table.insert(FunctionTable::value_type(602630,cStdWizard::Create));

    function_table.insert(FunctionTable::value_type(603810,cStdOutputArea::Create));

    function_table.insert(FunctionTable::value_type(603811,cStdProjectTree::Create));

    // ...

    // more ltable entries

    // ...

    initialized = true;

  }

  Application::resetApplicationError();

  FunctionTable::iterator it = function_table.find(resid);

  if ( it != function_table.end() )

    (*it->second)(&ctx_void);

  Application::resetApplicationError();

  return(ctx_void);

}

Generating Context Class factory for C++

In order to define proper context class factories, the development database should be checked for resource references associated with a context class. This could be done writing a simple OSI function. A better way is, however, generating context classes

directly from database definitions by defining a template that collects the resource references ( SDB_ResourceRef ), which are associated with a context class. Since relevant information is stored in the resource reference object, the template just needs to select resource references having a context class associated, in order to create a proper CreateContext() function. This is more or less, what the ClassEditor is doing just using another template and a bit more sophisticated class selection in order to support several context classes in different projects.

$template CreateCCFactory()$

void *__cdecl CreateContext (int32 resid )

{

  void        *ctx_void = 0;

  switch ( resid ) {

$SDB_ResourceRef()->CreateCCLine()$

    default     : ;

  }

}

$end$

$template SDB_ResourceRef::CreateCCLine()$

$while next$\

$if context_class.count > 0$\

    case $__AUTOIDENT$ : ctx_void = new $context_class.get(0).sys_ident$();         break;

$end$\

$end$\

$end$