001package edu.wpi.first.wpilibj.networktables2; 002 003import edu.wpi.first.wpilibj.networktables2.AbstractNetworkTableEntryStore.TableListenerManager; 004import edu.wpi.first.wpilibj.networktables2.connection.*; 005import edu.wpi.first.wpilibj.networktables2.type.*; 006import java.io.*; 007 008 009/** 010 * An entry in a network table 011 * 012 * @author mwills 013 * 014 */ 015public class NetworkTableEntry { 016 /** 017 * the id that represents that an id is unknown for an entry 018 */ 019 public static final char UNKNOWN_ID = (char)0xFFFF; 020 021 private char id; 022 private char sequenceNumber; 023 /** 024 * the name of the entry 025 */ 026 public final String name; 027 /** 028 * the type of the entry 029 */ 030 private NetworkTableEntryType type; 031 private Object value; 032 private volatile boolean isNew = true; 033 private volatile boolean isDirty = false; 034 035 /** 036 * Create a new entry with the given name, type, value, an unknown id and a sequence number of 0 037 * @param name 038 * @param type 039 * @param value 040 */ 041 public NetworkTableEntry(final String name, final NetworkTableEntryType type, final Object value){ 042 this(UNKNOWN_ID, name, (char)0, type, value); 043 } 044 /** 045 * Create a new entry with the given id, name, sequence number, type and value 046 * @param id 047 * @param name 048 * @param sequenceNumber 049 * @param type 050 * @param value 051 */ 052 public NetworkTableEntry(final char id, final String name, final char sequenceNumber, final NetworkTableEntryType type, final Object value){ 053 this.id = id; 054 this.name = name; 055 this.sequenceNumber = sequenceNumber; 056 this.type = type; 057 this.value = value; 058 } 059 060 /** 061 * @return the id of the entry 062 */ 063 public char getId() { 064 return id; 065 } 066 /** 067 * @return the current value of the entry 068 */ 069 public Object getValue(){ 070 return value; 071 } 072 /** 073 * @return the type of the entry 074 */ 075 public NetworkTableEntryType getType(){ 076 return type; 077 } 078 private static final char HALF_OF_CHAR = 32768; 079 /** 080 * set the value of the entry if the given sequence number is greater that the current sequence number 081 * @param newSequenceNumber the sequence number of the incoming entry 082 * @param newValue the new value 083 * @return true if the value was set 084 */ 085 public boolean putValue(final char newSequenceNumber, final Object newValue) { 086 if( (sequenceNumber < newSequenceNumber && newSequenceNumber - sequenceNumber < HALF_OF_CHAR) 087 || (sequenceNumber > newSequenceNumber && sequenceNumber - newSequenceNumber > HALF_OF_CHAR) ){ 088 value = newValue; 089 sequenceNumber = newSequenceNumber; 090 return true; 091 } 092 return false; 093 } 094 /** 095 * force a value and new sequence number upon an entry 096 * @param newSequenceNumber 097 * @param newValue 098 */ 099 public void forcePut(final char newSequenceNumber, final Object newValue) { 100 value = newValue; 101 sequenceNumber = newSequenceNumber; 102 } 103 /** 104 * force a value and new sequence number upon an entry, Will also set the type of the entry 105 * @param newSequenceNumber 106 * @param type 107 * @param newValue 108 */ 109 public void forcePut(final char newSequenceNumber, final NetworkTableEntryType type, final Object newValue) { 110 this.type = type; 111 forcePut(newSequenceNumber, newValue); 112 } 113 114 115 public void makeDirty() { 116 isDirty = true; 117 } 118 public void makeClean() { 119 isDirty = false; 120 } 121 public boolean isDirty(){ 122 return isDirty; 123 } 124 125 /** 126 * Send the value of the entry over the output stream 127 * @param os 128 * @throws IOException 129 */ 130 public void sendValue(final DataOutputStream os) throws IOException{ 131 type.sendValue(value, os); 132 } 133 134 /** 135 * @return the current sequence number of the entry 136 */ 137 public char getSequenceNumber() { 138 return sequenceNumber; 139 } 140 /** 141 * Sets the id of the entry 142 * @param id the id of the entry 143 * @throws IllegalStateException if the entry already has a known id 144 */ 145 public void setId(final char id) throws IllegalStateException{ 146 if(this.id!=UNKNOWN_ID) 147 throw new IllegalStateException("Cannot set the Id of a table entry that already has a valid id"); 148 this.id = id; 149 } 150 /** 151 * clear the id of the entry to unknown 152 */ 153 public void clearId() { 154 id = UNKNOWN_ID; 155 } 156 157 public void send(NetworkTableConnection connection) throws IOException { 158 connection.sendEntryAssignment(this); 159 } 160 public void fireListener(TableListenerManager listenerManager) {//TODO determine best way to handle complex data 161 listenerManager.fireTableListeners(name, value, isNew); 162 isNew = false; 163 } 164 165 public String toString(){ 166 return "Network Table "+type.name+" entry: "+name+": "+(int)getId()+" - "+(int)getSequenceNumber()+" - "+getValue(); 167 } 168 169 170 171}