001/*----------------------------------------------------------------------------*/
002/* Copyright (c) FIRST 2017-2018. All Rights Reserved.                        */
003/* Open Source Software - may be modified and shared by FRC teams. The code   */
004/* must be accompanied by the FIRST BSD license file in the root directory of */
005/* the project.                                                               */
006/*----------------------------------------------------------------------------*/
007
008package edu.wpi.first.networktables;
009
010import java.nio.ByteBuffer;
011import java.util.function.Consumer;
012
013/**
014 * NetworkTables Entry
015 */
016public final class NetworkTableEntry {
017  /**
018   * Flag values (as returned by {@link #getFlags()}).
019   */
020  public static final int kPersistent = 0x01;
021
022  /**
023   * Construct from native handle.
024   * @param inst Instance
025   * @param handle Native handle
026   */
027  public NetworkTableEntry(NetworkTableInstance inst, int handle) {
028    m_inst = inst;
029    m_handle = handle;
030  }
031
032  /**
033   * Determines if the native handle is valid.
034   * @return True if the native handle is valid, false otherwise.
035   */
036  public boolean isValid() {
037    return m_handle != 0;
038  }
039
040  /**
041   * Gets the native handle for the entry.
042   * @return Native handle
043   */
044  public int getHandle() {
045    return m_handle;
046  }
047
048  /**
049   * Gets the instance for the entry.
050   * @return Instance
051   */
052  public NetworkTableInstance getInstance() {
053    return m_inst;
054  }
055
056  /**
057   * Determines if the entry currently exists.
058   * @return True if the entry exists, false otherwise.
059   */
060  public boolean exists() {
061    return NetworkTablesJNI.getType(m_handle) != 0;
062  }
063
064  /**
065   * Gets the name of the entry (the key).
066   * @return the entry's name
067   */
068  public String getName() {
069    return NetworkTablesJNI.getEntryName(m_handle);
070  }
071
072  /**
073   * Gets the type of the entry.
074   * @return the entry's type
075   */
076  public NetworkTableType getType() {
077    return NetworkTableType.getFromInt(NetworkTablesJNI.getType(m_handle));
078  }
079
080  /**
081   * Returns the flags.
082   * @return the flags (bitmask)
083   */
084  public int getFlags() {
085    return NetworkTablesJNI.getEntryFlags(m_handle);
086  }
087
088  /**
089   * Gets the last time the entry's value was changed.
090   * @return Entry last change time
091   */
092  public long getLastChange() {
093    return NetworkTablesJNI.getEntryLastChange(m_handle);
094  }
095
096  /**
097   * Gets combined information about the entry.
098   * @return Entry information
099   */
100  public EntryInfo getInfo() {
101    return NetworkTablesJNI.getEntryInfoHandle(m_inst, m_handle);
102  }
103
104  /**
105   * Gets the entry's value.
106   * Returns a value with type NetworkTableType.kUnassigned if the value
107   * does not exist.
108   * @return the entry's value
109   */
110  public NetworkTableValue getValue() {
111    return NetworkTablesJNI.getValue(m_handle);
112  }
113
114  /**
115   * Gets the entry's value as a boolean. If the entry does not exist or is of
116   * different type, it will return the default value.
117   * @param defaultValue the value to be returned if no value is found
118   * @return the entry's value or the given default value
119   */
120  public boolean getBoolean(boolean defaultValue) {
121    return NetworkTablesJNI.getBoolean(m_handle, defaultValue);
122  }
123
124  /**
125   * Gets the entry's value as a double. If the entry does not exist or is of
126   * different type, it will return the default value.
127   * @param defaultValue the value to be returned if no value is found
128   * @return the entry's value or the given default value
129   */
130  public double getDouble(double defaultValue) {
131    return NetworkTablesJNI.getDouble(m_handle, defaultValue);
132  }
133
134  /**
135   * Gets the entry's value as a double. If the entry does not exist or is of
136   * different type, it will return the default value.
137   * @param defaultValue the value to be returned if no value is found
138   * @return the entry's value or the given default value
139   */
140  public Number getNumber(Number defaultValue) {
141    return NetworkTablesJNI.getDouble(m_handle, defaultValue.doubleValue());
142  }
143
144  /**
145   * Gets the entry's value as a string. If the entry does not exist or is of
146   * different type, it will return the default value.
147   * @param defaultValue the value to be returned if no value is found
148   * @return the entry's value or the given default value
149   */
150  public String getString(String defaultValue) {
151    return NetworkTablesJNI.getString(m_handle, defaultValue);
152  }
153
154  /**
155   * Gets the entry's value as a raw value (byte array). If the entry does not
156   * exist or is of different type, it will return the default value.
157   * @param defaultValue the value to be returned if no value is found
158   * @return the entry's value or the given default value
159   */
160  public byte[] getRaw(byte[] defaultValue) {
161    return NetworkTablesJNI.getRaw(m_handle, defaultValue);
162  }
163
164  /**
165   * Gets the entry's value as a boolean array. If the entry does not exist
166   * or is of different type, it will return the default value.
167   * @param defaultValue the value to be returned if no value is found
168   * @return the entry's value or the given default value
169   */
170  public boolean[] getBooleanArray(boolean[] defaultValue) {
171    return NetworkTablesJNI.getBooleanArray(m_handle, defaultValue);
172  }
173
174  /**
175   * Gets the entry's value as a boolean array. If the entry does not exist
176   * or is of different type, it will return the default value.
177   * @param defaultValue the value to be returned if no value is found
178   * @return the entry's value or the given default value
179   */
180  public Boolean[] getBooleanArray(Boolean[] defaultValue) {
181    return NetworkTableValue.fromNative(NetworkTablesJNI.getBooleanArray(m_handle, NetworkTableValue.toNative(defaultValue)));
182  }
183
184  /**
185   * Gets the entry's value as a double array. If the entry does not exist
186   * or is of different type, it will return the default value.
187   * @param defaultValue the value to be returned if no value is found
188   * @return the entry's value or the given default value
189   */
190  public double[] getDoubleArray(double[] defaultValue) {
191    return NetworkTablesJNI.getDoubleArray(m_handle, defaultValue);
192  }
193
194  /**
195   * Gets the entry's value as a double array. If the entry does not exist
196   * or is of different type, it will return the default value.
197   * @param defaultValue the value to be returned if no value is found
198   * @return the entry's value or the given default value
199   */
200  public Double[] getDoubleArray(Double[] defaultValue) {
201    return NetworkTableValue.fromNative(NetworkTablesJNI.getDoubleArray(m_handle, NetworkTableValue.toNative(defaultValue)));
202  }
203
204  /**
205   * Gets the entry's value as a double array. If the entry does not exist
206   * or is of different type, it will return the default value.
207   * @param defaultValue the value to be returned if no value is found
208   * @return the entry's value or the given default value
209   */
210  public Number[] getNumberArray(Number[] defaultValue) {
211    return NetworkTableValue.fromNative(NetworkTablesJNI.getDoubleArray(m_handle, NetworkTableValue.toNative(defaultValue)));
212  }
213
214  /**
215   * Gets the entry's value as a string array. If the entry does not exist
216   * or is of different type, it will return the default value.
217   * @param defaultValue the value to be returned if no value is found
218   * @return the entry's value or the given default value
219   */
220  public String[] getStringArray(String[] defaultValue) {
221    return NetworkTablesJNI.getStringArray(m_handle, defaultValue);
222  }
223
224  /**
225   * Sets the entry's value if it does not exist.
226   * @param defaultValue the default value to set
227   * @return False if the entry exists with a different type
228   * @throws IllegalArgumentException if the value is not a known type
229   */
230  public boolean setDefaultValue(Object defaultValue) {
231    if (defaultValue instanceof NetworkTableValue) {
232      long time = ((NetworkTableValue)defaultValue).getTime();
233      Object o = ((NetworkTableValue)defaultValue).getValue();
234      switch (((NetworkTableValue)defaultValue).getType()) {
235        case kBoolean:
236          return NetworkTablesJNI.setDefaultBoolean(m_handle, time, ((Boolean)o).booleanValue());
237        case kDouble:
238          return NetworkTablesJNI.setDefaultDouble(m_handle, time, ((Number)o).doubleValue());
239        case kString:
240          return NetworkTablesJNI.setDefaultString(m_handle, time, (String)o);
241        case kRaw:
242          return NetworkTablesJNI.setDefaultRaw(m_handle, time, (byte[])o);
243        case kBooleanArray:
244          return NetworkTablesJNI.setDefaultBooleanArray(m_handle, time, (boolean[])o);
245        case kDoubleArray:
246          return NetworkTablesJNI.setDefaultDoubleArray(m_handle, time, (double[])o);
247        case kStringArray:
248          return NetworkTablesJNI.setDefaultStringArray(m_handle, time, (String[])o);
249        case kRpc:
250          // TODO
251        default:
252          return true;
253      }
254    } else if (defaultValue instanceof Boolean) {
255      return setDefaultBoolean((Boolean)defaultValue);
256    } else if (defaultValue instanceof Number) {
257      return setDefaultNumber((Number)defaultValue);
258    } else if (defaultValue instanceof String) {
259      return setDefaultString((String)defaultValue);
260    } else if (defaultValue instanceof byte[]) {
261      return setDefaultRaw((byte[])defaultValue);
262    } else if (defaultValue instanceof boolean[]) {
263      return setDefaultBooleanArray((boolean[])defaultValue);
264    } else if (defaultValue instanceof double[]) {
265      return setDefaultDoubleArray((double[])defaultValue);
266    } else if (defaultValue instanceof Boolean[]) {
267      return setDefaultBooleanArray((Boolean[])defaultValue);
268    } else if (defaultValue instanceof Number[]) {
269      return setDefaultNumberArray((Number[])defaultValue);
270    } else if (defaultValue instanceof String[]) {
271      return setDefaultStringArray((String[])defaultValue);
272    } else {
273      throw new IllegalArgumentException("Value of type " + defaultValue.getClass().getName()
274        + " cannot be put into a table");
275    }
276  }
277
278  /**
279   * Sets the entry's value if it does not exist.
280   * @param defaultValue the default value to set
281   * @return False if the entry exists with a different type
282   */
283  public boolean setDefaultBoolean(boolean defaultValue) {
284    return NetworkTablesJNI.setDefaultBoolean(m_handle, 0, defaultValue);
285  }
286
287  /**
288   * Sets the entry's value if it does not exist.
289   * @param defaultValue the default value to set
290   * @return False if the entry exists with a different type
291   */
292  public boolean setDefaultDouble(double defaultValue) {
293    return NetworkTablesJNI.setDefaultDouble(m_handle, 0, defaultValue);
294  }
295
296  /**
297   * Sets the entry's value if it does not exist.
298   * @param defaultValue the default value to set
299   * @return False if the entry exists with a different type
300   */
301  public boolean setDefaultNumber(Number defaultValue) {
302    return NetworkTablesJNI.setDefaultDouble(m_handle, 0, defaultValue.doubleValue());
303  }
304
305  /**
306   * Sets the entry's value if it does not exist.
307   * @param defaultValue the default value to set
308   * @return False if the entry exists with a different type
309   */
310  public boolean setDefaultString(String defaultValue) {
311    return NetworkTablesJNI.setDefaultString(m_handle, 0, defaultValue);
312  }
313
314  /**
315   * Sets the entry's value if it does not exist.
316   * @param defaultValue the default value to set
317   * @return False if the entry exists with a different type
318   */
319  public boolean setDefaultRaw(byte[] defaultValue) {
320    return NetworkTablesJNI.setDefaultRaw(m_handle, 0, defaultValue);
321  }
322
323  /**
324   * Sets the entry's value if it does not exist.
325   * @param defaultValue the default value to set
326   * @return False if the entry exists with a different type
327   */
328  public boolean setDefaultBooleanArray(boolean[] defaultValue) {
329    return NetworkTablesJNI.setDefaultBooleanArray(m_handle, 0, defaultValue);
330  }
331
332  /**
333   * Sets the entry's value if it does not exist.
334   * @param defaultValue the default value to set
335   * @return False if the entry exists with a different type
336   */
337  public boolean setDefaultBooleanArray(Boolean[] defaultValue) {
338    return NetworkTablesJNI.setDefaultBooleanArray(m_handle, 0, NetworkTableValue.toNative(defaultValue));
339  }
340
341  /**
342   * Sets the entry's value if it does not exist.
343   * @param defaultValue the default value to set
344   * @return False if the entry exists with a different type
345   */
346  public boolean setDefaultDoubleArray(double[] defaultValue) {
347    return NetworkTablesJNI.setDefaultDoubleArray(m_handle, 0, defaultValue);
348  }
349
350  /**
351   * Sets the entry's value if it does not exist.
352   * @param defaultValue the default value to set
353   * @return False if the entry exists with a different type
354   */
355  public boolean setDefaultNumberArray(Number[] defaultValue) {
356    return NetworkTablesJNI.setDefaultDoubleArray(m_handle, 0, NetworkTableValue.toNative(defaultValue));
357  }
358
359  /**
360   * Sets the entry's value if it does not exist.
361   * @param defaultValue the default value to set
362   * @return False if the entry exists with a different type
363   */
364  public boolean setDefaultStringArray(String[] defaultValue) {
365    return NetworkTablesJNI.setDefaultStringArray(m_handle, 0, defaultValue);
366  }
367
368  /**
369   * Sets the entry's value
370   * @param value the value that will be assigned
371   * @return False if the table key already exists with a different type
372   * @throws IllegalArgumentException if the value is not a known type
373   */
374  public boolean setValue(Object value) {
375    if (value instanceof NetworkTableValue) {
376      long time = ((NetworkTableValue)value).getTime();
377      Object o = ((NetworkTableValue)value).getValue();
378      switch (((NetworkTableValue)value).getType()) {
379        case kBoolean:
380          return NetworkTablesJNI.setBoolean(m_handle, time, ((Boolean)o).booleanValue(), false);
381        case kDouble:
382          return NetworkTablesJNI.setDouble(m_handle, time, ((Number)o).doubleValue(), false);
383        case kString:
384          return NetworkTablesJNI.setString(m_handle, time, (String)o, false);
385        case kRaw:
386          return NetworkTablesJNI.setRaw(m_handle, time, (byte[])o, false);
387        case kBooleanArray:
388          return NetworkTablesJNI.setBooleanArray(m_handle, time, (boolean[])o, false);
389        case kDoubleArray:
390          return NetworkTablesJNI.setDoubleArray(m_handle, time, (double[])o, false);
391        case kStringArray:
392          return NetworkTablesJNI.setStringArray(m_handle, time, (String[])o, false);
393        case kRpc:
394          // TODO
395        default:
396          return true;
397      }
398    } else if (value instanceof Boolean) {
399      return setBoolean((Boolean)value);
400    } else if (value instanceof Number) {
401      return setNumber((Number)value);
402    } else if (value instanceof String) {
403      return setString((String)value);
404    } else if (value instanceof byte[]) {
405      return setRaw((byte[])value);
406    } else if (value instanceof boolean[]) {
407      return setBooleanArray((boolean[])value);
408    } else if (value instanceof double[]) {
409      return setDoubleArray((double[])value);
410    } else if (value instanceof Boolean[]) {
411      return setBooleanArray((Boolean[])value);
412    } else if (value instanceof Number[]) {
413      return setNumberArray((Number[])value);
414    } else if (value instanceof String[]) {
415      return setStringArray((String[])value);
416    } else {
417      throw new IllegalArgumentException("Value of type " + value.getClass().getName()
418        + " cannot be put into a table");
419    }
420  }
421
422  /**
423   * Sets the entry's value.
424   * @param value the value to set
425   * @return False if the entry exists with a different type
426   */
427  public boolean setBoolean(boolean value) {
428    return NetworkTablesJNI.setBoolean(m_handle, 0, value, false);
429  }
430
431  /**
432   * Sets the entry's value.
433   * @param value the value to set
434   * @return False if the entry exists with a different type
435   */
436  public boolean setDouble(double value) {
437    return NetworkTablesJNI.setDouble(m_handle, 0, value, false);
438  }
439
440  /**
441   * Sets the entry's value.
442   * @param value the value to set
443   * @return False if the entry exists with a different type
444   */
445  public boolean setNumber(Number value) {
446    return NetworkTablesJNI.setDouble(m_handle, 0, value.doubleValue(), false);
447  }
448
449  /**
450   * Sets the entry's value.
451   * @param value the value to set
452   * @return False if the entry exists with a different type
453   */
454  public boolean setString(String value) {
455    return NetworkTablesJNI.setString(m_handle, 0, value, false);
456  }
457
458  /**
459   * Sets the entry's value.
460   * @param value the value to set
461   * @return False if the entry exists with a different type
462   */
463  public boolean setRaw(byte[] value) {
464    return NetworkTablesJNI.setRaw(m_handle, 0, value, false);
465  }
466
467  /**
468   * Sets the entry's value.
469   * @param value the value to set
470   * @param len the length of the value
471   * @return False if the entry exists with a different type
472   */
473  public boolean setRaw(ByteBuffer value, int len) {
474    if (!value.isDirect())
475      throw new IllegalArgumentException("must be a direct buffer");
476    if (value.capacity() < len)
477      throw new IllegalArgumentException("buffer is too small, must be at least " + len);
478    return NetworkTablesJNI.setRaw(m_handle, 0, value, len, false);
479  }
480
481  /**
482   * Sets the entry's value.
483   * @param value the value to set
484   * @return False if the entry exists with a different type
485   */
486  public boolean setBooleanArray(boolean[] value) {
487    return NetworkTablesJNI.setBooleanArray(m_handle, 0, value, false);
488  }
489
490  /**
491   * Sets the entry's value.
492   * @param value the value to set
493   * @return False if the entry exists with a different type
494   */
495  public boolean setBooleanArray(Boolean[] value) {
496    return NetworkTablesJNI.setBooleanArray(m_handle, 0, NetworkTableValue.toNative(value), false);
497  }
498
499  /**
500   * Sets the entry's value.
501   * @param value the value to set
502   * @return False if the entry exists with a different type
503   */
504  public boolean setDoubleArray(double[] value) {
505    return NetworkTablesJNI.setDoubleArray(m_handle, 0, value, false);
506  }
507
508  /**
509   * Sets the entry's value.
510   * @param value the value to set
511   * @return False if the entry exists with a different type
512   */
513  public boolean setNumberArray(Number[] value) {
514    return NetworkTablesJNI.setDoubleArray(m_handle, 0, NetworkTableValue.toNative(value), false);
515  }
516
517  /**
518   * Sets the entry's value.
519   * @param value the value to set
520   * @return False if the entry exists with a different type
521   */
522  public boolean setStringArray(String[] value) {
523    return NetworkTablesJNI.setStringArray(m_handle, 0, value, false);
524  }
525
526  /**
527   * Sets the entry's value.  If the value is of different type, the type is
528   * changed to match the new value.
529   * @param value the value to set
530   * @throws IllegalArgumentException if the value is not a known type
531   */
532  public void forceSetValue(Object value) {
533    if (value instanceof NetworkTableValue) {
534      long time = ((NetworkTableValue)value).getTime();
535      Object o = ((NetworkTableValue)value).getValue();
536      switch (((NetworkTableValue)value).getType()) {
537        case kBoolean:
538          NetworkTablesJNI.setBoolean(m_handle, time, ((Boolean)o).booleanValue(), true);
539          return;
540        case kDouble:
541          NetworkTablesJNI.setDouble(m_handle, time, ((Number)o).doubleValue(), true);
542          return;
543        case kString:
544          NetworkTablesJNI.setString(m_handle, time, (String)o, true);
545          return;
546        case kRaw:
547          NetworkTablesJNI.setRaw(m_handle, time, (byte[])o, true);
548          return;
549        case kBooleanArray:
550          NetworkTablesJNI.setBooleanArray(m_handle, time, (boolean[])o, true);
551          return;
552        case kDoubleArray:
553          NetworkTablesJNI.setDoubleArray(m_handle, time, (double[])o, true);
554          return;
555        case kStringArray:
556          NetworkTablesJNI.setStringArray(m_handle, time, (String[])o, true);
557          return;
558        case kRpc:
559          // TODO
560        default:
561          return;
562      }
563    } else if (value instanceof Boolean) {
564      forceSetBoolean((Boolean)value);
565    } else if (value instanceof Number) {
566      forceSetNumber((Number)value);
567    } else if (value instanceof String) {
568      forceSetString((String)value);
569    } else if (value instanceof byte[]) {
570      forceSetRaw((byte[])value);
571    } else if (value instanceof boolean[]) {
572      forceSetBooleanArray((boolean[])value);
573    } else if (value instanceof double[]) {
574      forceSetDoubleArray((double[])value);
575    } else if (value instanceof Boolean[]) {
576      forceSetBooleanArray((Boolean[])value);
577    } else if (value instanceof Number[]) {
578      forceSetNumberArray((Number[])value);
579    } else if (value instanceof String[]) {
580      forceSetStringArray((String[])value);
581    } else {
582      throw new IllegalArgumentException("Value of type " + value.getClass().getName()
583        + " cannot be put into a table");
584    }
585  }
586
587  /**
588   * Sets the entry's value.  If the value is of different type, the type is
589   * changed to match the new value.
590   * @param value the value to set
591   */
592  public void forceSetBoolean(boolean value) {
593    NetworkTablesJNI.setBoolean(m_handle, 0, value, true);
594  }
595
596  /**
597   * Sets the entry's value.  If the value is of different type, the type is
598   * changed to match the new value.
599   * @param value the value to set
600   */
601  public void forceSetDouble(double value) {
602    NetworkTablesJNI.setDouble(m_handle, 0, value, true);
603  }
604
605  /**
606   * Sets the entry's value.  If the value is of different type, the type is
607   * changed to match the new value.
608   * @param value the value to set
609   */
610  public void forceSetNumber(Number value) {
611    NetworkTablesJNI.setDouble(m_handle, 0, value.doubleValue(), true);
612  }
613
614  /**
615   * Sets the entry's value.  If the value is of different type, the type is
616   * changed to match the new value.
617   * @param value the value to set
618   */
619  public void forceSetString(String value) {
620    NetworkTablesJNI.setString(m_handle, 0, value, true);
621  }
622
623  /**
624   * Sets the entry's value.  If the value is of different type, the type is
625   * changed to match the new value.
626   * @param value the value to set
627   */
628  public void forceSetRaw(byte[] value) {
629    NetworkTablesJNI.setRaw(m_handle, 0, value, true);
630  }
631
632  /**
633   * Sets the entry's value.  If the value is of different type, the type is
634   * changed to match the new value.
635   * @param value the value to set
636   */
637  public void forceSetBooleanArray(boolean[] value) {
638    NetworkTablesJNI.setBooleanArray(m_handle, 0, value, true);
639  }
640
641  /**
642   * Sets the entry's value.  If the value is of different type, the type is
643   * changed to match the new value.
644   * @param value the value to set
645   */
646  public void forceSetBooleanArray(Boolean[] value) {
647    NetworkTablesJNI.setBooleanArray(m_handle, 0, NetworkTableValue.toNative(value), true);
648  }
649
650  /**
651   * Sets the entry's value.  If the value is of different type, the type is
652   * changed to match the new value.
653   * @param value the value to set
654   */
655  public void forceSetDoubleArray(double[] value) {
656    NetworkTablesJNI.setDoubleArray(m_handle, 0, value, true);
657  }
658
659  /**
660   * Sets the entry's value.  If the value is of different type, the type is
661   * changed to match the new value.
662   * @param value the value to set
663   */
664  public void forceSetNumberArray(Number[] value) {
665    NetworkTablesJNI.setDoubleArray(m_handle, 0, NetworkTableValue.toNative(value), true);
666  }
667
668  /**
669   * Sets the entry's value.  If the value is of different type, the type is
670   * changed to match the new value.
671   * @param value the value to set
672   */
673  public void forceSetStringArray(String[] value) {
674    NetworkTablesJNI.setStringArray(m_handle, 0, value, true);
675  }
676
677  /**
678   * Sets flags.
679   * @param flags the flags to set (bitmask)
680   */
681  public void setFlags(int flags) {
682    NetworkTablesJNI.setEntryFlags(m_handle, getFlags() | flags);
683  }
684
685  /**
686   * Clears flags.
687   * @param flags the flags to clear (bitmask)
688   */
689  public void clearFlags(int flags) {
690    NetworkTablesJNI.setEntryFlags(m_handle, getFlags() & ~flags);
691  }
692
693  /**
694   * Make value persistent through program restarts.
695   */
696  public void setPersistent() {
697    setFlags(kPersistent);
698  }
699
700  /**
701   * Stop making value persistent through program restarts.
702   */
703  public void clearPersistent() {
704    clearFlags(kPersistent);
705  }
706
707  /**
708   * Returns whether the value is persistent through program restarts.
709   * @return True if the value is persistent.
710   */
711  public boolean isPersistent() {
712    return (getFlags() & kPersistent) != 0;
713  }
714
715  /**
716   * Deletes the entry.
717   */
718  public void delete() {
719    NetworkTablesJNI.deleteEntry(m_handle);
720  }
721
722  /**
723   * Create a callback-based RPC entry point.  Only valid to use on the server.
724   * The callback function will be called when the RPC is called.
725   * This function creates RPC version 0 definitions (raw data in and out).
726   * @param callback  callback function
727   */
728  void createRpc(Consumer<RpcAnswer> callback) {
729    m_inst.createRpc(this, callback);
730  }
731
732  /**
733   * Call a RPC function.  May be used on either the client or server.
734   * This function is non-blocking.  Either {@link RpcCall#GetResult()} or
735   * {@link RpcCall#CancelResult()} must be called on the return value to either
736   * get or ignore the result of the call.
737   * @param params      parameter
738   * @return RPC call object.
739   */
740  RpcCall callRpc(byte[] params) {
741    return new RpcCall(this, NetworkTablesJNI.callRpc(m_handle, params));
742  }
743
744  /**
745   * Add a listener for changes to the entry
746   * @param listener the listener to add
747   * @param flags bitmask specifying desired notifications
748   * @return listener handle
749   */
750  public int addListener(Consumer<EntryNotification> listener, int flags) {
751    return m_inst.addEntryListener(this, listener, flags);
752  }
753
754  /**
755   * Remove a listener from receiving entry events
756   * @param listener the listener to be removed
757   */
758  public void removeListener(int listener) {
759    m_inst.removeEntryListener(listener);
760  }
761
762  @Override
763  public boolean equals(Object o) {
764    if (o == this) {
765      return true;
766    }
767    if (!(o instanceof NetworkTableEntry)) {
768      return false;
769    }
770    NetworkTableEntry other = (NetworkTableEntry) o;
771    return m_handle == other.m_handle;
772  }
773
774  @Override
775  public int hashCode() {
776    return m_handle;
777  }
778
779  private NetworkTableInstance m_inst;
780  private int m_handle;
781}