3.3. Inserting Implementations into Bocca-Generated Components

So far, with very little work, we have generated what appears to be an application but is really just the componentized shell of an application. In order to cause it to do something useful we have to add the implementation. There are two places that we have to change things to make that happen: add methods to the interface definition, or .sidl file and then put the implementation code into the components in the language chosen in Section 3.1, “ Creating a Bocca Project ”. The .sidl files are located in the directory ./myProject/ports/sidl and the implementations for the components will be found in the directories ./myProject/components/myProject.Driver, ./myProject/components/myProject.Integrator, and ./myProject/components/myProject.Function.

3.3.1.  Adding Methods to Ports

First modify the sidl files to create the gov.cca.Port's that are needed to import/export functionality from/to the components, look at the file myProject/ports/sidl/myProject.IntegratorPort.sidl.




// DO-NOT-DELETE bocca.splicer.begin(myProject.comment)
// Insert-code-here {myProject.comment} (Insert your package comments here)

// DO-NOT-DELETE bocca.splicer.end(myProject.comment)
package myProject version 0.0 {

    // DO-NOT-DELETE bocca.splicer.begin(myProject.IntegratorPort.comment)
    // Insert-code-here {myProject.IntegratorPort.comment} (Insert your port comments here)

    // DO-NOT-DELETE bocca.splicer.end(myProject.IntegratorPort.comment)
    interface IntegratorPort extends gov.cca.Port
    {
        // DO-NOT-DELETE bocca.splicer.begin(myProject.IntegratorPort.methods)
        // Insert-code-here {myProject.IntegratorPort.methods} (Insert your port methods here)

        // DO-NOT-DELETE bocca.splicer.end(myProject.IntegratorPort.methods)
    };
}


Edit ports/sidl/myProject.IntegratorPort.sidl to insert the integrate:



// DO-NOT-DELETE bocca.splicer.begin(myProject.comment)
// Insert-code-here {myProject.comment} (Insert your package comments here)

// DO-NOT-DELETE bocca.splicer.end(myProject.comment)
package myProject version 0.0 {

    // DO-NOT-DELETE bocca.splicer.begin(myProject.IntegratorPort.comment)
    // Insert-code-here {myProject.IntegratorPort.comment} (Insert your port comments here)

    // DO-NOT-DELETE bocca.splicer.end(myProject.IntegratorPort.comment)
    interface IntegratorPort extends gov.cca.Port
    {
        // DO-NOT-DELETE bocca.splicer.begin(myProject.IntegratorPort.methods)
        // Insert-code-here {myProject.IntegratorPort.methods} (Insert your port methods here)


    double integrate(in double lowBound, in double upBound, in int count);


        // DO-NOT-DELETE bocca.splicer.end(myProject.IntegratorPort.methods)
    };
}


Again edit the file myProject/ports/sidl/myProject.FunctionPort.sidl:



// DO-NOT-DELETE bocca.splicer.begin(myProject.comment)
// Insert-code-here {myProject.comment} (Insert your package comments here)

// DO-NOT-DELETE bocca.splicer.end(myProject.comment)
package myProject version 0.0 {

    // DO-NOT-DELETE bocca.splicer.begin(myProject.FunctionPort.comment)
    // Insert-code-here {myProject.FunctionPort.comment} (Insert your port comments here)

    // DO-NOT-DELETE bocca.splicer.end(myProject.FunctionPort.comment)
    interface FunctionPort extends gov.cca.Port
    {
        // DO-NOT-DELETE bocca.splicer.begin(myProject.FunctionPort.methods)
        // Insert-code-here {myProject.FunctionPort.methods} (Insert your port methods here)

        // DO-NOT-DELETE bocca.splicer.end(myProject.FunctionPort.methods)
    };
}


to add two methods init and evaluate so that the file looks like this:


// DO-NOT-DELETE bocca.splicer.begin(myProject.comment)
// Insert-code-here {myProject.comment} (Insert your package comments here)

