org.robokind.api.motion.servos.AbstractServoController Maven / Gradle / Ivy
/*
* Copyright 2011 Hanson Robokind LLC.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.robokind.api.motion.servos;
import org.robokind.api.motion.servos.utils.ConnectionStatus;
import java.beans.PropertyChangeEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.robokind.api.common.property.PropertyChangeAction;
import org.robokind.api.common.property.PropertyChangeMonitor;
import org.robokind.api.common.property.PropertyChangeNotifier;
import org.robokind.api.motion.servos.config.ServoConfig;
import org.robokind.api.motion.servos.config.ServoControllerConfig;
/**
* Provides common functionality for ServoControllers.
*
* @param Id Type use by this ServoController's Servos
* @param Servo type used by this AbstractServoController
* @param ServoControllerConfig type used
* @param ServoConfig type used by S and Conf
*
* @author Matthew Stevenson
*/
public abstract class AbstractServoController<
IdType,
ServoConf extends ServoConfig,
S extends Servo,
ControllerConf extends ServoControllerConfig
> extends PropertyChangeNotifier implements
ServoController{
private final static Logger theLogger = Logger.getLogger(AbstractServoController.class.getName());
private ServoController.Id myServoControllerId;
/**
* ServoController's Confgiuration parameters.
*/
protected ControllerConf myConfig;
/**
* List of the Coontroller's Servos.
*/
protected List myServos;
/**
* Map of the Controller's Servos and their ids.
*/
protected Map, S> myServoMap;
/**
* The Controller's ConnectionStatus.
*/
protected ConnectionStatus myConnectionStatus;
/**
* The Controllers's PropertyChangeMonitor to listen for changes in Servos
* and configs.
*/
protected PropertyChangeMonitor myChangeMonitor;
/**
* Creates a new AbstractServoController from the given config.
* @param config the Controller's cofig
*/
public AbstractServoController(ControllerConf config){
if(config == null){
throw new NullPointerException();
}
ServoController.Id id = config.getServoControllerId();
if(id == null){
throw new NullPointerException();
}
myServoControllerId = id;
initPropertyChangeMontior();
myConfig = config;
myConfig.addPropertyChangeListener(myChangeMonitor);
for(ServoConfig sc : myConfig.getServoConfigs().values()){
sc.addPropertyChangeListener(myChangeMonitor);
}
myConnectionStatus = ConnectionStatus.DISCONNECTED;
myServoMap = new HashMap();
myServos = new ArrayList();
}
private void initPropertyChangeMontior() {
myChangeMonitor = new PropertyChangeMonitor();
myChangeMonitor.addAction(ServoControllerConfig.PROP_SERVO_ADD,
new PropertyChangeAction() {
@Override
protected void run(PropertyChangeEvent event) {
ServoConf config = (ServoConf)event.getNewValue();
addingServo(config);
}
});
myChangeMonitor.addAction(ServoControllerConfig.PROP_SERVO_REMOVE,
new PropertyChangeAction() {
@Override
protected void run(PropertyChangeEvent event) {
ServoConf config = (ServoConf)event.getNewValue();
removingServo(servoId(config.getServoId()));
}
});
myChangeMonitor.addAction(ServoConfig.PROP_ID,
new PropertyChangeAction() {
@Override
protected void run(PropertyChangeEvent event) {
changeServoId((ServoId)event.getOldValue(),
(ServoId)event.getNewValue());
}
});
}
@Override
public final ServoController.Id getId(){
return myServoControllerId;
}
/**
* Called when a new Servo is being added. The overriding method
* should make the Servo available from the given ServoConfig.
*
* @param config
* @return a new Servo from the ServoConfig
*/
protected abstract S connectServo(ServoConf config);
/**
* Called when a Servo is being removed. The overriding method should
* remove references to the Servo from the ServoController.
* @param id Servo's id
* @return true if successful
*/
protected abstract boolean disconnectServo(ServoId id);
/**
* Add a Servo the ServoController.
* @param config Servo's configuration parameters
*/
public void addServo(ServoConf config){
myConfig.addServoConfig(config);
}
/**
* Remove a Servo from the ServoController.
* @param servo Servo to remove
*/
public void removeServo(S servo){
myConfig.removeServoConfig(servo.getConfig());
}
/**
* Set the ServoController's ConnectionStatus.
* @param status new ConnectionStatus
*/
protected void setConnectStatus(ConnectionStatus status){
ConnectionStatus oldStatus = myConnectionStatus;
myConnectionStatus = status;
firePropertyChange(PROP_CONNECTION_STATUS, oldStatus, status);
}
@Override
public S getServo(ServoId id) {
if(ConnectionStatus.CONNECTED != myConnectionStatus){
theLogger.log(Level.WARNING, "Must be connected to access Servos");
return null;
}
S Servo = myServoMap.get(id);
return Servo;
}
@Override
public List getServos() {
if(ConnectionStatus.CONNECTED != myConnectionStatus){
theLogger.log(Level.WARNING, "Must be connected to access Servos");
return Collections.EMPTY_LIST;
}
return myServos;
}
@Override
public boolean containsIds(Set> ids) {
if(ConnectionStatus.CONNECTED != myConnectionStatus){
theLogger.log(Level.WARNING, "Must be connected to access Servos");
return false;
}
return myServoMap.keySet().containsAll(ids);
}
@Override
public boolean containsId(ServoId id) {
if(ConnectionStatus.CONNECTED != myConnectionStatus){
theLogger.log(Level.WARNING, "Must be connected to access Servos");
return false;
}
return myServoMap.containsKey(id);
}
@Override
public ConnectionStatus getConnectionStatus(){
return myConnectionStatus;
}
/**
* Called when a Servo is added to the underlying ServoControllerConfig.
* @param config the Servo's configuration parameters
*/
protected void addingServo(ServoConf config){
S servo = connectServo(config);
if(servo == null){
return;
}
myServos.add(servo);
myServoMap.put(servoId(servo.getId()), servo);
servo.getConfig().addPropertyChangeListener(myChangeMonitor);
firePropertyChange(PROP_SERVO_ADD, null, servo);
}
/**
* Called when a Servo is removed from the underlying ServoControllerConfig.
* @param id id of the Servo being removed
*/
protected void removingServo(ServoId id){
if(!disconnectServo(id)){
return;
}
S servo = myServoMap.remove(id);
myServos.remove(servo);
servo.getConfig().removePropertyChangeListener(myChangeMonitor);
firePropertyChange(PROP_SERVO_REMOVE, null, servo);
}
/**
* Called when the id of a Servo changes in the underlying
* ServoControllerConfig.
* @param oldId old id
* @param newId new id
*/
protected void changeServoId(ServoId oldId, ServoId newId){
S servo = myServoMap.remove(oldId);
myServoMap.put(newId, servo);
firePropertyChange(PROP_SERVOS, null, myServoMap);
}
@Override
public ControllerConf getConfig(){
return myConfig;
}
/**
* Creates a ServoController.ServoId from this ServoController's Id and a
* Servo's Id
* @param id Servo Id to use
* @return ServoController.ServoId containing this ServoController's Id and
* the give Servo Id
*/
protected ServoId servoId(IdType id){
if(id == null){
throw new NullPointerException();
}
return new ServoController.ServoId(myServoControllerId, id);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy