#include #include #include #include "cca_factory.hh" SimTK::CCAFramework::CCAFramework() {} SimTK::CCAFramework::~CCAFramework() { } void SimTK::CCAFramework::driverBody( neo::cca::AbstractFramework *af ) throw(neo::cca::Exception) { neo::cca::TypeMap_shared dummy; dummy = af->createTypeMap(); builderServices = 0; SimTK::CCAPrivateRepository pr; abstractFramework = af; // set the script up as a component in the frame it receives. services = abstractFramework->getServices("SimTK::CCAFramework", "SimTK::CCAFramework", dummy); // and find its id tag in the frame. neo::cca::ComponentID_shared myself = services->getComponentID(); // tell the framework about the components that come with the driver. // the components from simtk_NeoMain_PrivateRepository will now be available from // the BuilderService port. services->addProvidesPort(&pr, "SimTKCCAFactory", "neo::cca::ports::ComponentFactory"); services->registerUsesPort("bs", "neo::cca::ports::BuilderService"); neo::cca::Port *p = 0; p = services->getPort("bs"); builderServices = dynamic_cast< neo::cca::ports::BuilderService *>(p); if (builderServices == 0) { throw neo::cca::Exception(neo::cca::BadPortType, "Service port bs is not of expected type neo::cca::ports::BuilderService"); } std::cerr << "####### Creating StartSim s1 #########" << std::endl; neo::cca::ComponentID_shared s1 = builderServices->createInstance("s1", "SimTK::StartSim", dummy); std::cerr << "####### Creating CvodeComponent cv #########" << std::endl; neo::cca::ComponentID_shared cv = builderServices->createInstance("cv", "SimTK::CvodeComponent", dummy); std::cerr << "####### Creating UserDense ud #########" << std::endl; neo::cca::ComponentID_shared ud = ud = builderServices->createInstance("ud", "SimTK::UserDense", dummy); neo::cca::ConnectionID_shared s1_cvode_cv_THE_CVODE = builderServices->connect(s1, "cvode", cv, "THE_CVODE"); neo::cca::ConnectionID_shared cv_Dense_ud_THE_CVODE = builderServices->connect(cv, "Dense", ud, "UserFunc"); neo::support::helpers::invokeGo( "s1", "go", s1 , services, builderServices ); std::cerr << "####### Shutting down #########" << std::endl; // Section to clean up connections the user didn't. reverse order. builderServices->disconnect(cv_Dense_ud_THE_CVODE, 0); builderServices->disconnect(s1_cvode_cv_THE_CVODE, 0); // Section to clean up components the user didn't. reverse order. builderServices->destroyInstance(ud, 0.0); builderServices->destroyInstance(cv, 0.0); builderServices->destroyInstance(s1, 0.0); builderServices = 0; services->releasePort("bs"); services->unregisterUsesPort("bs"); services->removeProvidesPort("SimTKCCAFactory"); // remove ourselves from the frame. abstractFramework->releaseServices(services); } /* Generated extern block */ /*---------------------------------------*/ extern "C" { /* We expect the following functions, or equivalent with alternate names, * to exist. Given these component-specific constructor wrappers, * we can do the rest with generic framework facilities and do * not need to include component or application specific headers. * * The names generated here depend on the input ccaffeine script, * and may need to be adjusted to match c++ reality. */ neo::cca::Component *create_StartSim(); neo::cca::Component *create_UserDense(); neo::cca::Component *create_CvodeComponent(); } /* Generated custom factory implementation block */ /*---------------------------------------*/ void SimTK::CCAPrivateRepository::addDescription(std::string name, std::string alias) { neo::cca::ports::ComponentClassDescription_shared ncpccds = neo::support::ComponentClassDescription::create(name, alias); descriptions.push_back(ncpccds); } SimTK::CCAPrivateRepository::CCAPrivateRepository() { addDescription("SimTK::StartSim", "SimTK::StartSim"); addDescription("SimTK::UserDense", "SimTK::UserDense"); addDescription("SimTK::CvodeComponent", "SimTK::CvodeComponent"); } std::vector< neo::cca::ports::ComponentClassDescription_shared > SimTK::CCAPrivateRepository::getAvailableComponentClasses() { return descriptions; } std::vector< std::string> SimTK::CCAPrivateRepository::getComponentClassAliases() { std::vector< std::string> result; for (size_t i=0, n= descriptions.size(); i < n; i++) { result.push_back( descriptions[i]->getDeploymentClassAlias() ); } return result; } neo::cca::Component * SimTK::CCAPrivateRepository::createComponentInstance(const std::string & classAlias) { neo::cca::TypeMap_shared tm; return createComponentInstance(classAlias, tm); } neo::cca::Component * SimTK::CCAPrivateRepository::createComponentInstance(const std::string & classAlias, neo::cca::TypeMap_shared & properties) { // note for users. if your components need something other than // the usual C wrapper (like they want to have properties passed) // then you will modify the code in this function. if (classAlias == "SimTK::StartSim") { return create_StartSim(); } if (classAlias == "SimTK::UserDense") { return create_UserDense(); } if (classAlias == "SimTK::CvodeComponent") { // faking create function for CvodeComponent. fix this code by hand or make sure the component libraries referred to in the input script exist. return create_CvodeComponent(); } return 0; //throw? } void SimTK::CCAPrivateRepository::destroyComponentInstance(const std::string & componentClassAlias, neo::cca::Component * component) { // note for users: you may need to write a c wrapper // for your destructor as well if you have used // advanced c++ techniques for memory management. if ( componentClassAlias == "SimTK::StartSim" ) { delete component; } if ( componentClassAlias == "SimTK::UserDense" ) { delete component; } if ( componentClassAlias == "SimTK::CvodeComponent" ) { delete component; } }