// DO-NOT-DELETE bocca.splicer.end(myProject.comment)
package myProject version 0.0 {

    // DO-NOT-DELETE bocca.splicer.begin(myProject.FunctionPort.comment)
    // Insert-code-here {myProject.FunctionPort.comment} (Insert your port comments here)

    // DO-NOT-DELETE bocca.splicer.end(myProject.FunctionPort.comment)
    interface FunctionPort extends gov.cca.Port
    {
        // DO-NOT-DELETE bocca.splicer.begin(myProject.FunctionPort.methods)
        // Insert-code-here {myProject.FunctionPort.methods} (Insert your port methods here)

    void   init(in array<double,1> params);
    double evaluate(in double x);

        // DO-NOT-DELETE bocca.splicer.end(myProject.FunctionPort.methods)
    };
}

What we have done is place methods into the SIDL files in a language-independant way. When you type:


configure;make


                        .
                        .
                        .

the methods will be placed into your already generated components in the language you chose when you created the project in Section 3.1, “ Creating a Bocca Project ”. At this point we are ready to insert the implementation into the components. You will now want to jump to the particular language implementation you chose in Section 3.1, “ Creating a Bocca Project ”. There is a section below for each language chaice available in Bocca. While it is hardly remarkable that we have to resort to a specific programming language to create a component implementation, it is rather surprising that we have acheived all of the foregoing without it.

3.3.2.  Language Specific Implementations of the Function, Integrator and Driver Components

3.3.2.1.  C++ Implementation

You created the project with bocca create project myProject --language=cxx

Look at the file: myProject/components/myProject.Function/myProject_Function_Impl.cxx that Bocca has generated for you. Parse down the file until you find the evaluate_Impl method generated from the SIDL definition of FunctionPort:


/**
 * Method:  evaluate[]
 */
double
myProject::Function_impl::evaluate_impl (
  /* in */double x ) 
{
  // DO-NOT-DELETE splicer.begin(myProject.Function.evaluate)
  // Insert-Code-Here {myProject.Function.evaluate} (evaluate method)
    
    // DO-DELETE-WHEN-IMPLEMENTING exception.begin()
    /*
     * This method has not been implemented
     */
    ::sidl::NotImplementedException ex = ::sidl::NotImplementedException::_create();
    ex.setNote("This method has not been implemented");
    ex.add(__FILE__, __LINE__, "evaluate");
    throw ex;
    // DO-DELETE-WHEN-IMPLEMENTING exception.end()
    
  // DO-NOT-DELETE splicer.end(myProject.Function.evaluate)
}

As the comment suggests this method is "not implemented" but some code has been inserted by Babel to make sure an exception is thrown to inform the user if this is called by mistake. Remove this boilerplate so and substitute an implementation for the PiFunction (i.e. the integral from 0 to 1 of 4/(1 + x2) is π).



/**
 * Method:  evaluate[]
 */
double
myProject::Function_impl::evaluate_impl (
  /* in */double x ) 
{
  // DO-NOT-DELETE splicer.begin(myProject.Function.evaluate)
  // Insert-Code-Here {myProject.Function.evaluate} (evaluate method)

  return 4.0 / (1.0 + x * x);

  // DO-NOT-DELETE splicer.end(myProject.Function.evaluate)
}


Now in the same file find the second method for FunctionPort: init:


/**
 * Method:  init[]
 */
void
myProject::Function_impl::init_impl (
  /* in array<double> */::sidl::array<double< params ) 
{
  // DO-NOT-DELETE splicer.begin(myProject.Function.init)
  // Insert-Code-Here {myProject.Function.init} (init method)

  // Do nothing.
    
  // DO-NOT-DELETE splicer.end(myProject.Function.init)
}

Here we don't have any initialization so we just eliminate the code that throws the exception for running the method.

Similarly look at the Integrator in myProject/components/myProject.Integrator/myProject_Integrator_Impl.cxx:



/**
 * Method:  integrate[]
 */
