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$