520 likes | 653 Views
Interpreters 2. (Translators). Component stack. Legend. pointer to. operates on. interface. C++ BON1 based component (interpreter). C++ BON2 based component (interpreter). JAVA BON based component (interpreter). part of GME. user-written. C++ BON1. C++ BON2. JAVA BON.
E N D
Component stack Legend pointer to operates on interface C++ BON1 based component (interpreter) C++ BON2 based component (interpreter) JAVA BON based component (interpreter) part of GME user-written C++ BON1 C++ BON2 JAVA BON Wrapper layer C# Raw .NET component (interpreter) CBuilderModel Model JBuilderModel Implementation layer C++ RawCOM component (interpreter) ModelImpl .NET-COM interop MGA component of GME (Gmodel) IMgaModel* IMgaModel* IMgaModel*
Interface definitions found at: COM interface definition mapped to .NET interface is shown in Visual Studio’s Object Browser C++ BON1 based component (interpreter) C++ BON2 based component (interpreter) JAVA BON based component (interpreter) C++ BON1 C++ BON2 JAVA BON Wrapper layer class JBuilderModel in gme\SDK\Java\gme.jar - or - gme\SDK\Java\org\isis\gme\bon class Model gme\SDK\BON\ BON.h C# Raw .NET component (interpreter) class CBuilderModel in gme\SDK\BON\Builder.h Impl layer class ModelImpl gme\SDK\BON\ BONImpl.h C++ RawCOM component (interpreter) .NET-COM interop MGA component of GME (Gmodel) interface IMgaModel in gme\Interfaces\Mga.idl IMgaModel* IMgaModel*
Using JAVA for interpreters • Org package • Isis package • Jaut package • GME package • Mga package • Meta package • BON package • TestBONComponent class • BONComponent interface • JBuilderModel class • JBuilderAtom class etc. JAVA-BON found in GME\SDK\JAVA\gme.jar BON = builder object network --a higher level interface-- Dummy implementation JavaBon Interpreters use these classes
How to Create a JAVA intepreter? // contents of file TestBONComponent.java package org.isis.gme.bon; import java.util.*; import org.isis.gme.mga.MgaObject; public class TestBONComponent implements BONComponent { public void invokeEx( JBuilder builder, JBuilderObject focus, Collection selected, int param) { } } invokeEx() method entry point when an interpreter is called from GME
A plain JAVA intepreter • Fill in the blanks in TestBONComponent.java • Compile your class • javac -classpath "C:\Program Files\GME\SDK\Java\gme.jar" TestBONComponent.java • Register it with SDK \ JAVA \ JavaCompRegister.exe • Name: MyHelloWorldInterpreter • No spaces • Description: This is Hello World from JAVA • ProgID: Mga.Interpreter.MyHelloWorldInterpreter • Autocompleted based on Name, no spaces, uniqueness • GUID: 12345678-9ABC-DEF0-1234-56789ABCDEF0 • Changes upon all invokations of JavaCompRegister • ClassPath: <<path to your compiled .class file>> • E.g. c:\myprojects\myjavainterpreters • Class: <<full name of your class>> • mic.gme.interpreters.TestBONComponent • Paradigms • * indicates all • Menu/Tooltip • Select a few objects before running this interpreter • Register systemwide • For all users/For this user? • Run it from GME
Classes and methods • JBuilder methods • JBuilderFolder getRootFolder() • String getProjectName() • MgaProject getProject() • JBuilderFolder methods • public String getName() • public Vector getRootModels() • public Vector getSubFolders() • JBuilderModel createNewModel(String kindName) • JBuilderModel methods • Vector getChildren() • String getCurrentAspent() • JBuilderModel createNewModel(String partName) • JBuilderAtom createNewAtom(String partName) • JBuilderConnection createNewConnection(…) • JBuilderReference createNewReference(String partName) • JBuilderReference methods • boolean putReferred(JBuilderObject nref) • JBuilderObject getReferred() • int getReferredType() • JBuilderConnection methods • JBuilderModel getOwner() • JBuilderObject getSource() • JBuilderObject getDestination() BON classes found in GME\SDK\JAVA\gme.jar
Classes and methods 2. • JBuilderObject methods • String getObjID() • JBuilderModel getParent() • boolean getAttribute(String name, double val[]) • boolean getAttribute(String name, boolean val[]) • boolean getAttribute(String name, int val[]) • boolean getAttribute(String name, String val[]) • boolean setAttribute(String name, boolean val) • boolean setAttribute(String name, float val) • boolean setAttribute(String name, int val) • boolean setAttribute(String name, String val) • Vector getInConnections(String name) • Vector getOutConnections(String name) • boolean getInConnectedObjects(String name, Vector list[]) • boolean getOutConnectedObjects(String name, Vector list[]) • Vector getReferencedBy() BON classes found in GME\SDK\JAVA\gme.jar
ReferencePorts If selection object is a reference • if(selection.getObjType()==MgaObject.OBJTYPE_REFERENCE) • { • msg = msg + "Reference " + selection.getName() + " selected. \n Refers to: "; • JBuilderObject referred = ((JBuilderReference)selection).getReferred(); • if(referred == null) • msg = msg + "NULL\n"; • else • { • msg = msg + referred.getName() + "\n"; • if(selection.getClass().getName().equals("org.isis.gme.bon.JBuilderModelReference")) • { • Vector ports = ((JBuilderModelReference)selection).getReferencePorts(); • msg = msg + " " + ports.size() + " Reference Ports.\n"; • for(int j=0; j<ports.size(); j++) • { • JBuilderReferencePort port = (JBuilderReferencePort)ports.elementAt(j); • msg = msg + " " + port.getName() + " connected to:"; • msg = msg + getConnectedNames(port); • msg = msg + getConnectedNames(port.getPortObject()); • msg = msg + "\n"; • } • } • } • } If not a null reference If a modelrefernce ( = refers to a model) Model1 Ref1 Ref2 Model2
A JAVA intepreter in Eclipse • Eclipse • Open workspace • Create a package (optional) • Create a class MyBONComponent • Add reference to gme.jar • Save it • Register it with SDK \ JAVA \ JavaCompRegister.exe • Run it • Modify it • Save it • Involves auto-compilation • Run it Repeat these steps
How to Create a C++ intepreter? • Use GME\SDK\CreateNewComponent.exe to create • BON • BON2 • RAW COM components • Requires MS VS .NET 2003 installed • the official version of GME is built with this version • Creates solution and project file properly set up for • MS VS .NET 2003 (VC++ 7.1) • Available for download CreateNewComponent80.exe, which creates solution and project files for MS VS .NET 2005 (VC++ 8.0) • Workflow: • Create the component • Build (Build menu/Build Solution) • Self-Registration into GME is done after link step succeeded • Try it from GME • Enhance it with your code: look for the invokeEx() method
Welcome to the BON2 world • Uses Standard template library (STL) • Is A Higher level C++ interface to Models
Standard Template Library (STL) • Container types: vector, list, set, multiset, map, multimap, hashmap • Methods: push_back, insert, remove, … • set< string> Myset; // Lexicographical compare by default • Myset.insert( “zero”); • Myset.insert( “one”); //{ “one”, “zero”} • set< string, numericalCompare> Myset; • Myset.insert( “zero”); //{ “zero”, “one” } • Myset.insert( “one”);
Sets sorted in a specific order class NumericalCompare // will compare p1 and p2; returns ( p1 < p2 ) { public: bool operator( ) ( string p1, string p2) const ; }; set< string, NumericalCompare> Myset; // implementation of comparator: bool NumericalCompare::operator( )( string p1, string p2) const { int v1 = parseInt( p1); int v2 = parseInt( p2); return v1 < v2; } class ObjComp { public: bool operator()( BON::Object p1, BON::Object p2) const; }; std::set<BON::Object, ObjComp> ObjSet; bool ObjComp::operator( )( BON::Object p1, BON::Object p2) const { if( !p1) return true; if( !p2) return false; return p1->getName() < p2->getName(); // string lexicographical compare } Comparator methods must fulfill the following Irreflexivity x < x must be false. Antisymmetry x < y implies !(y < x) Transitivity x < y and y < z implies x < z Otherwise one may end up with infinite loops upon insertion, when the comapator is used.
Standard Template Library (STL) • Standard way of iterating over a sequence of objects: typedef vector<int> MyCont; typedef vector<int>::const_iterator MyCont_C_Iter; MyCont mycont; for( MyCont_C_Iter it = mycont.begin(); it != mycont.end(); // standard end-condition++it) { int k = *it; //current object is obtained by *it }
Standard Template Library (STL) • Underlying container changed from vector to list, and still works: typedef list<int> MyCont; typedef list<int>::const_iterator MyCont_C_Iter; MyCont mycont; for( MyCont_C_Iter it = mycont.begin(); it != mycont.end(); // standard end-condition++it) { int k = *it; //current object is obtained by *it }
Layers in BON2 Legend BON2 component (interpreter) pointer to operates on BON2 wrapper layer Model Atom BON2 implementation layer ModelImpl AtomImpl MGA component of GME (Gmodel) IMgaModel* IMgaAtom*
BON2 wrapper classes Util::GenRefCounter RegistryNode Attribute ConnectionEnd Object ReferencePort FCO Folder Atom Reference Connection Model Set Legend: inheritance
BON2 implementation classes Util::GenRefCounted EventListenerPool RegistryNodeImpl AttributeImpl ConnectionEndImpl ObjectImpl ReferencePortImpl FCOImpl FolderImpl AtomImpl ReferenceImpl ConnectionImpl ModelImpl SetImpl Legend: inheritance
Important methods on the wrapper layer class FCO { public: // to test if an object is not null simply: if( myFCO) { //… operator bool () const; // to test if an object is not null simply: if( !myFCO) { //… bool operator ! () const; // constructor to convert from a ConnectionEnd e.g: // ConnectionEnd a_connection_end = … // given a ConnectionEnd object returned by some method // FCO myFCO( a_connection_end); // convert it to an FCO // if( myFCO) { // … } // if succeeded FCO( const ConnectionEnd& object ); // constructor to convert from an Object FCO( const Object& object ); }; class Folder { public: FolderImpl* operator -> () const; static Folder create( const Folder& parent, const MON::Folder& meta = MON::Folder() ); static Folder create( const Folder& parent, const std::string& strFolder ); };
Important methods on the wrapper layer 2. class Atom { public: // to create a new Atom in a Folder e.g.: Atom myAtom = Atom::create( folder_parent); static Atom create( const Folder& parent, const MON::Atom& meta = MON::Atom() ); // to create a new Atom in a Folder e.g.: Atom myAtom = Atom::create( folder_parent, “InputSignal”); static Atom create( const Folder& parent, const std::string& strAtom ); // to create a new Atom in a Model e.g.: Atom myAtom = Atom::create( model_parent); static Atom create( const Model& parent, const MON::Atom& meta = MON::Atom(), const std::string& strRole = "" ); // to create a new Atom in a Model e.g.: Atom myAtom = Atom::create( model_parent, “InputParam”, “InputParameters”); static Atom create( const Model& parent, const std::string& strAtom, const std::string& strRole = "" ); AtomImpl* operator -> () const; }; class Model { public: // to create a new Model in a Folder e.g.: Model myModel = Model::create( folder_parent, “Compound”); static Model create( const Folder& parent, const std::string& strModel ); // to create a new Model in a Model e.g.: Model myModel = Model::create( model_parent, “Compound”, “CompoundParts”); static Model create( const Model& parent, const std::string& strModel, const std::string& strRole = "" ); // all other method calls will be dispatched to ModelImpl though operator -> // e.g. it is NOT OK : set<FCO> myInpSignals = myModel.getChildFCOs( “InputSignals”); // compiler error, no such method // e.g. it is OK : set<FCO> myInpSignals = myModel->getChildFCOs( “InputSignals”); ModelImpl* operator -> () const; // … };
Important methods on the impl layer class FCOImpl : public ObjectImpl, public ConnectionEndImpl { public: // who is my parent Model getParentModel(); // which set is FCO member of e.g.: set<Set> i_am_member_of = fco->getMemberOf(); set<Set> getMemberOf( const MON::Set& meta = MON::Set(), const MON::Aspect& aspect = MON::Aspect() ); // which reference points to this FCO e.g.: set<Reference> i_am_referred_by = fco->getReferredBy(); set<Reference> getReferredBy( const MON::Reference& meta = MON::Reference() ); // to find out an attribute’s value use e.g.: string val = fco->getAttribute(“Firing”)->getStringValue(); Attribute getAttribute( const std::string& strName ); }; class AttributeImpl { public: // to inquire an attribute value these can be used depending on its type //e.g.: long prim_priority = primitiveFCO->getAttribute(“Priority”)->getIntegerValue(); long getIntegerValue( bool bTypeTolerant = true ) const; void setIntegerValue( long lValue, bool bTypeTolerant = true ); bool getBooleanValue( bool bTypeTolerant = true ) const; void setBooleanValue( bool bValue, bool bTypeTolerant = true ); double getRealValue( bool bTypeTolerant = true ) const; void setRealValue( double dValue, bool bTypeTolerant = true ); string getStringValue( bool bTypeTolerant = true ) const; void setStringValue( const std::string& strValue, bool bTypeTolerant = true ); };
Important methods on the impl layer 2. class ReferenceImpl { public: // e.g. FCO refd = a_ref->getReferred(); FCO getReferred( const MON::FCO& meta = MON::FCO() ); FCO getReferred( const std::string& strFCO ); // e.g. a_ref->setReferred( new_target); void setReferred( const FCO& fco ); }; class SetImpl { public: // to inquire members // e.g.: set< FCO> members = a_set->getMembers(); std::set<FCO> getMembers( const MON::FCO& meta = MON::FCO(), const MON::Aspect& aspect = MON::Aspect() ); std::set<FCO> getMembers( const std::string& strFCO, const MON::Aspect& aspect = MON::Aspect() ); // add and remove members void addMember( const BON::FCO& fco ); void removeMember( const BON::FCO& fco ); };
Important methods on the impl layer 3. class FCOImpl : public ObjectImpl, public ConnectionEndImpl { … }; class ConnectionImpl : virtual public FCOImpl { // e.g. ConnectionEnd src = a_conn->getSrc(); ConnectionEnd getSrc( ... ); ConnectionEnd getDst( ... ); std::multiset<ConnectionEnd> getConnEnds( ... ); }; class ConnectionEndImpl { // e.g. set<Connection> lines = an_end->getConnLinks(); std::set<Connection> getConnLinks(); // e.g. multiset<ConnectionEnd> peers = an_end->getConnEnds(); std::multiset<ConnectionEnd> getConnEnds(); }; class ReferencePortImpl : public ConnectionEndImpl { FCO getFCO(); };
Handling connectionEnds in a complex paradigm void handle( ConnectionEnd& p_connectionend) { BON::FCO connend_fco( p_connectionend); if( connend_fco) { // connend_fco is valid: the connected object is an fco } else { BON::ReferencePort connend_refport( p_connectionend); if( connend_refport) { // it's a referenceport: see ReferencePortImpl for details BON::FCO fco = connend_refport->getFCO(); BON::ReferencePortContainer rpc = connend_refport->getContainer(); BON::Reference ref = rpc->getReference(); // the connected end is a port (fco) shown on a reference (ref) } else ASSERT(0); // it can't happen } } Model1 Ref1 Ref2 Model2
BON2 interpreter entry point& debugging void Component::invokeEx( Project& project, FCO& currentFCO, const std::set<FCO>& setSelectedFCOs, long lParam ) // project : the currently opened project // currentFCO and setSelectedFCOs: the currently selected objects if any { std::string msg; std::set<FCO>::const_iterator it0 = setSelectedFCOs.begin(); std::set<FCO>::const_iterator itE = setSelectedFCOs.end(); for( ; it0 != itE; ++it0) { FCO i = *it0; msg += i->getName(); msg += "\n"; } if( msg.empty()) msg = "No object selected"; // show in a message box the names of the selected objects AfxMessageBox( msg.c_str()); // show message in console window project->consoleMsg( msg, MSG_INFO); }
ProjectImpl (found in BonImpl.h) The most important: RootFolder accessed • Folder getRootFolder(); • std::set<Object> findByKind(const std::string& strKind ); • std::set<Object> findByKind(const MON::Object& meta ); • const MON::Project& getProjectMeta(); • void consoleMsg(const std::string& msg, msgtype_enum type); Access to the MetaModel Sends message to the GME console window
FolderImpl • Object findByPath( const std::string& strPath, const std::string& strDelimiter = "/", bool bReverseOrder = false ); • std::set<Object> getChildObjects( const MON::Object& meta = MON::Object() ); • std::set<Object> getChildObjects(const std::string& strObject ); • std::set<Folder> getChildFolders(); • std::set<FCO> getRootFCOs(); • std::set<Atom> getChildAtoms(); • std::set<Model> getChildModels(); Model myC= project->getRootFolder()->findByPath("/SFDemo/System") std::set<Model> submodels = myC->getChildModels();
ModelImpl • std::set<FCO> getChildFCOs(const MON::FCO& meta = MON::FCO(), const MON::Aspect& aspect = MON::Aspect()); • std::set<FCO> getChildFCOs( const std::string& strFCO, const MON::Aspect& aspect = MON::Aspect()); • std::set<FCO> getChildFCOsAs(const std::string& strRole, const MON::Aspect& aspect = MON::Aspect()); • std::set<Atom> getChildAtoms(const MON::Aspect& aspect = MON::Aspect()); • std::set<Model> getChildModels(const MON::Aspect& aspect = MON::Aspect() ); • std::set<Set> getChildSets( const MON::Aspect& aspect = MON::Aspect()); • std::set<Reference> getChildReferences(const MON::Aspect& aspect = MON::Aspect()); • std::set<Connection> getChildConnections( const MON::Aspect& aspect = MON::Aspect()); isigs = model->getChildFCOs(“InputSignal") isigs = model->getChildFCOsAs(“InputSignals") Children getter methods
ConnectionEndImpl • std::set<Connection> getConnLinks(const MON::Connection& meta = MON::Connection(), const std::string& strRole = "", bool bIncludeRefs = true, const MON::Aspect& aspect = MON::Aspect() ); • std::set<Connection> getConnLinks(const std::string& strConnection, const std::string& strRole = "", bool bIncludeRefs = true, const MON::Aspect& aspect = MON::Aspect() ); • std::set<Connection> getInConnLinks(const MON::Connection& meta = MON::Connection(), bool bIncludeRefs = true, const MON::Aspect& aspect = MON::Aspect() ); • std::set<Connection> getInConnLinks(const std::string& strConnection, bool bIncludeRefs = true, const MON::Aspect& aspect = MON::Aspect() ); • std::set<Connection> getOutConnLinks(const MON::Connection& meta = MON::Connection(), bool bIncludeRefs = true, const MON::Aspect& aspect = MON::Aspect() ); • std::set<Connection> getOutConnLinks(const std::string& strConnection, bool bIncludeRefs = true, const MON::Aspect& aspect = MON::Aspect() ); Links: the connection lines
ConnectionEndImpl cont’d • std::multiset<ConnectionEnd> getInConnEnds(const MON::Connection& meta = MON::Connection(), bool bIncludeRefs = true, const MON::Aspect& aspect = MON::Aspect() ); • std::multiset<ConnectionEnd> getInConnEnds(const std::string& strConnection, bool bIncludeRefs = true, const MON::Aspect& aspect = MON::Aspect() ); • std::multiset<ConnectionEnd> getOutConnEnds(const MON::Connection& meta = MON::Connection(), bool bIncludeRefs = true, const MON::Aspect& aspect = MON::Aspect() ); • std::multiset<ConnectionEnd> getOutConnEnds(const std::string& strConnection, bool bIncludeRefs = true, const MON::Aspect& aspect = MON::Aspect() ); • std::multiset<ConnectionEnd> getConnEnds( const MON::Connection& meta = MON::Connection(), const std::string& strRole = "", bool bIncludeRefs = true, const MON::Aspect& aspect = MON::Aspect() ); • std::multiset<ConnectionEnd> getConnEnds( const std::string& strConnection, const std::string& strRole = "", bool bIncludeRefs = true, const MON::Aspect& aspect = MON::Aspect() ); Ends: the connection endpoints
ObjectImpl • std::string getName() const; • void setName(const std::string& strName ); • std::string getPath( const std::string& strDelimiter = "/", bool bReverseOrder = false, bool bNeedRootFolder = false ) const; • const MON::Object& getObjectMeta() const; • std::string getInfoString(); Absolute path of object Debugging info Meta description class of object
Automatic domain-specific extension of BON2 BonExtender (BonX) interpreter
BonX interpreter • CodeGenerator • Input: Metamodel • Output: C++ code (class definition and implementation) • Automatical generation of paradigm specific code • Life without BonX: • a paradigm specific code had to be hand-written first • error prone for typos ( i.e. ‘InputSignal’ or ‘Inputsignal’) • Relates to UDM (Universal Data Model)
Metamodel and extended BON2 correspondence class ParameterBaseImpl : virtual public BON::AtomImpl { public: typedef enum { Integer_DataType_Type, Double_DataType_Type, Character_DataType_Type, Pointer_DataType_Type } DataType_Type; // attribute getters and setters long getSize() ; void setSize( const long val); DataType_Type getDataType(); void setDataType( DataType_Type val); };
Metamodel and extended BON2 correspondence C++ classes BON::Model SF_BON::Processing BonX interpreter SF_BON::Primitive SF_BON::Compound BON::ModelImpl SF_BON::ProcessingImpl SF_BON::PrimitiveImpl SF_BON::CompoundImpl
Component stack - revisited Legend C++ BONX based component (interpreter) pointer to operates on interface BON2 Extension extends Page C++ BON1 based component (interpreter) C++ BON2 based component (interpreter) JAVA BON based component (interpreter) part of GME user-written PageImpl C++ BON1 C++ BON2 JAVA BON Wrapper layer C# Raw .NET component (interpreter) CBuilderModel Model JBuilderModel Implementation layer C++ RawCOM component (interpreter) ModelImpl .NET-COM interop MGA component of GME (Gmodel) IMgaModel* IMgaModel* IMgaModel*
Extended BON2 // declare Processing class, derived from BON::Model DECLARE_ABSTRACT_BONEXTENSION( BON::Model, ProcessingImpl, Processing ); class ProcessingImpl : // implementation class ProcessingImpl virtual public BON::ModelImpl // also derived from ModelImpl { public: // kind and role getters std::set<InputSignal> getInputSignals(); std::set<OutputSignal> getOutputSignals(); std::set<Signal> gets(); std::set<InputParam> getInputParameters(); std::set<OutputParam> getOutputParameters(); std::set<Param> getParameters(); std::set<ParameterBase> geteters(); std::set<ParameterConn> getPC(); // connection };
Extended BON2 // declares automatically class Compound as a subclass of Processing DECLARE_BONEXTENSION( Processing, CompoundImpl, Compound ); class CompoundImpl : // implementation class CompoundImpl public ProcessingImpl // also derived from ProcessingImpl { public: // Compound specific kind and role getters // getChildFCOs() still available since defined in BON::ModelImpl baseclass std::set<Compound> getCompoundParts(); std::set<DataflowConn> getDFC(); std::set<Processing> getParts(); std::set<Primitive> getPrimitiveParts(); ///BUP // add your own members here ///EUP }; Declarations added here are preserved upon several invokations
Metamodel and extended BON2 correspondence class ParameterBaseImpl : virtual public BON::AtomImpl { public: // … (attribute getters) // connectionEnd getters std::multiset<ParameterBase> getParameterConnDsts(); std::multiset<ParameterBase> getParameterConnSrcs(); // connectionLink getters std::set<ParameterConn> getInParameterConnLinks(); std::set<ParameterConn> getOutParameterConnLinks(); std::set<ParameterConn> getParameterConnLinks(); }; Multiplicity of elements >= 1
Casting to the extended types void Component::invokeEx( Project& project, FCO& currentFCO, const std::set<FCO>& setSelectedFCOs, long lParam ) { std::string msg; std::set<FCO>::const_iterator it0 = setSelectedFCOs.begin(); std::set<FCO>::const_iterator itE = setSelectedFCOs.end(); for( ; it0 != itE; ++it0) { // BON::FCO i = *it0; // longer form // SF_BON::Processing proc = i; // copy ctor invoked 2x SF_BON::Processing prc( *it0); // shorter form if( prc) // valid? test { SF_BON::Compound com( prc); if( com) msg += “Compound: “; else msg += “Primitive: “; msg += prc->getName(); msg += "\n"; } } // . . . }
Using Visitor with extended BON2 namespace BON { void Component::invokeEx( Project& project, BON::FCO& curFCO, const std::set<FCO>& selFCOs, long par) { SF_BON::SFVisitor v; Folder rf = project->getRootFolder(); rf->accept( &v); v.showResults(); } } namespace SF_BON { bool SFVisitor::visitCompound( const Compound& object ) { if ( !object) return false; m_results.push_back( Result( object->getName())); return true; } void SFVisitor::showResults() { for( int i = 0; i < m_results.size(); ++i) { /* . . . */ } } }
Using Visitor with extended BON2 class ModelImpl { public: virtual void accept( Visitor* pVisitor); // . . . }; void ModelImpl::accept( Visitor* pVisitor) { FCOSet children = getChildFCOsI(); // visit children first for( FCOSet::iterator it = children.begin(); it != children.end() ; it++ ) { (*it)->accept( pVisitor ); } // visit the node itself pVisitor->visitModel( Model( this ) ); }
Using Visitor with extended BON2 void MyModelImpl::accept( Visitor* pVisitor) { std::set<Kid> children = getKids(); // visit the node itself first pVisitor->visitModel( Model( this ) ); // then visit children for(std::set<Kid>::iterator it=children.begin(); it != children.end() ; it++ ) { (*it)->accept( pVisitor ); } }
BON2 Lightweight: on-demand instantiation STL-based Multiple inheritance allowed: good metamodel conformance domain-specific extension generation from metamodels (BonX interpreter) Includes MON: Meta Object Network Add-ons supported Steep learning curve BON1 Relatively heavyweight Relies on MFC No multiple inheritance allowed Easier to use BON versions compared
Project FCO Atom Model Set Reference Connection Folder Aspect IMgaProject IMgaFCO IMgaAtom IMgaModel, IMgaPart IMgaSet IMgaReference IMgaSimpleConnection IMgaFolder IMgaMetaAspect COM Interpreter Concepts These Interfaces (which stem from the COM architecture) can be used already
COM interpreter called from GME // section of generated RawComponent.cpp file: // This is the main component method for interpereters and plugins. // May als be used in case of invokeable addons STDMETHODIMP RawComponent::InvokeEx( IMgaProject *project, IMgaFCO *currentobj, IMgaFCOs *selectedobjs, long param) { COMTRY { CComBSTR projname; CComBSTR focusname = "<nothing>"; CComPtr<IMgaTerritory> terr; COMTHROW(project->CreateTerritory(NULL, &terr)); COMTHROW(project->BeginTransaction(terr)); try { COMTHROW(project->get_Name(&projname)); if(currentobj) COMTHROW(currentobj->get_Name(&focusname)); long cnt = 0; if( selectedobjs) COMTHROW( selectedobjs->get_Count( &cnt)); for( long i = 1; i <= cnt; ++i) { CComPtr<IMgaFCO> obj_i; COMTHROW( selectedobjs->get_Item( i, &obj_i); CComBSTR nm; COMTHROW( obj_i->get_Name( &nm)); } AfxMessageBox("RAW Com Component --- Plugin!!!! Sample (project: " + CString(projname) + ", focus: " + CString(focusname)); COMTHROW(project->CommitTransaction()); }catch(...) { project->AbortTransaction(); throw; } } COMCATCH(;); }
COM interpreter - transactions interface IMgaProject { [ helpstring("method CreateTerritory (call outside transaction)")] HRESULT CreateTerritory([in] IMgaEventSink *handler, [out] IMgaTerritory **terr, [in, defaultvalue(0)] IMgaEventSink *rwhandler); HRESULT BeginTransaction([in] IMgaTerritory *terr, [in, defaultvalue(TRANSACTION_GENERAL)] transactiontype_enum mode); [ helpstring("method CommitTransaction")] HRESULT CommitTransaction(); [ helpstring("method AbortTransaction")] HRESULT AbortTransaction(); };
interface IMgaModel : IMgaFCO { [ helpstring("method CreateChildObject")] HRESULT CreateChildObject([in] IMgaMetaRole *meta, [out] IMgaFCO **newobj); [ helpstring("method DeriveChildObject")]HRESULT DeriveChildObject([in] IMgaFCO *base, [in] IMgaMetaRole *role, [in] VARIANT_BOOL instance, [out] IMgaFCO **newobj); [propget, helpstring("property ChildDerivedFrom")] HRESULT ChildDerivedFrom([in] IMgaFCO *baseobj, [out, retval] IMgaFCO **pVal); [propget, helpstring("property AspectParts")] HRESULT AspectParts([in] IMgaMetaAspect * asp, [in] unsigned int filter, [out, retval] IMgaParts **pVal); [ helpstring("method CreateSimpleConn")] HRESULT CreateSimpleConn([in] IMgaMetaRole *meta, [in] IMgaFCO *src, [in] IMgaFCO *dst, [in] IMgaFCOs *srcrefs, [in] IMgaFCOs *dstrefs, [out] IMgaFCO **newobj); [ helpstring("method CreateReference")] HRESULT CreateReference([in] IMgaMetaRole *meta, [in] IMgaFCO *target, [out] IMgaFCO **newobj); [ helpstring("method AddInternalConnections")] HRESULT AddInternalConnections([in] IMgaFCOs *inobjs, [out] IMgaFCOs **outobjs); [id(0x551), helpstring("method MoveFCOs")] HRESULT MoveFCOs([in] IMgaFCOs * to_copy, [in] IMgaMetaRoles *destroles, [out] IMgaFCOs **objs); [id(0x552), helpstring("method CopyFCOs")] HRESULT CopyFCOs([in] IMgaFCOs * to_move, [in] IMgaMetaRoles *destroles, [out] IMgaFCOs **objs); COM Interpreter Concepts 2. IMgaModel interface A bit difficult
COM Interpreter Concepts 3. IMgaModel interface Weird string datatype. A CString or std::string class must be converted all the time back and forth // Container methods and properties [id(0x553), propget, helpstring("property ChildFCOs")] HRESULT ChildFCOs([out, retval] IMgaFCOs **pVal); [id(0x554),propget, helpstring("property ChildFCO, return NULL if not found")] HRESULT ChildFCO([in] BSTR name, [out, retval] IMgaFCO **pVal); [id(0x555), helpstring("method GetDescendantFCOs: recursive search")] HRESULT GetDescendantFCOs([in] IMgaFilter *filter, [out] IMgaFCOs **returnset); [id(0x556), helpstring("method GetChildFCOsOfKind: non recursive search")] HRESULT GetChildrenOfKind([in] BSTR kindname, [out] IMgaFCOs **returnset); [id(0x560), propget, helpstring("property ChildRelIDCounter")] HRESULT ChildRelIDCounter([out, retval] long *pVal); [id(0x560), propput, helpstring("property ChildRelIDCounter")] HRESULT ChildRelIDCounter([in] long pVal); };