double
myProject::Integrator_impl::integrate_impl (
  /* in */double lowBound,
  /* in */double upBound,
  /* in */int32_t count ) 
{
  // DO-NOT-DELETE splicer.begin(myProject.Integrator.integrate)
  // Insert-Code-Here {myProject.Integrator.integrate} (integrate method)
  // 
  // This method has not been implemented
  // 
    ::sidl::NotImplementedException ex = ::sidl::NotImplementedException::_create();
    ex.setNote("This method has not been implemented");
    ex.add(__FILE__, __LINE__, "integrate");
    throw ex;
  // DO-NOT-DELETE splicer.end(myProject.Integrator.integrate)
}


Again remove this boilerplate code and insert an implementation that uses the FunctionPort and a Trapezoid method for integration:



/**
 * Method:  integrate[]
 */
double
myProject::Integrator_impl::integrate_impl (
  /* in */double lowBound,
  /* in */double upBound,
  /* in */int32_t count ) 
{
  // DO-NOT-DELETE splicer.begin(myProject.Integrator.integrate)
  // Insert-Code-Here {myProject.Integrator.integrate} (integrate method)

   function::FunctionPort  myFunPort;
   gov::cca::Port          generalPort;
   
   generalPort = frameworkServices.getPort("FunctionPort");
   if (generalPort._is_nil()){
       fprintf(stderr, "Error:: %s:%d: generalPort is nil - \
             maybe I'm not connected to any port!!\n",
             __FILE__, __LINE__);
       exit(1);  
    }
     
    myFunPort = ::babel_cast< function::FunctionPort >(generalPort);
    if (myFunPort._is_nil()){
       fprintf(stderr, "Error:: %s:%d: myFunPort is nil - \
             maybe I'm connected to the wrong \"Provides\" port!!\n",
             __FILE__, __LINE__);
       exit(1);  
    }
    
    double h = (upBound - lowBound) / count;
    double retval = 0.0;
    double sum = 0.0;
    for (int i = 1; i <= count; i++){
       sum += myFunPort.evaluate(lowBound + (i - 1) * h) +
              myFunPort.evaluate(lowBound + i * h);
    }
    retval = h/2.0 * sum;
    frameworkServices.releasePort("FunctionPort");
    return retval;

  // DO-NOT-DELETE splicer.end(myProject.Integrator.integrate)
}


Finally for the Driver component in myProject/components/myProject.Driver/myProject_Driver_Impl.cxx we have to implement the GoPort to get things going. The generated (empty) method looks like:



/**
 *  
 * Execute some encapsulated functionality on the component. 
 * Return 0 if ok, -1 if internal error but component may be 
 * used further, and -2 if error so severe that component cannot
 * be further used safely.
 */
int32_t
myProject::Driver_impl::go_impl () 

{
  // DO-NOT-DELETE splicer.begin(myProject.Driver.go)
  // Insert-Code-Here {myProject.Driver.go} (go method)
  // 
  // This method has not been implemented
  // 
    ::sidl::NotImplementedException ex = ::sidl::NotImplementedException::_create();
    ex.setNote("This method has not been implemented");
    ex.add(__FILE__, __LINE__, "go");
    throw ex;
  // DO-NOT-DELETE splicer.end(myProject.Driver.go)
}



Again delete the useless boilerplate code between the splicer directives and insert an implementation of the GoPort method go. The go() function will be called when the "go" button is pushed. We will implement that method to fetch the IntegratorPort that we have been connected to and use it to find the integral:



/**
 *  
 * Execute some encapsulated functionality on the component. 
 * Return 0 if ok, -1 if internal error but component may be 
 * used further, and -2 if error so severe that component cannot
 * be further used safely.
 */
int32_t
myProject::Driver_impl::go_impl () 

