001package edu.wpi.first.wpilibj.networktables2; 002 003import edu.wpi.first.wpilibj.networktables2.AbstractNetworkTableEntryStore.TableListenerManager; 004import edu.wpi.first.wpilibj.networktables2.client.*; 005import edu.wpi.first.wpilibj.networktables2.type.*; 006import edu.wpi.first.wpilibj.networktables2.util.*; 007import edu.wpi.first.wpilibj.tables.*; 008 009/** 010 * represents a node (either a client or a server) in a network tables 2.0 011 * <br> 012 * implementers of the class must ensure that they call {@link #init(NetworkTableTransactionPool, AbstractNetworkTableEntryStore)} before calling any other methods on this class 013 * 014 * @author Mitchell 015 * 016 */ 017public abstract class NetworkTableNode implements TableListenerManager, ClientConnectionListenerManager, IRemote{ 018 019 protected AbstractNetworkTableEntryStore entryStore; 020 021 022 protected final void init(AbstractNetworkTableEntryStore entryStore) { 023 this.entryStore = entryStore; 024 } 025 026 /** 027 * @return the entry store used by this node 028 */ 029 public AbstractNetworkTableEntryStore getEntryStore(){ 030 return entryStore; 031 } 032 033 034 035 public void putBoolean(String name, boolean value){ 036 putValue(name, DefaultEntryTypes.BOOLEAN, value?Boolean.TRUE:Boolean.FALSE); 037 } 038 public boolean getBoolean(String name) throws TableKeyNotDefinedException{ 039 NetworkTableEntry entry = entryStore.getEntry(name); 040 if(entry==null) 041 throw new TableKeyNotDefinedException(name); 042 return ((Boolean)entry.getValue()).booleanValue(); 043 } 044 045 public void putDouble(String name, double value){ 046 putValue(name, DefaultEntryTypes.DOUBLE, new Double(value));//TODO don't make a new double every time 047 } 048 public double getDouble(String name) throws TableKeyNotDefinedException{ 049 NetworkTableEntry entry = entryStore.getEntry(name); 050 if(entry==null) 051 throw new TableKeyNotDefinedException(name); 052 return ((Double)entry.getValue()).doubleValue(); 053 } 054 055 public void putString(String name, String value){ 056 putValue(name, DefaultEntryTypes.STRING, value); 057 } 058 public String getString(String name) throws TableKeyNotDefinedException{ 059 NetworkTableEntry entry = entryStore.getEntry(name); 060 if(entry==null) 061 throw new TableKeyNotDefinedException(name); 062 return ((String)entry.getValue()); 063 } 064 065 public void putComplex(String name, ComplexData value){ 066 putValue(name, value.getType(), value); 067 } 068 069 public void retrieveValue(String name, Object externalData) throws TableKeyNotDefinedException{ 070 synchronized(entryStore){ 071 NetworkTableEntry entry = entryStore.getEntry(name); 072 if(entry==null) 073 throw new TableKeyNotDefinedException(name); 074 NetworkTableEntryType entryType = entry.getType(); 075 if(!(entryType instanceof ComplexEntryType)) 076 throw new TableKeyExistsWithDifferentTypeException(name, entryType, "Is not a complex data type"); 077 ComplexEntryType complexType = (ComplexEntryType)entryType; 078 complexType.exportValue(name, entry.getValue(), externalData); 079 } 080 } 081 082 083 084 085 public void putValue(String name, Object value) throws IllegalArgumentException{ 086 if(value instanceof Double){ 087 putValue(name, DefaultEntryTypes.DOUBLE, value); 088 } else if (value instanceof String){ 089 putValue(name, DefaultEntryTypes.STRING, value); 090 } else if(value instanceof Boolean){ 091 putValue(name, DefaultEntryTypes.BOOLEAN, value); 092 } else if(value instanceof ComplexData){ 093 putValue(name, ((ComplexData)value).getType(), value); 094 } else if(value==null) { 095 throw new NullPointerException("Cannot put a null value into networktables"); 096 } else { 097 throw new IllegalArgumentException("Invalid Type"); 098 } 099 } 100 101 /** 102 * Put a value with a specific network table type 103 * @param name the name of the entry to associate with the given value 104 * @param type the type of the entry 105 * @param value the actual value of the entry 106 */ 107 public void putValue(String name, NetworkTableEntryType type, Object value){ 108 if(type instanceof ComplexEntryType){ 109 synchronized(entryStore){//must sync because use get 110 ComplexEntryType entryType = (ComplexEntryType)type; 111 NetworkTableEntry entry = entryStore.getEntry(name); 112 if(entry!=null) 113 entryStore.putOutgoing(entry, entryType.internalizeValue(entry.name, value, entry.getValue())); 114 else 115 entryStore.putOutgoing(name, type, entryType.internalizeValue(name, value, null)); 116 } 117 } 118 else 119 entryStore.putOutgoing(name, type, value); 120 } 121 122 public void putValue(NetworkTableEntry entry, Object value){ 123 if(entry.getType() instanceof ComplexEntryType){ 124 synchronized(entryStore){//must sync because use get 125 ComplexEntryType entryType = (ComplexEntryType)entry.getType(); 126 entryStore.putOutgoing(entry, entryType.internalizeValue(entry.name, value, entry.getValue())); 127 } 128 } 129 else 130 entryStore.putOutgoing(entry, value); 131 } 132 133 public Object getValue(String name) throws TableKeyNotDefinedException{//TODO don't allow get of complex types 134 synchronized(entryStore){ 135 NetworkTableEntry entry = entryStore.getEntry(name); 136 if(entry == null) 137 throw new TableKeyNotDefinedException(name); 138 return entry.getValue(); 139 } 140 } 141 142 143 /** 144 * @param key the key to check for existence 145 * @return true if the table has the given key 146 */ 147 public boolean containsKey(final String key){ 148 return entryStore.getEntry(key)!=null; 149 } 150 151 /** 152 * close all networking activity related to this node 153 */ 154 public abstract void close(); 155 156 private final List remoteListeners = new List(); 157 public void addConnectionListener(IRemoteConnectionListener listener, boolean immediateNotify) { 158 remoteListeners.add(listener); 159 if(isConnected()) 160 listener.connected(this); 161 else 162 listener.disconnected(this); 163 } 164 public void removeConnectionListener(IRemoteConnectionListener listener) { 165 remoteListeners.remove(listener); 166 } 167 public void fireConnectedEvent(){ 168 for(int i = 0; i<remoteListeners.size(); ++i) 169 ((IRemoteConnectionListener)remoteListeners.get(i)).connected(this); 170 } 171 public void fireDisconnectedEvent(){ 172 for(int i = 0; i<remoteListeners.size(); ++i) 173 ((IRemoteConnectionListener)remoteListeners.get(i)).disconnected(this); 174 } 175 176 177 private final List tableListeners = new List(); 178 public void addTableListener(ITableListener listener, boolean immediateNotify) { 179 tableListeners.add(listener); 180 if(immediateNotify) 181 entryStore.notifyEntries(null, listener); 182 } 183 public void removeTableListener(ITableListener listener) { 184 tableListeners.remove(listener); 185 } 186 public void fireTableListeners(String key, Object value, boolean isNew){ 187 for(int i = 0; i<tableListeners.size(); ++i) 188 ((ITableListener)tableListeners.get(i)).valueChanged(null, key, value, isNew); 189 } 190}