001/*
002 * Copyright (c) 2010 The Regents of the University of California.
003 * All rights reserved.
004 *
005 * '$Author: crawl $'
006 * '$Date: 2015-08-24 22:48:48 +0000 (Mon, 24 Aug 2015) $' 
007 * '$Revision: 33634 $'
008 * 
009 * Permission is hereby granted, without written agreement and without
010 * license or royalty fees, to use, copy, modify, and distribute this
011 * software and its documentation for any purpose, provided that the above
012 * copyright notice and the following two paragraphs appear in all copies
013 * of this software.
014 *
015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
019 * SUCH DAMAGE.
020 *
021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
026 * ENHANCEMENTS, OR MODIFICATIONS.
027 *
028 */
029
030package org.ROADnet;
031
032import com.brtt.antelope.Orb;
033import com.brtt.antelope.OrbPacket;
034import com.brtt.antelope.OrbRawPacket;
035
036import ptolemy.actor.TypedAtomicActor;
037import ptolemy.actor.TypedIOPort;
038import ptolemy.data.ObjectToken;
039import ptolemy.data.StringToken;
040import ptolemy.data.expr.Parameter;
041import ptolemy.data.type.BaseType;
042import ptolemy.kernel.CompositeEntity;
043import ptolemy.kernel.util.IllegalActionException;
044import ptolemy.kernel.util.NameDuplicationException;
045
046/**
047 * This actor connects to an Antelope ORB and provides a stream of
048 * {@link OrbPacket} objects to Ptolemy, delivered as {@link ObjectToken}s. This
049 * is part of an experiment to provide an interface to Antelope that closely
050 * follows the traditional programming interface, as opposed to a more abstract
051 * interface that would provide "waveforms" or "database tuples" without
052 * explicitly dealing with the mechanics of orb packets.
053 * 
054 * @see OrbWaveformSource
055 * @see OrbImageSource
056 * @author Tobin Fricke, University of California
057 * @version $Id: OrbPacketObjectSource.java 33634 2015-08-24 22:48:48Z crawl $
058 */
059
060public class OrbPacketObjectSource extends TypedAtomicActor {
061
062        public OrbPacketObjectSource(CompositeEntity container, String name)
063                        throws NameDuplicationException, IllegalActionException {
064                super(container, name);
065
066                output = new TypedIOPort(this, "output", false, true);
067                output.setMultiport(true);
068                output.setTypeEquals(BaseType.OBJECT);
069
070                input = new TypedIOPort(this, "input", true, false);
071                input.setMultiport(true);
072                input.setTypeEquals(BaseType.OBJECT);
073
074                orbname = new Parameter(this, "orbname");
075                srcname = new Parameter(this, "srcname");
076
077                orbname.setTypeEquals(BaseType.STRING);
078                srcname.setTypeEquals(BaseType.STRING);
079        }
080
081        /** Connect to the ORB */
082
083        public void initialize() throws IllegalActionException {
084                System.out.println("OrbSource: initialize");
085                try {
086                        super.initialize();
087
088                        String orb = StringToken.convert(orbname.getToken()).stringValue();
089                        String src = StringToken.convert(srcname.getToken()).stringValue();
090
091                        // how should we handle permissions?
092
093                        _orb = new Orb(orb, "rw");
094                        _orb.select(src);
095                        _orb.after(0);
096                } catch (Exception e) {
097                        // ...
098                }
099
100        }
101
102        /**
103         * Reap one packet from the ORB, and broadcast it to the output port as an
104         * ObjectToken holding an OrbPacket object.
105         */
106
107        public void fire() throws IllegalActionException {
108                super.fire();
109                try {
110
111                        // first take care of any inputs
112
113                        for (int c = 0; c < input.getWidth(); c++) {
114                                while (input.hasToken(c)) {
115                                        ObjectToken token = (ObjectToken) (input.get(c));
116
117                                        // fixme: we should actually check the following
118
119                                        OrbPacket packet = (OrbPacket) (token.getValue());
120
121                                        if (!(packet instanceof OrbRawPacket)) {
122                                                packet = packet.stuff();
123                                        }
124
125                                        _orb.put((OrbRawPacket) packet);
126                                }
127                        }
128
129                        // now take care of the outputs
130
131                        if (output.numberOfSinks() > 0) {
132
133                                // we have to decide whether this should block or not --
134                                // depends on domain?
135
136                                OrbPacket pkt = _orb.reap(true);
137
138                                output.broadcast(new ObjectToken(pkt));
139                        }
140
141                } catch (Exception e) {
142                        throw new IllegalActionException(this, e.getMessage());
143                }
144
145        }
146
147        /**
148         * The name of the Antelope ORB to connect to, in the format
149         * "hostname:port".
150         */
151
152        public Parameter orbname;
153
154        /** The sourcename to request from the ORB. */
155
156        public Parameter srcname;
157
158        /**
159         * Packets reaped from the ORB will appear on this port as Ptolemy
160         * ObjectTokens.
161         */
162
163        public TypedIOPort output;
164        public TypedIOPort input;
165
166        private Orb _orb;
167
168}