{
  // DO-NOT-DELETE splicer.begin(myProject.Driver.go)
  // Insert-Code-Here {myProject.Driver.go} (go method)

  double value;
  int count = 100000;
  double lowerBound = 0.0, upperBound = 1.0;

  ::integrator::IntegratorPort integrator;

  // get the port ...
  gov::cca::Port port = frameworkServices.getPort("IntegratorPort");
  integrator = babel_cast< ::integrator::IntegratorPort >(port);

  if(integrator._is_nil()) {
    fprintf(stdout, "drivers.CXXDriver not connected\n");
    frameworkServices.releasePort("IntegratorPort");
    return -1;    
  }
    // operate on the port
    value = integrator.integrate (lowerBound, upperBound, count);

    fprintf(stdout,"Value = %lf\n", value);
    fflush(stdout);
  
  // release the port.
  frameworkServices.releasePort("IntegratorPort");
  return 0;


  // DO-NOT-DELETE splicer.end(myProject.Driver.go)
}


Now remake your project tree to finish the components:



$  configure;make


Connect up and run your components in the GUI if you like:



$  ./utils/run-gui.sh


3.3.2.2.  Fortran9X Implementation

You created the project with bocca create project myProject --language=f90

Look at the file: myProject/components/myProject.Function/myProject_Function_Impl.F90 that Bocca has generated for you. Parse down the file until you find the evaluate_Impl method generated from the SIDL definition of FunctionPort method evaluate:


! 
! Method:  evaluate[]
! 

recursive subroutine myProject_Function_evaluate_mi(self, x, retval,           &
  exception)
  use sidl
  use sidl_NotImplementedException
  use sidl_BaseInterface
  use sidl_RuntimeException
  use myProject_Function
  use myProject_Function_impl
  ! DO-NOT-DELETE splicer.begin(myProject.Function.evaluate.use)
  ! Insert-Code-Here {myProject.Function.evaluate.use} (use statements)
  ! DO-NOT-DELETE splicer.end(myProject.Function.evaluate.use)
  implicit none
  type(myProject_Function_t) :: self ! in
  real (kind=sidl_double) :: x ! in
  real (kind=sidl_double) :: retval ! out
  type(sidl_BaseInterface_t) :: exception ! out

! DO-NOT-DELETE splicer.begin(myProject.Function.evaluate)
! Insert-Code-Here {myProject.Function.evaluate} (evaluate method)
 
! DO-DELETE-WHEN-IMPLEMENTING exception.begin() 
! 
! This method has not been implemented
! 
  type(sidl_BaseInterface_t) :: throwaway
  type(sidl_NotImplementedException_t) :: notImpl
  call new(notImpl, exception)
  call setNote(notImpl, 'Not Implemented', exception)
  call cast(notImpl, exception,throwaway)
  call deleteRef(notImpl,throwaway)
  return
! DO-DELETE-WHEN-IMPLEMENTING exception.end() 
 
! DO-NOT-DELETE splicer.end(myProject.Function.evaluate)
end subroutine myProject_Function_evaluate_mi


As the comment suggests this method is "not implemented" but some code has been inserted by Babel to make sure an exception is thrown to inform the user if this is called by mistake. Remove this boilerplate code and substitute an implementation for the SquareFunction: x2:


! 
! Method:  evaluate[]
! 

recursive subroutine SquareFun_evaluatetu_xix96dh_mi(self, x, retval,          &
  exception)
  use sidl
  use sidl_NotImplementedException
  use sidl_BaseInterface
  use sidl_RuntimeException
  use functions_SquareFunction
  use functions_SquareFunction_impl
  ! DO-NOT-DELETE splicer.begin(functions.SquareFunction.evaluate.use)
  ! Insert-Code-Here {functions.SquareFunction.evaluate.use} (use statements)
  ! DO-NOT-DELETE splicer.end(functions.SquareFunction.evaluate.use)
  implicit none
  type(functions_SquareFunction_t) :: self ! in
  real (kind=sidl_double) :: x ! in
  real (kind=sidl_double) :: retval ! out
  type(sidl_BaseInterface_t) :: exception ! out

! DO-NOT-DELETE splicer.begin(functions.SquareFunction.evaluate)

        retval = x*x 

! DO-NOT-DELETE splicer.end(functions.SquareFunction.evaluate)
end subroutine SquareFun_evaluatetu_xix96dh_mi

Now in the same file find the second method for FunctionPort: init:


recursive subroutine myProject_Function_init_mi(self, params, exception)
  use sidl
  use sidl_NotImplementedException
  use sidl_BaseInterface
  use sidl_RuntimeException
  use myProject_Function
  use sidl_double_array
  use myProject_Function_impl
  ! DO-NOT-DELETE splicer.begin(myProject.Function.init.use)
  ! Insert-Code-Here {myProject.Function.init.use} (use statements)
  ! DO-NOT-DELETE splicer.end(myProject.Function.init.use)
  implicit none
  type(myProject_Function_t) :: self ! in
  type(sidl_double_1d) :: params ! in
  type(sidl_BaseInterface_t) :: exception ! out

! DO-NOT-DELETE splicer.begin(myProject.Function.init)
! Insert-Code-Here {myProject.Function.init} (init method)

! Do nothing.

! DO-NOT-DELETE splicer.end(myProject.Function.init)
end subroutine myProject_Function_init_mi


Here we don't have any initialization so we just eliminate the code that throws the exception for running the method.

Similarly look at the Integrator in myProject/components/myProject.Integrator/myProject_Integrator_Impl.F90 specifically the integrate method:


! 
! Method:  integrate[]
! 

recursive subroutine Integrat_integrate27jlju5gbk_mi(self, lowBound, upBound,  &
  count, retval, exception)
  use sidl
  use sidl_NotImplementedException
  use sidl_BaseInterface
  use sidl_RuntimeException
  use myProject_Integrator
  use myProject_Integrator_impl
  ! DO-NOT-DELETE splicer.begin(myProject.Integrator.integrate.use)
  ! Insert-Code-Here {myProject.Integrator.integrate.use} (use statements)
  ! DO-NOT-DELETE splicer.end(myProject.Integrator.integrate.use)
  implicit none
  type(myProject_Integrator_t) :: self ! in
  real (kind=sidl_double) :: lowBound ! in
  real (kind=sidl_double) :: upBound ! in
  integer (kind=sidl_int) :: count ! in
  real (kind=sidl_double) :: retval ! out
  type(sidl_BaseInterface_t) :: exception ! out

! DO-NOT-DELETE splicer.begin(myProject.Integrator.integrate)
! Insert-Code-Here {myProject.Integrator.integrate} (integrate method)
 
! DO-DELETE-WHEN-IMPLEMENTING exception.begin() 
! 
! This method has not been implemented
! 
  type(sidl_BaseInterface_t) :: throwaway
  type(sidl_NotImplementedException_t) :: notImpl
  call new(notImpl, exception)
  call setNote(notImpl, 'Not Implemented', exception)
  call cast(notImpl, exception,throwaway)
  call deleteRef(notImpl,throwaway)
  return
! DO-DELETE-WHEN-IMPLEMENTING exception.end() 
 
! DO-NOT-DELETE splicer.end(myProject.Integrator.integrate)
end subroutine Integrat_integrate27jlju5gbk_mi

Again remove this boilerplate code and insert an implementation that uses the FunctionPort and a Monte-Carlo method for integration (to run this we will need to hook up the RandNumGenerator component from the pre-built tree):


! 
! Method:  integrate[]
! 

recursive subroutine MonteCar_integrateudcgc9x69z_mi(self, lowBound, upBound,  &
  count, retval, exception)
  use sidl
  use sidl_NotImplementedException
  use sidl_BaseInterface
  use sidl_RuntimeException
  use integrators_MonteCarlo
  use integrators_MonteCarlo_impl
  ! DO-NOT-DELETE splicer.begin(integrators.MonteCarlo.integrate.use)
  ! Insert use statements here...

  use function_FunctionPort
  use randomgen_RandomGeneratorPort
  use gov_cca_Services
  use gov_cca_Port
  use sidl_BaseInterface

  ! DO-NOT-DELETE splicer.end(integrators.MonteCarlo.integrate.use)
  implicit none
  type(integrators_MonteCarlo_t) :: self ! in
  real (kind=sidl_double) :: lowBound ! in
  real (kind=sidl_double) :: upBound ! in
  integer (kind=sidl_int) :: count ! in
  real (kind=sidl_double) :: retval ! out
  type(sidl_BaseInterface_t) :: exception ! out

! DO-NOT-DELETE splicer.begin(integrators.MonteCarlo.integrate)
 
 
! Insert the implementation here...


  type(gov_cca_Port_t) :: generalPort, generalPort2
  type(function_FunctionPort_t) :: functionPort
  type(randomgen_RandomGeneratorPort_t) :: randomPort
  type(SIDL_BaseInterface_t) :: excpt, funcExcpt, randomExcpt, throwaway
  ! Private data reference
  type(integrators_MonteCarlo_wrap) :: dp

  real (selected_real_kind(15, 307)) :: sum, width, x, func
  integer (selected_int_kind(9)) :: i

  ! Access private data
  call integrators_MonteCarlo__get_data_m(self, dp)
  retval = -1

  if (not_null(dp%d_private_data%d_services)) then
     ! Obtain a handle to a FunctionPort
     call getPort(dp%d_private_data%d_services, &
          'function', generalPort, funcExcpt)

     if (is_null(funcExcpt)) then

        call cast(generalPort, functionPort, throwaway)
        if (not_null(functionPort)) then
           
           ! Obtain a handle to a RandomGeneratorPort
           call getPort(dp%d_private_data%d_services, &
                'RandomGeneratorPort', generalPort2, randomExcpt)

           if (is_null(randomExcpt)) then
              call cast(generalPort2, randomPort, throwaway)
              if (not_null(randomPort)) then
                 ! Compute integral
                 sum = 0
                 width = upBound - lowBound
                 do i = 1, count
                    call getRandomNumber(randomPort, x, excpt)
                    call checkExceptionMC(excpt, &
                      'getRandomNumber(randomPort, x, excpt)')
                    x = lowBound + width*x
                    call evaluate(functionPort, x, func, excpt)
                    call checkExceptionMC(excpt, &
                    'evaluate(functionPort, x, func, excpt)')
                    sum = sum + func
                 enddo
                 retval = width*sum/count
              else  ! randomPort is null
                 write(*,*) 'Exception: MonteCarlo: incompatible RandomGeneratorPort'
              endif
              call deleteRef(generalPort2, throwaway)

           else  ! randomExcpt is not null

              call checkExceptionMC(randomExcpt, 'getPort(''RandomPort'')')
           endif
        else    ! functionPort is null
           write(*,*) 'Exception: MonteCarlo: incompatible FunctionPort'
        endif
        call deleteRef(generalPort, throwaway)

        ! Free ports
        call releasePort(dp%d_private_data%d_services, &
             'RandomGeneratorPort', excpt)
        call checkExceptionMC(excpt, 'releasePort(''RandomGeneratorPort'')')
 
        call releasePort(dp%d_private_data%d_services, &
             'function', excpt)
        call checkExceptionMC(excpt, 'releasePort(''function'')')
 
     else      ! funcExcpt is not null

        call checkExceptionMC(funcExcpt, 'getPort(''function'')')
     endif
  else
     write(*,*) 'Error: MonteCarlo: integrate called before setServices'
  endif

! DO-NOT-DELETE splicer.end(integrators.MonteCarlo.integrate)
end subroutine MonteCar_integrateudcgc9x69z_mi


Finally for the Driver component in file myProject/components/myProject.Driver/myProject_Driver_Impl.F90 we have to implement the GoPort to get things going. The generated (empty) method looks like:


! 
! Method:  go[]
!  
! Execute some encapsulated functionality on the component. 
! Return 0 if ok, -1 if internal error but component may be 
! used further, and -2 if error so severe that component cannot
! be further used safely.
! 

