/* An actor that executes compiled embedded code. Copyright (c) 2007-2014 The Regents of the University of California. All rights reserved. Permission is hereby granted, without written agreement and without license or royalty fees, to use, copy, modify, and distribute this software and its documentation for any purpose, provided that the above copyright notice and the following two paragraphs appear in all copies of this software. IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. PT_COPYRIGHT_VERSION_2 COPYRIGHTENDKEY */ package ptolemy.cg.lib; import java.lang.reflect.Constructor; import java.util.List; import ptolemy.actor.Director; import ptolemy.actor.TypedAtomicActor; import ptolemy.actor.TypedIOPort; import ptolemy.actor.TypedIORelation; import ptolemy.domains.sdf.kernel.SDFDirector; import ptolemy.kernel.CompositeEntity; import ptolemy.kernel.util.IllegalActionException; import ptolemy.kernel.util.InternalErrorException; import ptolemy.kernel.util.NameDuplicationException; import ptolemy.kernel.util.Settable; import ptolemy.kernel.util.StringAttribute; /////////////////////////////////////////////////////////////////// //// EmbeddedCodeActor /** An actor of this class executes compiled embedded code. FIXME: Currently, it seems this only works with embedded Java code, but in theory it should work with any embedded code that can be executed within Java.
To use this actor within Vergil, double click on the actor and insert Java code into the code templates, as indicated by the sample template. Normally you will also need to add ports to the actor. You may need to set the types of these ports as well.
This actor is actually a composite actor that contains a single
embedded actor that actually executes the generated code. The
reason for the extra level of hierarchy is so that the director
adapter code that handles conversion and transport across the boundary
can be consolidated in one place. In its preinitialize() method,
this actor will create an instance of whatever director is
in charge of executing it. The presumption is that that director
has a code generation adapter that knows how to transport data
from the simulation world in Java to the generated code world
within.
@author Bert Rodiers, Gang Zhou, Edward A. Lee, Jia Zou
@version $Id: EmbeddedCodeActor.java 70402 2014-10-23 00:52:20Z cxh $
@since Ptolemy II 10.0
@Pt.ProposedRating Red (zgang)
@Pt.AcceptedRating Red (zgang)
*/
public class EmbeddedCodeActor extends CompiledCompositeActor {
/** Construct an actor with the given container and name.
* In addition to invoking the base class constructor,
* create the embeddedCode parameter, and initialize
* it to provide an empty template.
* @param container The container.
* @param name The name of this actor.
* @exception NameDuplicationException If the container already
* has an actor with this name.
* @exception IllegalActionException If the actor cannot be contained
* by the proposed container.
*/
public EmbeddedCodeActor(CompositeEntity container, String name)
throws NameDuplicationException, IllegalActionException {
super(container, name);
embeddedCode = new StringAttribute(this, "embeddedCode");
// Set the visibility to expert, as casual users should
// not see the Java code. This is particularly true if one
// installs an actor that is an instance of this with
// particular Java code in the library.
embeddedCode.setVisibility(Settable.EXPERT);
// initialize the code to provide a template for identity function:
//
// /***fileDependencies***/
// /**/
//
// /***preinitBlock***/
// /**/
//
// /***initBlock***/
// /**/
//
// /***fireBlock***/
// // Assuming you have added an input port named "input"
// // and an output port named "output", then the following
// // line results in the input being copied to the output.
// $put(output, $get(input));
// /**/
//
// /***wrapupBlock***/
// /**/
//
String code = "";
code = code + _getFileDependencies();
code = code + _getPreinitBlock();
code = code + _getInitBlock();
code = code + _getFireBlock();
code = code + _getWrapupBlock();
embeddedCode.setExpression(code);
_attachText("_iconDescription", "\n");
// For embeddedJavaActor, there is only embedded Java code specifying its
// functionality.
executeEmbeddedCode.setExpression("true");
// In preinitialize(), this actor will create a director that matches
// the class of its enclosing director. However, we need it to have
// a director at all times, so we set a generic director here.
new Director(this, "Director");
}
///////////////////////////////////////////////////////////////////
//// ports and parameters ////
/** The Java code that specifies the function of this actor. The
* default value is the code necessary to implement a identity
* function.
*/
public StringAttribute embeddedCode;
///////////////////////////////////////////////////////////////////
//// public methods ////
/** Create the embedded actor and add ports to it.
*/
@Override
public void preinitialize() throws IllegalActionException {
Director executiveDirector = getExecutiveDirector();
Director localDirector = getDirector();
if (localDirector == null
|| !localDirector.getClass().equals(
executiveDirector.getClass())) {
if (localDirector != null) {
try {
localDirector.setContainer(null);
} catch (NameDuplicationException e) {
throw new InternalErrorException(e);
}
}
// The inside director should match the outside director.
// Use reflection to create a matching instance.
Class directorClass = getExecutiveDirector().getClass();
Constructor> constructor = null;
try {
constructor = directorClass.getConstructor(new Class[] {
CompositeEntity.class, String.class });
} catch (Exception ex) {
throw new IllegalActionException(this, ex,
"Cannot create an instance of the enclosing director class: "
+ directorClass);
}
try {
constructor.newInstance(new Object[] { this,
getExecutiveDirector().getName() });
localDirector = getDirector();
if (localDirector instanceof SDFDirector) {
// Needed for $PTII/bin/vergil ptolemy/cg/lib/test/auto/Scale_c.xml
// See "SDF director iterations parameter default of 0 is unfriendly"
// http://bugzilla.ecoinformatics.org/show_bug.cgi?id=5546
((SDFDirector) localDirector).iterations.setExpression("0");
}
} catch (Exception ex) {
throw new IllegalActionException(this, ex,
"Failed to instantiate the enclosing director class: "
+ directorClass);
}
}
try {
setEmbeddedActor();
int i = 0;
for (TypedIOPort port : (List