/******************************************************************************** * * JOrocos Library * * Copyright (c) 2011 * All rights reserved. * * Luca Gherardi * University of Bergamo * Dept. of Information Technology and Mathematics * * ------------------------------------------------------------------------------- * * File: AbstractOrocosConnection.java * Created: Jul 27, 2011 * * Author: <A HREF="mailto:luca.gherardi@unibg.it">Luca Gherardi</A> * * Supervised by: <A HREF="mailto:brugali@unibg.it">Davide Brugali</A> * * In cooperation with: <A HREF="mailto:herman.bruyninckx@mech.kuleuven.be">Herman Bruyninckx</A> * * ------------------------------------------------------------------------------- * * This software is published under a dual-license: GNU Lesser General Public * License LGPL 2.1 and BSD license. The dual-license implies that users of this * code may choose which terms they prefer. * * ------------------------------------------------------------------------------- * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - Neither the name of the University of Bergamo nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License LGPL as * published by the Free Software Foundation, either version 2.1 of the * License, or (at your option) any later version or the BSD license. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License LGPL and the BSD license for more details. * * You should have received a copy of the GNU Lesser General Public * License LGPL and BSD license along with this program. * *******************************************************************************/ package it.unibg.robotics.jorocos.core; import it.unibg.robotics.jorocos.core.OrocosDataPort.OutputPortStatus; import it.unibg.robotics.jorocos.exceptions.WrongUseOfConnectionException; import java.util.Observable; import org.omg.CORBA.TypeCodePackage.BadKind; import RTT.corba.CChannelElement; import RTT.corba.CConnPolicy; /** * The Class AbstractOrocosConnection provides the channel that allows * the operations of writing data on the output ports and reading data * from the input ports. * * @author <A HREF="mailto:luca.gherardi@unibg.it">Luca Gherardi</A> * @version 1.0 * @since August 2011 */ public abstract class AbstractOrocosConnection extends Observable{ /** * The Enum ConnectionType defines the available connections. */ public enum ConnectionType{ /** * The DATA connection. * On a data connection, the reader will have only access to the last written value. */ DATA, /** * The BUFFER connection. * On a buffered connection, a size number of elements can be stored until the reader reads them. */ BUFFER } /** * The Enum LockPolocy defines the available lock policies. */ public enum LockPolicy{ /** * The USYNC connection policy defines how locking is done in the connection. * UNSYNC means there's no synchronization at all (not thread safe). */ USYNC, /** * The LOCKED connection policy defines how locking is done in the connection. * LOCKED uses mutexes. */ LOCKED, /** * The LOCK FREE connection policy defines how locking is done in the connection. * LOCK_FREE uses a lock free method. */ LOCK_FREE } /** * One of the port of this connection. The other port is not explicitly defined and is * represented by the client that creates this connection */ protected OrocosDataPort port; /** * The connection type. */ protected ConnectionType connectionType; /** The connection lock policy. */ protected CConnPolicy connectionPolicy; /** * A pointer to the channel which is modeled by this connection. * */ protected CChannelElement channelElement; /** * Returns the Orocos port, see the variable OrocosDataPort. * * @return the the Orocos port which is part of the connection */ public OrocosDataPort getPort(){ return port; } /** * Returns the connection type. * * @return the connection type */ public ConnectionType getConnectionType(){ return connectionType; } /** * Tries to read a data from the data port. * This method works only if the Orocos data port is an input port. * * @return the result of the reading operation * @throws WrongUseOfConnectionException the wrong use of connection exception */ abstract public PortReadingResult readData() throws WrongUseOfConnectionException; /** * Tries to write a data on the data port. * This method works only if the Orocos data port is an output port. * * @param value the data that has to be written * @return true, if successful. False otherwise, e.g. if value is an instance of a different type * with respect to the data port type. * @throws WrongUseOfConnectionException the wrong use of connection exception * @throws BadKind */ abstract public boolean writeData(Object value) throws WrongUseOfConnectionException; /** * Start the publish subscriber thread which periodically tries to read from an output port * and notifies the client when new data are available. * * @param periodMs defines the frequency with which the availability * of new data on the port will be checked (it is expressed as period in milliseconds). */ public void initPublishSubscriber(final int periodMs){ Thread thread = new Thread() { public void run() { PortReadingResult or; // check if the observer is still there // we have no more than 1 observer while(countObservers()>0){ try { or = readData(); while(or.getStatus() == OutputPortStatus.NO_DATA || or.getStatus() == OutputPortStatus.OLD_DATA){ Thread.sleep(periodMs); or = readData(); } // if a new data is availbale notify the observer setChanged(); notifyObservers(new OrocosPortEvent(port.getName(), or.getValue())); } catch(InterruptedException e){ e.printStackTrace(); } catch (WrongUseOfConnectionException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }; thread.start(); } }