recursive subroutine myProject_Driver_go_mi(self, retval, exception)
  use sidl
  use sidl_NotImplementedException
  use sidl_BaseInterface
  use sidl_RuntimeException
  use myProject_Driver
  use myProject_Driver_impl
  ! DO-NOT-DELETE splicer.begin(myProject.Driver.go.use)
  ! Insert-Code-Here {myProject.Driver.go.use} (use statements)
  ! DO-NOT-DELETE splicer.end(myProject.Driver.go.use)
  implicit none
  type(myProject_Driver_t) :: self ! in
  integer (kind=sidl_int) :: retval ! out
  type(sidl_BaseInterface_t) :: exception ! out

! DO-NOT-DELETE splicer.begin(myProject.Driver.go)
! Insert-Code-Here {myProject.Driver.go} (go method)
 
! DO-DELETE-WHEN-IMPLEMENTING exception.begin() 
! 
! This method has not been implemented
! 
  type(sidl_BaseInterface_t) :: throwaway
  type(sidl_NotImplementedException_t) :: notImpl
  call new(notImpl, exception)
  call setNote(notImpl, 'Not Implemented', exception)
  call cast(notImpl, exception,throwaway)
  call deleteRef(notImpl,throwaway)
  return
! DO-DELETE-WHEN-IMPLEMENTING exception.end() 
 
! DO-NOT-DELETE splicer.end(myProject.Driver.go)
end subroutine myProject_Driver_go_mi

Again delete the useless boilerplate code between the splicer directives and insert an implementation of the GoPort method go. The go() subroutine will be called when the "go" button is pushed. We will implement that method to fetch the IntegratorPort that we have been connected to and use it to find the integral:


! 
! Method:  go[]
!  
! Execute some encapsulated functionality on the component. 
! Return 0 if ok, -1 if internal error but component may be 
! used further, and -2 if error so severe that component cannot
! be further used safely.
! 

recursive subroutine drivers_F90Driver_go_mi(self, retval, exception)
  use sidl
  use sidl_NotImplementedException
  use sidl_BaseInterface
  use sidl_RuntimeException
  use drivers_F90Driver
  use drivers_F90Driver_impl
  ! DO-NOT-DELETE splicer.begin(drivers.F90Driver.go.use)
  ! Insert use statements here...
  
  use sidl_BaseInterface
  use gov_cca_Port
  use integrator_IntegratorPort

  ! DO-NOT-DELETE splicer.end(drivers.F90Driver.go.use)
  implicit none
  type(drivers_F90Driver_t) :: self ! in
  integer (kind=sidl_int) :: retval ! out
  type(sidl_BaseInterface_t) :: exception ! out

! DO-NOT-DELETE splicer.begin(drivers.F90Driver.go)
 
 
! Insert the implementation here...


  type(gov_cca_Port_t) :: generalPort
  type(SIDL_BaseInterface_t) :: excpt
  type(integrator_IntegratorPort_t) :: integratorPort

  ! Private data reference
  type(drivers_F90Driver_wrap) :: dp

  ! local variables for integration
  real (kind=sidl_double) :: lowBound 
  real (kind=sidl_double) :: upBound 
  integer (kind=sidl_int) :: count 
  real (kind=sidl_double) :: value 

  ! Initialize local variables
  count = 100000
  lowBound = 0.0
  upBound = 1.0

  ! Access private data
  call drivers_F90Driver__get_data_m(self, dp)
  retval = -1

  ! get the port ...
  call getPort(dp%d_private_data%d_services, &
       'integrate', generalPort, excpt)
  call checkExceptionDriver(excpt, 'getPort(''integrate'')')
  if(is_null(generalPort)) then
     write(*,*) 'drivers.F90Driver not connected'
     return
  endif

  ! Get an IntegratorPort reference from the general port one
  call cast(generalPort, integratorPort, excpt)
  call checkExceptionDriver(excpt, 'cast(generalPort, integratorPort, excpt)')
  
  if (not_null(integratorPort)) then
     value = -1.0 ! nonsense number to confirm it is set

     ! operate on the port
     call integrate(integratorPort, lowBound, upBound, count, value, excpt)
     call checkExceptionDriver(excpt, &
        'integrate(integratorPort, lowBound, upBound, count, value, excpt)')
  
     write(*,*) 'Value = ', value
  else   ! integratorPort is null
     write(*,*) 'DriverF90: incompatible IntegratorPort'
  endif

  ! release the port
  call releasePort(dp%d_private_data%d_services, &
       'integrate', excpt)
  call checkExceptionDriver(excpt, 'releasePort(''integrate'')')

  retval = 0
  return

