company logo

C++ Context Class factory

When implementing a C++ context class factory, 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 . Otherwise it has to be implemented explicitly.

One might mix C++ context classes with OSI context classes, but not with C# context classes, i.e. one has to decide whether the interface is implemented in C++/OSI or C#/OSI. One might also mix C++ and OSI context functions in one context class. In this case, the context class should be defined as C++ context class.

// 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$