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.
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.
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
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
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