! DO-NOT-DELETE splicer.end(drivers.F90Driver.go)
end subroutine drivers_F90Driver_go_mi

Now remake your project tree to finish the components:



$  configure;make


Connect up and run your components in the GUI if you like:



$  ./utils/run-gui.sh


3.3.2.3.  C Implementation

You created the project with bocca create project myProject --language=c

Look at the file: myProject/components/myProject.Function/myProject_Function_Impl.c that Bocca has generated for you. Parse down the file until you find the evaluate_Impl method generated from the SIDL definition of FunctionPort:


/*
 * Method:  evaluate[]
 */

#undef __FUNC__
#define __FUNC__ "impl_myProject_Function_evaluate"

#ifdef __cplusplus
extern "C"
#endif
double
impl_myProject_Function_evaluate(
  /* in */ myProject_Function self,
  /* in */ double x,
  /* out */ sidl_BaseInterface *_ex)
{
  *_ex = 0;
  {
    /* DO-NOT-DELETE splicer.begin(myProject.Function.evaluate) */
    /* Insert-Code-Here {myProject.Function.evaluate} (evaluate method) */
    
    /* DO-DELETE-WHEN-IMPLEMENTING exception.begin() */
    /* 
     * This method has not been implemented.
     */
    SIDL_THROW(*_ex, sidl_NotImplementedException,     "This method has not been implemented");
  EXIT:;
    /* DO-DELETE-WHEN-IMPLEMENTING exception.end() */
    
    /* DO-NOT-DELETE splicer.end(myProject.Function.evaluate) */
  }
}

As the comment suggests this method is "not implemented" but some code has been inserted by Babel to make sure an exception is thrown to inform the user if this is called by mistake. Remove this boilerplate so and substitute an implementation for the LinearFunction:


/*
 * Method:  evaluate[]
 */

#undef __FUNC__
#define __FUNC__ "impl_functions_LinearFunction_evaluate"

#ifdef __cplusplus
extern "C"
#endif
double
impl_functions_LinearFunction_evaluate(
  /* in */ functions_LinearFunction self,
  /* in */ double x,
  /* out */ sidl_BaseInterface *_ex)
{
  *_ex = 0;
  {
    /* DO-NOT-DELETE splicer.begin(functions.LinearFunction.evaluate) */
    
    
  /* Insert the implementation of the evaluate method here... */

  return 12.0 * x + 3.2;

    /* DO-NOT-DELETE splicer.end(functions.LinearFunction.evaluate) */
  }


Now in the same file find the second method for FunctionPort: init:


/*
 * Method:  init[]
 */

#undef __FUNC__
#define __FUNC__ "impl_functions_LinearFunction_init"

#ifdef __cplusplus
extern "C"
#endif
void
impl_functions_LinearFunction_init(
  /* in */ functions_LinearFunction self,
  /* in array<double> */ struct sidl_double__array* params,
  /* out */ sidl_BaseInterface *_ex)
{
  *_ex = 0;
  {
    /* DO-NOT-DELETE splicer.begin(functions.LinearFunction.init) */
    
  /* Insert the implementation of the init method here... */

/* Do Nothing. */

    /* DO-NOT-DELETE splicer.end(functions.LinearFunction.init) */
  }
}

Here we don't have any initialization so we just eliminate the code that throws the exception for running the method.

To incorporate this component into an application you will have to link it up with Driver and Integrator components from the pre-built source tree. To compile and link this component remake your project:



$  configure;make


Connect up and run your components in the GUI if you like:



$  ./utils/run-gui.sh