Using Progress Functions

Sometimes making HOOPS perform a task won’t give an immediate result. And insofar as the API is not concurrent, performing any time consuming operation will block your application until it’s finished. This is the case when loading files or processing CAD models where the operation may take a little while.

To give you feedback on the evolution of such operations, you can provide the API with a set of callback functions which are automatically called to update you about the progress of a long running task.

Setting Up the Callbacks

To define the callback functions, call A3DDllSetCallbacksProgress(). It accepts 5 functions and a pointer to a control flag that can be used to stop the process:

A3DVoid on_start(A3DInt32 in_iCode);
A3DVoid on_size(A3DInt32 in_iMax);
A3DVoid on_increment(A3DInt32 in_iValue);
A3DVoid on_end();
A3DVoid on_title(A3DUTF8Char* in_pcTitle);

A3DInt32 stop_process = 0;

A3DDllSetCallbacksProgress(on_start, on_size, on_increment, on_end, on_title, &stop_process);

All functions must be set.

Progress Start and End

When the API starts a new progress, on_start is called. This function receives an indicator of the type of the performed operation:

  • 0: Undefined

  • 1: File Read

  • 2: File Write

  • 3: Any operation done after reading

Warning

The current version of HOOPS API does not provide an exhaustive set of identifiers. For a more precise description of the task being performed, please see the description of the on_title callback below.

A3DVoid on_start(A3DInt32 in_iCode)
{
  switch(in_iCode)
  {
    case 1:
      printf("File reading...\n");
      break;
    // ...
    default:
      break;
  }
}

All incoming calls to your callback functions address the same progress until on_end is called by the API:

A3DVoid on_end()
{
  printf("Done.\n");
}

Getting a Description of the Executing Task

Right after the progress starts, on_title is called and is given a descriptive string of the performing task. If the current progress is the loading of a CAD file, the value contains the name of the file.

A3DVoid on_title(A3DUTF8Char* in_pcTitle)
{
  printf("In Progress: %s\n", in_pcTitle);
}

Please note that the lifetime of in_pcTitle is clamped to the call of this function.

Being Notified About the Progress

The progress of the task is expressed using a range of integer values where the maximum is passed to on_size.

A3DInt32 max = 0;

A3DVoid on_size(A3DInt32 in_iMax)
{
  max = in_iMax;
}

Warning

Please note that there is no direct relation between this value and a potential time estimation for the performed task. The value given for in_iMax in set internally and shouldn’t be interpreted to any specific meaning.

Then each time HOOPS notifies about its progress, it calls on_increment which is given a value between 0 and max:

A3DVoid on_increment(A3DInt32 in_iValue)
{
  const A3DInt32 p = (100 * in_iValue) / max;
  printf("Current Progress: %d%%\n", p);
}

Stopping the Progress

Some operations may be canceled while running. To do so, simply change the value given to A3DDllSetCallbacksProgress() to any non-zero integer.

Warning

Because the value passed to A3DDllSetCallbacksProgress is a pointer to a local variable, please be cautious with the lifetime of the actual variable.

Full Example

This complete example can be used to display any progress in the standard output.

Some elements of this code snippets are worth some precisions:

  • Because there is no order guarantee in the function calls, on_increment shouldn’t assume that max is non-zero. To avoid a zero-division, we display only the title of the progress in that case.

  • For the same reason, title may not be set when on_increment is called. This is why is it initialized first to a default value.

struct {
  char        title[1024];
  A3DInt32    max;
  A3DInt32    stop;
} progress;

A3DVoid on_start(A3DInt32)
{
  printf("Starting process...\n");
}

A3DVoid on_end()
{
  printf("Done.\n");
}

A3DVoid on_size(A3DInt32 in_iMax)
{
  progress.max = in_iMax;
}

A3DVoid on_increment(A3DInt32 in_iValue)
{
  if(progress.max == 0)
  {
    printf("%s...\n", progress.title);
  }
  else
  {
    const A3DInt32 p = (100 * in_iValue) / progress.max;
    printf("%s: %d%%\n", process.title, p);
  }
}

A3DVoid on_title(A3DUTF8Char* in_pcTitle)
{
  strcpy(progress.title, in_pcTitle);
}

int main(int argc, char* argv[])
{
  // Initializing HOOPS API

  strcpy(progress.title, "Unknown");
  progress.max = 0;
  progress.stop = 0;
  A3DDllSetCallbacksProgress(on_start, on_size, on_increment, on_end, on_title, &progress.stop);

  // Using HOOPS API

  return EXIT_SUCCESS;
}