mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-22 01:11:42 +00:00
[ntcore] NetworkTables 4 (#3217)
This commit is contained in:
15
ntcore/src/generate/java/Entry.java.jinja
Normal file
15
ntcore/src/generate/java/Entry.java.jinja
Normal file
@@ -0,0 +1,15 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
package edu.wpi.first.networktables;
|
||||
|
||||
/**
|
||||
* NetworkTables {{ TypeName }} entry.
|
||||
*
|
||||
* <p>Unlike NetworkTableEntry, the entry goes away when close() is called.
|
||||
*/
|
||||
public interface {{ TypeName }}Entry extends {{ TypeName }}Subscriber, {{ TypeName }}Publisher {
|
||||
/** Stops publishing the entry if it's published. */
|
||||
void unpublish();
|
||||
}
|
||||
75
ntcore/src/generate/java/EntryImpl.java.jinja
Normal file
75
ntcore/src/generate/java/EntryImpl.java.jinja
Normal file
@@ -0,0 +1,75 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
package edu.wpi.first.networktables;
|
||||
|
||||
/** NetworkTables {{ TypeName }} implementation. */
|
||||
@SuppressWarnings("PMD.ArrayIsStoredDirectly")
|
||||
final class {{ TypeName }}EntryImpl extends EntryBase implements {{ TypeName }}Entry {
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param topic Topic
|
||||
* @param handle Native handle
|
||||
* @param defaultValue Default value for get()
|
||||
*/
|
||||
{{ TypeName }}EntryImpl({{ TypeName }}Topic topic, int handle, {{ java.ValueType }} defaultValue) {
|
||||
super(handle);
|
||||
m_topic = topic;
|
||||
m_defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public {{ TypeName }}Topic getTopic() {
|
||||
return m_topic;
|
||||
}
|
||||
|
||||
@Override
|
||||
public {{ java.ValueType }} get() {
|
||||
return NetworkTablesJNI.get{{ TypeName }}(m_handle, m_defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public {{ java.ValueType }} get({{ java.ValueType }} defaultValue) {
|
||||
return NetworkTablesJNI.get{{TypeName}}(m_handle, defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timestamped{{ TypeName }} getAtomic() {
|
||||
return NetworkTablesJNI.getAtomic{{ TypeName }}(m_handle, m_defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timestamped{{ TypeName }} getAtomic({{ java.ValueType }} defaultValue) {
|
||||
return NetworkTablesJNI.getAtomic{{ TypeName }}(m_handle, defaultValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timestamped{{ TypeName }}[] readQueue() {
|
||||
return NetworkTablesJNI.readQueue{{ TypeName }}(m_handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public {{ java.ValueType }}[] readQueueValues() {
|
||||
return NetworkTablesJNI.readQueueValues{{ TypeName }}(m_handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set({{ java.ValueType }} value, long time) {
|
||||
NetworkTablesJNI.set{{ TypeName }}(m_handle, time, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDefault({{ java.ValueType }} value) {
|
||||
NetworkTablesJNI.setDefault{{ TypeName }}(m_handle, 0, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unpublish() {
|
||||
NetworkTablesJNI.unpublish(m_handle);
|
||||
}
|
||||
|
||||
private final {{ TypeName }}Topic m_topic;
|
||||
private final {{ java.ValueType }} m_defaultValue;
|
||||
}
|
||||
317
ntcore/src/generate/java/GenericEntryImpl.java.jinja
Normal file
317
ntcore/src/generate/java/GenericEntryImpl.java.jinja
Normal file
@@ -0,0 +1,317 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
package edu.wpi.first.networktables;
|
||||
|
||||
/** NetworkTables generic implementation. */
|
||||
final class GenericEntryImpl extends EntryBase implements GenericEntry {
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param topic Topic
|
||||
* @param handle Native handle
|
||||
*/
|
||||
GenericEntryImpl(Topic topic, int handle) {
|
||||
super(handle);
|
||||
m_topic = topic;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Topic getTopic() {
|
||||
return m_topic;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NetworkTableValue get() {
|
||||
return NetworkTablesJNI.getValue(m_handle);
|
||||
}
|
||||
{% for t in types %}
|
||||
/**
|
||||
* Gets the entry's value as a {{ t.java.ValueType }}. If the entry does not exist or is of different type, it
|
||||
* will return the default value.
|
||||
*
|
||||
* @param defaultValue the value to be returned if no value is found
|
||||
* @return the entry's value or the given default value
|
||||
*/
|
||||
@Override
|
||||
public {{ t.java.ValueType }} get{{ t.TypeName }}({{ t.java.ValueType }} defaultValue) {
|
||||
return NetworkTablesJNI.get{{ t.TypeName }}(m_handle, defaultValue);
|
||||
}
|
||||
{% if t.java.WrapValueType %}
|
||||
/**
|
||||
* Gets the entry's value as a boolean array. If the entry does not exist or is of different type,
|
||||
* it will return the default value.
|
||||
*
|
||||
* @param defaultValue the value to be returned if no value is found
|
||||
* @return the entry's value or the given default value
|
||||
*/
|
||||
@Override
|
||||
public {{ t.java.WrapValueType }} get{{ t.TypeName }}({{ t.java.WrapValueType }} defaultValue) {
|
||||
return NetworkTableValue.fromNative{{ t.TypeName }}(
|
||||
get{{ t.TypeName }}(NetworkTableValue.toNative{{ t.TypeName }}(defaultValue)));
|
||||
}
|
||||
{% endif -%}
|
||||
{% endfor %}
|
||||
@Override
|
||||
public NetworkTableValue[] readQueue() {
|
||||
return NetworkTablesJNI.readQueueValue(m_handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean set(NetworkTableValue value) {
|
||||
long time = value.getTime();
|
||||
Object otherValue = value.getValue();
|
||||
switch (value.getType()) {
|
||||
case kBoolean:
|
||||
return NetworkTablesJNI.setBoolean(m_handle, time, (Boolean) otherValue);
|
||||
case kInteger:
|
||||
return NetworkTablesJNI.setInteger(
|
||||
m_handle, time, ((Number) otherValue).longValue());
|
||||
case kFloat:
|
||||
return NetworkTablesJNI.setFloat(
|
||||
m_handle, time, ((Number) otherValue).floatValue());
|
||||
case kDouble:
|
||||
return NetworkTablesJNI.setDouble(
|
||||
m_handle, time, ((Number) otherValue).doubleValue());
|
||||
case kString:
|
||||
return NetworkTablesJNI.setString(m_handle, time, (String) otherValue);
|
||||
case kRaw:
|
||||
return NetworkTablesJNI.setRaw(m_handle, time, (byte[]) otherValue);
|
||||
case kBooleanArray:
|
||||
return NetworkTablesJNI.setBooleanArray(m_handle, time, (boolean[]) otherValue);
|
||||
case kIntegerArray:
|
||||
return NetworkTablesJNI.setIntegerArray(m_handle, time, (long[]) otherValue);
|
||||
case kFloatArray:
|
||||
return NetworkTablesJNI.setFloatArray(m_handle, time, (float[]) otherValue);
|
||||
case kDoubleArray:
|
||||
return NetworkTablesJNI.setDoubleArray(m_handle, time, (double[]) otherValue);
|
||||
case kStringArray:
|
||||
return NetworkTablesJNI.setStringArray(m_handle, time, (String[]) otherValue);
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the entry's value.
|
||||
*
|
||||
* @param value the value that will be assigned
|
||||
* @return False if the table key already exists with a different type
|
||||
* @throws IllegalArgumentException if the value is not a known type
|
||||
*/
|
||||
@Override
|
||||
public boolean setValue(Object value, long time) {
|
||||
if (value instanceof NetworkTableValue) {
|
||||
return set((NetworkTableValue) value);
|
||||
} else if (value instanceof Boolean) {
|
||||
return setBoolean((Boolean) value, time);
|
||||
} else if (value instanceof Long) {
|
||||
return setInteger((Long) value, time);
|
||||
} else if (value instanceof Float) {
|
||||
return setFloat((Float) value, time);
|
||||
} else if (value instanceof Number) {
|
||||
return setNumber((Number) value, time);
|
||||
} else if (value instanceof String) {
|
||||
return setString((String) value, time);
|
||||
} else if (value instanceof byte[]) {
|
||||
return setRaw((byte[]) value, time);
|
||||
} else if (value instanceof boolean[]) {
|
||||
return setBooleanArray((boolean[]) value, time);
|
||||
} else if (value instanceof long[]) {
|
||||
return setIntegerArray((long[]) value, time);
|
||||
} else if (value instanceof float[]) {
|
||||
return setFloatArray((float[]) value, time);
|
||||
} else if (value instanceof double[]) {
|
||||
return setDoubleArray((double[]) value, time);
|
||||
} else if (value instanceof Boolean[]) {
|
||||
return setBooleanArray((Boolean[]) value, time);
|
||||
} else if (value instanceof Long[]) {
|
||||
return setIntegerArray((Long[]) value, time);
|
||||
} else if (value instanceof Float[]) {
|
||||
return setFloatArray((Float[]) value, time);
|
||||
} else if (value instanceof Number[]) {
|
||||
return setNumberArray((Number[]) value, time);
|
||||
} else if (value instanceof String[]) {
|
||||
return setStringArray((String[]) value, time);
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
"Value of type " + value.getClass().getName() + " cannot be put into a table");
|
||||
}
|
||||
}
|
||||
{% for t in types %}
|
||||
/**
|
||||
* Sets the entry's value.
|
||||
*
|
||||
* @param value the value to set
|
||||
* @return False if the entry exists with a different type
|
||||
*/
|
||||
@Override
|
||||
public boolean set{{ t.TypeName }}({{ t.java.ValueType }} value, long time) {
|
||||
return NetworkTablesJNI.set{{ t.TypeName }}(m_handle, time, value);
|
||||
}
|
||||
{% if t.java.WrapValueType %}
|
||||
/**
|
||||
* Sets the entry's value.
|
||||
*
|
||||
* @param value the value to set
|
||||
* @return False if the entry exists with a different type
|
||||
*/
|
||||
@Override
|
||||
public boolean set{{ t.TypeName }}({{ t.java.WrapValueType }} value, long time) {
|
||||
return set{{ t.TypeName }}(NetworkTableValue.toNative{{ t.TypeName }}(value), time);
|
||||
}
|
||||
{% endif -%}
|
||||
{% endfor %}
|
||||
/**
|
||||
* Sets the entry's value.
|
||||
*
|
||||
* @param value the value to set
|
||||
* @return False if the entry exists with a different type
|
||||
*/
|
||||
public boolean setNumber(Number value, long time) {
|
||||
return setDouble(value.doubleValue(), time);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the entry's value.
|
||||
*
|
||||
* @param value the value to set
|
||||
* @return False if the entry exists with a different type
|
||||
*/
|
||||
public boolean setNumberArray(Number[] value, long time) {
|
||||
return setDoubleArray(NetworkTableValue.toNativeDoubleArray(value), time);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setDefault(NetworkTableValue defaultValue) {
|
||||
long time = defaultValue.getTime();
|
||||
Object otherValue = defaultValue.getValue();
|
||||
switch (defaultValue.getType()) {
|
||||
case kBoolean:
|
||||
return NetworkTablesJNI.setDefaultBoolean(m_handle, time, (Boolean) otherValue);
|
||||
case kInteger:
|
||||
return NetworkTablesJNI.setDefaultInteger(
|
||||
m_handle, time, ((Number) otherValue).longValue());
|
||||
case kFloat:
|
||||
return NetworkTablesJNI.setDefaultFloat(
|
||||
m_handle, time, ((Number) otherValue).floatValue());
|
||||
case kDouble:
|
||||
return NetworkTablesJNI.setDefaultDouble(
|
||||
m_handle, time, ((Number) otherValue).doubleValue());
|
||||
case kString:
|
||||
return NetworkTablesJNI.setDefaultString(m_handle, time, (String) otherValue);
|
||||
case kRaw:
|
||||
return NetworkTablesJNI.setDefaultRaw(m_handle, time, (byte[]) otherValue);
|
||||
case kBooleanArray:
|
||||
return NetworkTablesJNI.setDefaultBooleanArray(m_handle, time, (boolean[]) otherValue);
|
||||
case kIntegerArray:
|
||||
return NetworkTablesJNI.setDefaultIntegerArray(m_handle, time, (long[]) otherValue);
|
||||
case kFloatArray:
|
||||
return NetworkTablesJNI.setDefaultFloatArray(m_handle, time, (float[]) otherValue);
|
||||
case kDoubleArray:
|
||||
return NetworkTablesJNI.setDefaultDoubleArray(m_handle, time, (double[]) otherValue);
|
||||
case kStringArray:
|
||||
return NetworkTablesJNI.setDefaultStringArray(m_handle, time, (String[]) otherValue);
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the entry's value if it does not exist.
|
||||
*
|
||||
* @param defaultValue the default value to set
|
||||
* @return False if the entry exists with a different type
|
||||
* @throws IllegalArgumentException if the value is not a known type
|
||||
*/
|
||||
@Override
|
||||
public boolean setDefaultValue(Object defaultValue) {
|
||||
if (defaultValue instanceof NetworkTableValue) {
|
||||
return setDefault((NetworkTableValue) defaultValue);
|
||||
} else if (defaultValue instanceof Boolean) {
|
||||
return setDefaultBoolean((Boolean) defaultValue);
|
||||
} else if (defaultValue instanceof Integer) {
|
||||
return setDefaultInteger((Integer) defaultValue);
|
||||
} else if (defaultValue instanceof Float) {
|
||||
return setDefaultFloat((Float) defaultValue);
|
||||
} else if (defaultValue instanceof Number) {
|
||||
return setDefaultNumber((Number) defaultValue);
|
||||
} else if (defaultValue instanceof String) {
|
||||
return setDefaultString((String) defaultValue);
|
||||
} else if (defaultValue instanceof byte[]) {
|
||||
return setDefaultRaw((byte[]) defaultValue);
|
||||
} else if (defaultValue instanceof boolean[]) {
|
||||
return setDefaultBooleanArray((boolean[]) defaultValue);
|
||||
} else if (defaultValue instanceof long[]) {
|
||||
return setDefaultIntegerArray((long[]) defaultValue);
|
||||
} else if (defaultValue instanceof float[]) {
|
||||
return setDefaultFloatArray((float[]) defaultValue);
|
||||
} else if (defaultValue instanceof double[]) {
|
||||
return setDefaultDoubleArray((double[]) defaultValue);
|
||||
} else if (defaultValue instanceof Boolean[]) {
|
||||
return setDefaultBooleanArray((Boolean[]) defaultValue);
|
||||
} else if (defaultValue instanceof Long[]) {
|
||||
return setDefaultIntegerArray((Long[]) defaultValue);
|
||||
} else if (defaultValue instanceof Float[]) {
|
||||
return setDefaultFloatArray((Float[]) defaultValue);
|
||||
} else if (defaultValue instanceof Number[]) {
|
||||
return setDefaultNumberArray((Number[]) defaultValue);
|
||||
} else if (defaultValue instanceof String[]) {
|
||||
return setDefaultStringArray((String[]) defaultValue);
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
"Value of type " + defaultValue.getClass().getName() + " cannot be put into a table");
|
||||
}
|
||||
}
|
||||
{% for t in types %}
|
||||
/**
|
||||
* Sets the entry's value if it does not exist.
|
||||
*
|
||||
* @param defaultValue the default value to set
|
||||
* @return False if the entry exists with a different type
|
||||
*/
|
||||
@Override
|
||||
public boolean setDefault{{ t.TypeName }}({{ t.java.ValueType }} defaultValue) {
|
||||
return NetworkTablesJNI.setDefault{{ t.TypeName }}(m_handle, 0, defaultValue);
|
||||
}
|
||||
{% if t.java.WrapValueType %}
|
||||
/**
|
||||
* Sets the entry's value if it does not exist.
|
||||
*
|
||||
* @param defaultValue the default value to set
|
||||
* @return False if the entry exists with a different type
|
||||
*/
|
||||
@Override
|
||||
public boolean setDefault{{ t.TypeName }}({{ t.java.WrapValueType }} defaultValue) {
|
||||
return setDefault{{ t.TypeName }}(NetworkTableValue.toNative{{ t.TypeName }}(defaultValue));
|
||||
}
|
||||
{% endif -%}
|
||||
{% endfor %}
|
||||
/**
|
||||
* Sets the entry's value if it does not exist.
|
||||
*
|
||||
* @param defaultValue the default value to set
|
||||
* @return False if the entry exists with a different type
|
||||
*/
|
||||
public boolean setDefaultNumber(Number defaultValue) {
|
||||
return setDefaultDouble(defaultValue.doubleValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the entry's value if it does not exist.
|
||||
*
|
||||
* @param defaultValue the default value to set
|
||||
* @return False if the entry exists with a different type
|
||||
*/
|
||||
public boolean setDefaultNumberArray(Number[] defaultValue) {
|
||||
return setDefaultDoubleArray(NetworkTableValue.toNativeDoubleArray(defaultValue));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unpublish() {
|
||||
NetworkTablesJNI.unpublish(m_handle);
|
||||
}
|
||||
|
||||
private final Topic m_topic;
|
||||
}
|
||||
119
ntcore/src/generate/java/GenericPublisher.java.jinja
Normal file
119
ntcore/src/generate/java/GenericPublisher.java.jinja
Normal file
@@ -0,0 +1,119 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
package edu.wpi.first.networktables;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/** NetworkTables generic publisher. */
|
||||
public interface GenericPublisher extends Publisher, Consumer<NetworkTableValue> {
|
||||
/**
|
||||
* Get the corresponding topic.
|
||||
*
|
||||
* @return Topic
|
||||
*/
|
||||
@Override
|
||||
Topic getTopic();
|
||||
|
||||
/**
|
||||
* Publish a new value.
|
||||
*
|
||||
* @param value value to publish
|
||||
* @return False if the topic already exists with a different type
|
||||
*/
|
||||
boolean set(NetworkTableValue value);
|
||||
|
||||
/**
|
||||
* Publish a new value.
|
||||
*
|
||||
* @param value value to publish
|
||||
* @return False if the topic already exists with a different type
|
||||
* @throws IllegalArgumentException if the value is not a known type
|
||||
*/
|
||||
default boolean setValue(Object value) {
|
||||
return setValue(value, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish a new value.
|
||||
*
|
||||
* @param value value to publish
|
||||
* @param time timestamp; 0 indicates current NT time should be used
|
||||
* @return False if the topic already exists with a different type
|
||||
* @throws IllegalArgumentException if the value is not a known type
|
||||
*/
|
||||
boolean setValue(Object value, long time);
|
||||
{% for t in types %}
|
||||
/**
|
||||
* Publish a new value.
|
||||
*
|
||||
* @param value value to publish
|
||||
* @return False if the topic already exists with a different type
|
||||
*/
|
||||
default boolean set{{ t.TypeName }}({{ t.java.ValueType }} value) {
|
||||
return set{{ t.TypeName }}(value, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish a new value.
|
||||
*
|
||||
* @param value value to publish
|
||||
* @param time timestamp; 0 indicates current NT time should be used
|
||||
* @return False if the topic already exists with a different type
|
||||
*/
|
||||
boolean set{{ t.TypeName }}({{ t.java.ValueType }} value, long time);
|
||||
{% if t.java.WrapValueType %}
|
||||
/**
|
||||
* Publish a new value.
|
||||
*
|
||||
* @param value value to publish
|
||||
* @return False if the topic already exists with a different type
|
||||
*/
|
||||
default boolean set{{ t.TypeName }}({{ t.java.WrapValueType }} value) {
|
||||
return set{{ t.TypeName }}(value, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish a new value.
|
||||
*
|
||||
* @param value value to publish
|
||||
* @param time timestamp; 0 indicates current NT time should be used
|
||||
* @return False if the topic already exists with a different type
|
||||
*/
|
||||
boolean set{{ t.TypeName }}({{ t.java.WrapValueType }} value, long time);
|
||||
{% endif -%}
|
||||
{% endfor %}
|
||||
/**
|
||||
* Sets the entry's value if it does not exist.
|
||||
*
|
||||
* @param defaultValue the default value to set
|
||||
* @return False if the entry exists with a different type
|
||||
*/
|
||||
boolean setDefault(NetworkTableValue defaultValue);
|
||||
|
||||
/**
|
||||
* Sets the entry's value if it does not exist.
|
||||
*
|
||||
* @param defaultValue the default value to set
|
||||
* @return False if the entry exists with a different type
|
||||
* @throws IllegalArgumentException if the value is not a known type
|
||||
*/
|
||||
boolean setDefaultValue(Object defaultValue);
|
||||
{% for t in types %}
|
||||
/**
|
||||
* Sets the entry's value if it does not exist.
|
||||
*
|
||||
* @param defaultValue the default value to set
|
||||
* @return False if the entry exists with a different type
|
||||
*/
|
||||
boolean setDefault{{ t.TypeName }}({{ t.java.ValueType }} defaultValue);
|
||||
{% if t.java.WrapValueType %}
|
||||
boolean setDefault{{ t.TypeName }}({{ t.java.WrapValueType }} defaultValue);
|
||||
{% endif -%}
|
||||
{% endfor %}
|
||||
@Override
|
||||
default void accept(NetworkTableValue value) {
|
||||
set(value);
|
||||
}
|
||||
}
|
||||
58
ntcore/src/generate/java/GenericSubscriber.java.jinja
Normal file
58
ntcore/src/generate/java/GenericSubscriber.java.jinja
Normal file
@@ -0,0 +1,58 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
package edu.wpi.first.networktables;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/** NetworkTables generic subscriber. */
|
||||
@SuppressWarnings("PMD.MissingOverride")
|
||||
public interface GenericSubscriber extends Subscriber, Supplier<NetworkTableValue> {
|
||||
/**
|
||||
* Get the corresponding topic.
|
||||
*
|
||||
* @return Topic
|
||||
*/
|
||||
@Override
|
||||
Topic getTopic();
|
||||
|
||||
/**
|
||||
* Get the last published value.
|
||||
* If no value has been published, returns a value with type NetworkTableType.kUnassigned.
|
||||
*
|
||||
* @return value
|
||||
*/
|
||||
NetworkTableValue get();
|
||||
{% for t in types %}
|
||||
/**
|
||||
* Gets the entry's value as a {{ t.java.ValueType }}. If the entry does not exist or is of different type, it
|
||||
* will return the default value.
|
||||
*
|
||||
* @param defaultValue the value to be returned if no value is found
|
||||
* @return the entry's value or the given default value
|
||||
*/
|
||||
{{ t.java.ValueType }} get{{ t.TypeName }}({{ t.java.ValueType }} defaultValue);
|
||||
{% if t.java.WrapValueType %}
|
||||
/**
|
||||
* Gets the entry's value as a boolean array. If the entry does not exist or is of different type,
|
||||
* it will return the default value.
|
||||
*
|
||||
* @param defaultValue the value to be returned if no value is found
|
||||
* @return the entry's value or the given default value
|
||||
*/
|
||||
{{ t.java.WrapValueType }} get{{ t.TypeName }}({{ t.java.WrapValueType }} defaultValue);
|
||||
{% endif -%}
|
||||
{% endfor %}
|
||||
/**
|
||||
* Get an array of all value changes since the last call to readQueue.
|
||||
* Also provides a timestamp for each value.
|
||||
*
|
||||
* <p>The "poll storage" subscribe option can be used to set the queue
|
||||
* depth.
|
||||
*
|
||||
* @return Array of timestamped values; empty array if no new changes have
|
||||
* been published since the previous call.
|
||||
*/
|
||||
NetworkTableValue[] readQueue();
|
||||
}
|
||||
537
ntcore/src/generate/java/NetworkTableEntry.java.jinja
Normal file
537
ntcore/src/generate/java/NetworkTableEntry.java.jinja
Normal file
@@ -0,0 +1,537 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
package edu.wpi.first.networktables;
|
||||
|
||||
/**
|
||||
* NetworkTables Entry.
|
||||
*
|
||||
* <p>For backwards compatibility, the NetworkTableEntry close() does not release the entry.
|
||||
*/
|
||||
@SuppressWarnings("UnnecessaryParentheses")
|
||||
public final class NetworkTableEntry implements Publisher, Subscriber {
|
||||
/**
|
||||
* Flag values (as returned by {@link #getFlags()}).
|
||||
*
|
||||
* @deprecated Use isPersistent() instead.
|
||||
*/
|
||||
@Deprecated(since = "2022", forRemoval = true)
|
||||
public static final int kPersistent = 0x01;
|
||||
|
||||
/**
|
||||
* Construct from native handle.
|
||||
*
|
||||
* @param inst Instance
|
||||
* @param handle Native handle
|
||||
*/
|
||||
public NetworkTableEntry(NetworkTableInstance inst, int handle) {
|
||||
this(new Topic(inst, NetworkTablesJNI.getTopicFromHandle(handle)), handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct from native handle.
|
||||
*
|
||||
* @param topic Topic
|
||||
* @param handle Native handle
|
||||
*/
|
||||
public NetworkTableEntry(Topic topic, int handle) {
|
||||
m_topic = topic;
|
||||
m_handle = handle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {}
|
||||
|
||||
/**
|
||||
* Determines if the native handle is valid.
|
||||
*
|
||||
* @return True if the native handle is valid, false otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return m_handle != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the native handle for the entry.
|
||||
*
|
||||
* @return Native handle
|
||||
*/
|
||||
@Override
|
||||
public int getHandle() {
|
||||
return m_handle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the subscribed-to / published-to topic.
|
||||
*
|
||||
* @return Topic
|
||||
*/
|
||||
@Override
|
||||
public Topic getTopic() {
|
||||
return m_topic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the instance for the entry.
|
||||
*
|
||||
* @return Instance
|
||||
*/
|
||||
public NetworkTableInstance getInstance() {
|
||||
return m_topic.getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the entry currently exists.
|
||||
*
|
||||
* @return True if the entry exists, false otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean exists() {
|
||||
return NetworkTablesJNI.getType(m_handle) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the entry (the key).
|
||||
*
|
||||
* @return the entry's name
|
||||
*/
|
||||
public String getName() {
|
||||
return NetworkTablesJNI.getEntryName(m_handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type of the entry.
|
||||
*
|
||||
* @return the entry's type
|
||||
*/
|
||||
public NetworkTableType getType() {
|
||||
return NetworkTableType.getFromInt(NetworkTablesJNI.getType(m_handle));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the flags.
|
||||
*
|
||||
* @return the flags (bitmask)
|
||||
* @deprecated Use isPersistent() or topic properties instead
|
||||
*/
|
||||
@Deprecated(since = "2022", forRemoval = true)
|
||||
public int getFlags() {
|
||||
return NetworkTablesJNI.getEntryFlags(m_handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the last time the entry's value was changed.
|
||||
*
|
||||
* @return Entry last change time
|
||||
*/
|
||||
@Override
|
||||
public long getLastChange() {
|
||||
return NetworkTablesJNI.getEntryLastChange(m_handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the entry's value. Returns a value with type NetworkTableType.kUnassigned if the value
|
||||
* does not exist.
|
||||
*
|
||||
* @return the entry's value
|
||||
*/
|
||||
public NetworkTableValue getValue() {
|
||||
return NetworkTablesJNI.getValue(m_handle);
|
||||
}
|
||||
{% for t in types %}
|
||||
/**
|
||||
* Gets the entry's value as a {{ t.java.ValueType }}. If the entry does not exist or is of different type, it
|
||||
* will return the default value.
|
||||
*
|
||||
* @param defaultValue the value to be returned if no value is found
|
||||
* @return the entry's value or the given default value
|
||||
*/
|
||||
public {{ t.java.ValueType }} get{{ t.TypeName }}({{ t.java.ValueType }} defaultValue) {
|
||||
return NetworkTablesJNI.get{{ t.TypeName }}(m_handle, defaultValue);
|
||||
}
|
||||
{% if t.java.WrapValueType %}
|
||||
/**
|
||||
* Gets the entry's value as a boolean array. If the entry does not exist or is of different type,
|
||||
* it will return the default value.
|
||||
*
|
||||
* @param defaultValue the value to be returned if no value is found
|
||||
* @return the entry's value or the given default value
|
||||
*/
|
||||
public {{ t.java.WrapValueType }} get{{ t.TypeName }}({{ t.java.WrapValueType }} defaultValue) {
|
||||
return NetworkTableValue.fromNative{{ t.TypeName }}(
|
||||
get{{ t.TypeName }}(NetworkTableValue.toNative{{ t.TypeName }}(defaultValue)));
|
||||
}
|
||||
{% endif -%}
|
||||
{% endfor %}
|
||||
/**
|
||||
* Gets the entry's value as a double. If the entry does not exist or is of different type, it
|
||||
* will return the default value.
|
||||
*
|
||||
* @param defaultValue the value to be returned if no value is found
|
||||
* @return the entry's value or the given default value
|
||||
*/
|
||||
public Number getNumber(Number defaultValue) {
|
||||
return getDouble(defaultValue.doubleValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the entry's value as a double array. If the entry does not exist or is of different type,
|
||||
* it will return the default value.
|
||||
*
|
||||
* @param defaultValue the value to be returned if no value is found
|
||||
* @return the entry's value or the given default value
|
||||
*/
|
||||
public Number[] getNumberArray(Number[] defaultValue) {
|
||||
return NetworkTableValue.fromNativeDoubleArray(
|
||||
getDoubleArray(NetworkTableValue.toNativeDoubleArray(defaultValue)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of all value changes since the last call to readQueue.
|
||||
*
|
||||
* <p>The "poll storage" subscribe option can be used to set the queue
|
||||
* depth.
|
||||
*
|
||||
* @return Array of values; empty array if no new changes have been
|
||||
* published since the previous call.
|
||||
*/
|
||||
public NetworkTableValue[] readQueue() {
|
||||
return NetworkTablesJNI.readQueueValue(m_handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a data value is of a type that can be placed in a NetworkTable entry.
|
||||
*
|
||||
* @param data the data to check
|
||||
* @return true if the data can be placed in an entry, false if it cannot
|
||||
*/
|
||||
public static boolean isValidDataType(Object data) {
|
||||
return data instanceof Number
|
||||
|| data instanceof Boolean
|
||||
|| data instanceof String
|
||||
|| data instanceof long[]
|
||||
|| data instanceof Long[]
|
||||
|| data instanceof float[]
|
||||
|| data instanceof Float[]
|
||||
|| data instanceof double[]
|
||||
|| data instanceof Double[]
|
||||
|| data instanceof Number[]
|
||||
|| data instanceof boolean[]
|
||||
|| data instanceof Boolean[]
|
||||
|| data instanceof String[]
|
||||
|| data instanceof byte[]
|
||||
|| data instanceof Byte[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the entry's value if it does not exist.
|
||||
*
|
||||
* @param defaultValue the default value to set
|
||||
* @return False if the entry exists with a different type
|
||||
* @throws IllegalArgumentException if the value is not a known type
|
||||
*/
|
||||
public boolean setDefaultValue(Object defaultValue) {
|
||||
if (defaultValue instanceof NetworkTableValue) {
|
||||
long time = ((NetworkTableValue) defaultValue).getTime();
|
||||
Object otherValue = ((NetworkTableValue) defaultValue).getValue();
|
||||
switch (((NetworkTableValue) defaultValue).getType()) {
|
||||
case kBoolean:
|
||||
return NetworkTablesJNI.setDefaultBoolean(m_handle, time, (Boolean) otherValue);
|
||||
case kInteger:
|
||||
return NetworkTablesJNI.setDefaultInteger(
|
||||
m_handle, time, ((Number) otherValue).longValue());
|
||||
case kFloat:
|
||||
return NetworkTablesJNI.setDefaultFloat(
|
||||
m_handle, time, ((Number) otherValue).floatValue());
|
||||
case kDouble:
|
||||
return NetworkTablesJNI.setDefaultDouble(
|
||||
m_handle, time, ((Number) otherValue).doubleValue());
|
||||
case kString:
|
||||
return NetworkTablesJNI.setDefaultString(m_handle, time, (String) otherValue);
|
||||
case kRaw:
|
||||
return NetworkTablesJNI.setDefaultRaw(m_handle, time, (byte[]) otherValue);
|
||||
case kBooleanArray:
|
||||
return NetworkTablesJNI.setDefaultBooleanArray(m_handle, time, (boolean[]) otherValue);
|
||||
case kIntegerArray:
|
||||
return NetworkTablesJNI.setDefaultIntegerArray(m_handle, time, (long[]) otherValue);
|
||||
case kFloatArray:
|
||||
return NetworkTablesJNI.setDefaultFloatArray(m_handle, time, (float[]) otherValue);
|
||||
case kDoubleArray:
|
||||
return NetworkTablesJNI.setDefaultDoubleArray(m_handle, time, (double[]) otherValue);
|
||||
case kStringArray:
|
||||
return NetworkTablesJNI.setDefaultStringArray(m_handle, time, (String[]) otherValue);
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
} else if (defaultValue instanceof Boolean) {
|
||||
return setDefaultBoolean((Boolean) defaultValue);
|
||||
} else if (defaultValue instanceof Integer) {
|
||||
return setDefaultInteger((Integer) defaultValue);
|
||||
} else if (defaultValue instanceof Float) {
|
||||
return setDefaultFloat((Float) defaultValue);
|
||||
} else if (defaultValue instanceof Number) {
|
||||
return setDefaultNumber((Number) defaultValue);
|
||||
} else if (defaultValue instanceof String) {
|
||||
return setDefaultString((String) defaultValue);
|
||||
} else if (defaultValue instanceof byte[]) {
|
||||
return setDefaultRaw((byte[]) defaultValue);
|
||||
} else if (defaultValue instanceof boolean[]) {
|
||||
return setDefaultBooleanArray((boolean[]) defaultValue);
|
||||
} else if (defaultValue instanceof long[]) {
|
||||
return setDefaultIntegerArray((long[]) defaultValue);
|
||||
} else if (defaultValue instanceof float[]) {
|
||||
return setDefaultFloatArray((float[]) defaultValue);
|
||||
} else if (defaultValue instanceof double[]) {
|
||||
return setDefaultDoubleArray((double[]) defaultValue);
|
||||
} else if (defaultValue instanceof Boolean[]) {
|
||||
return setDefaultBooleanArray((Boolean[]) defaultValue);
|
||||
} else if (defaultValue instanceof Long[]) {
|
||||
return setDefaultIntegerArray((Long[]) defaultValue);
|
||||
} else if (defaultValue instanceof Float[]) {
|
||||
return setDefaultFloatArray((Float[]) defaultValue);
|
||||
} else if (defaultValue instanceof Number[]) {
|
||||
return setDefaultNumberArray((Number[]) defaultValue);
|
||||
} else if (defaultValue instanceof String[]) {
|
||||
return setDefaultStringArray((String[]) defaultValue);
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
"Value of type " + defaultValue.getClass().getName() + " cannot be put into a table");
|
||||
}
|
||||
}
|
||||
{% for t in types %}
|
||||
/**
|
||||
* Sets the entry's value if it does not exist.
|
||||
*
|
||||
* @param defaultValue the default value to set
|
||||
* @return False if the entry exists with a different type
|
||||
*/
|
||||
public boolean setDefault{{ t.TypeName }}({{ t.java.ValueType }} defaultValue) {
|
||||
return NetworkTablesJNI.setDefault{{ t.TypeName }}(m_handle, 0, defaultValue);
|
||||
}
|
||||
{% if t.java.WrapValueType %}
|
||||
/**
|
||||
* Sets the entry's value if it does not exist.
|
||||
*
|
||||
* @param defaultValue the default value to set
|
||||
* @return False if the entry exists with a different type
|
||||
*/
|
||||
public boolean setDefault{{ t.TypeName }}({{ t.java.WrapValueType }} defaultValue) {
|
||||
return setDefault{{ t.TypeName }}(NetworkTableValue.toNative{{ t.TypeName }}(defaultValue));
|
||||
}
|
||||
{% endif -%}
|
||||
{% endfor %}
|
||||
/**
|
||||
* Sets the entry's value if it does not exist.
|
||||
*
|
||||
* @param defaultValue the default value to set
|
||||
* @return False if the entry exists with a different type
|
||||
*/
|
||||
public boolean setDefaultNumber(Number defaultValue) {
|
||||
return setDefaultDouble(defaultValue.doubleValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the entry's value if it does not exist.
|
||||
*
|
||||
* @param defaultValue the default value to set
|
||||
* @return False if the entry exists with a different type
|
||||
*/
|
||||
public boolean setDefaultNumberArray(Number[] defaultValue) {
|
||||
return setDefaultDoubleArray(NetworkTableValue.toNativeDoubleArray(defaultValue));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the entry's value.
|
||||
*
|
||||
* @param value the value that will be assigned
|
||||
* @return False if the table key already exists with a different type
|
||||
* @throws IllegalArgumentException if the value is not a known type
|
||||
*/
|
||||
public boolean setValue(Object value) {
|
||||
if (value instanceof NetworkTableValue) {
|
||||
long time = ((NetworkTableValue) value).getTime();
|
||||
Object otherValue = ((NetworkTableValue) value).getValue();
|
||||
switch (((NetworkTableValue) value).getType()) {
|
||||
case kBoolean:
|
||||
return NetworkTablesJNI.setBoolean(m_handle, time, (Boolean) otherValue);
|
||||
case kInteger:
|
||||
return NetworkTablesJNI.setInteger(
|
||||
m_handle, time, ((Number) otherValue).longValue());
|
||||
case kFloat:
|
||||
return NetworkTablesJNI.setFloat(
|
||||
m_handle, time, ((Number) otherValue).floatValue());
|
||||
case kDouble:
|
||||
return NetworkTablesJNI.setDouble(
|
||||
m_handle, time, ((Number) otherValue).doubleValue());
|
||||
case kString:
|
||||
return NetworkTablesJNI.setString(m_handle, time, (String) otherValue);
|
||||
case kRaw:
|
||||
return NetworkTablesJNI.setRaw(m_handle, time, (byte[]) otherValue);
|
||||
case kBooleanArray:
|
||||
return NetworkTablesJNI.setBooleanArray(m_handle, time, (boolean[]) otherValue);
|
||||
case kIntegerArray:
|
||||
return NetworkTablesJNI.setIntegerArray(m_handle, time, (long[]) otherValue);
|
||||
case kFloatArray:
|
||||
return NetworkTablesJNI.setFloatArray(m_handle, time, (float[]) otherValue);
|
||||
case kDoubleArray:
|
||||
return NetworkTablesJNI.setDoubleArray(m_handle, time, (double[]) otherValue);
|
||||
case kStringArray:
|
||||
return NetworkTablesJNI.setStringArray(m_handle, time, (String[]) otherValue);
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
} else if (value instanceof Boolean) {
|
||||
return setBoolean((Boolean) value);
|
||||
} else if (value instanceof Long) {
|
||||
return setInteger((Long) value);
|
||||
} else if (value instanceof Float) {
|
||||
return setFloat((Float) value);
|
||||
} else if (value instanceof Number) {
|
||||
return setNumber((Number) value);
|
||||
} else if (value instanceof String) {
|
||||
return setString((String) value);
|
||||
} else if (value instanceof byte[]) {
|
||||
return setRaw((byte[]) value);
|
||||
} else if (value instanceof boolean[]) {
|
||||
return setBooleanArray((boolean[]) value);
|
||||
} else if (value instanceof long[]) {
|
||||
return setIntegerArray((long[]) value);
|
||||
} else if (value instanceof float[]) {
|
||||
return setFloatArray((float[]) value);
|
||||
} else if (value instanceof double[]) {
|
||||
return setDoubleArray((double[]) value);
|
||||
} else if (value instanceof Boolean[]) {
|
||||
return setBooleanArray((Boolean[]) value);
|
||||
} else if (value instanceof Long[]) {
|
||||
return setIntegerArray((Long[]) value);
|
||||
} else if (value instanceof Float[]) {
|
||||
return setFloatArray((Float[]) value);
|
||||
} else if (value instanceof Number[]) {
|
||||
return setNumberArray((Number[]) value);
|
||||
} else if (value instanceof String[]) {
|
||||
return setStringArray((String[]) value);
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
"Value of type " + value.getClass().getName() + " cannot be put into a table");
|
||||
}
|
||||
}
|
||||
{% for t in types %}
|
||||
/**
|
||||
* Sets the entry's value.
|
||||
*
|
||||
* @param value the value to set
|
||||
* @return False if the entry exists with a different type
|
||||
*/
|
||||
public boolean set{{ t.TypeName }}({{ t.java.ValueType }} value) {
|
||||
return NetworkTablesJNI.set{{ t.TypeName }}(m_handle, 0, value);
|
||||
}
|
||||
{% if t.java.WrapValueType %}
|
||||
/**
|
||||
* Sets the entry's value.
|
||||
*
|
||||
* @param value the value to set
|
||||
* @return False if the entry exists with a different type
|
||||
*/
|
||||
public boolean set{{ t.TypeName }}({{ t.java.WrapValueType }} value) {
|
||||
return set{{ t.TypeName }}(NetworkTableValue.toNative{{ t.TypeName }}(value));
|
||||
}
|
||||
{% endif -%}
|
||||
{% endfor %}
|
||||
/**
|
||||
* Sets the entry's value.
|
||||
*
|
||||
* @param value the value to set
|
||||
* @return False if the entry exists with a different type
|
||||
*/
|
||||
public boolean setNumber(Number value) {
|
||||
return setDouble(value.doubleValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the entry's value.
|
||||
*
|
||||
* @param value the value to set
|
||||
* @return False if the entry exists with a different type
|
||||
*/
|
||||
public boolean setNumberArray(Number[] value) {
|
||||
return setDoubleArray(NetworkTableValue.toNativeDoubleArray(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets flags.
|
||||
*
|
||||
* @param flags the flags to set (bitmask)
|
||||
* @deprecated Use setPersistent() or topic properties instead
|
||||
*/
|
||||
@Deprecated(since = "2022", forRemoval = true)
|
||||
public void setFlags(int flags) {
|
||||
NetworkTablesJNI.setEntryFlags(m_handle, getFlags() | flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears flags.
|
||||
*
|
||||
* @param flags the flags to clear (bitmask)
|
||||
* @deprecated Use setPersistent() or topic properties instead
|
||||
*/
|
||||
@Deprecated(since = "2022", forRemoval = true)
|
||||
public void clearFlags(int flags) {
|
||||
NetworkTablesJNI.setEntryFlags(m_handle, getFlags() & ~flags);
|
||||
}
|
||||
|
||||
/** Make value persistent through program restarts. */
|
||||
public void setPersistent() {
|
||||
NetworkTablesJNI.setTopicPersistent(m_topic.getHandle(), true);
|
||||
}
|
||||
|
||||
/** Stop making value persistent through program restarts. */
|
||||
public void clearPersistent() {
|
||||
NetworkTablesJNI.setTopicPersistent(m_topic.getHandle(), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the value is persistent through program restarts.
|
||||
*
|
||||
* @return True if the value is persistent.
|
||||
*/
|
||||
public boolean isPersistent() {
|
||||
return NetworkTablesJNI.getTopicPersistent(m_topic.getHandle());
|
||||
}
|
||||
|
||||
/** Stops publishing the entry if it's been published. */
|
||||
public void unpublish() {
|
||||
NetworkTablesJNI.unpublish(m_handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the entry.
|
||||
*
|
||||
* @deprecated Use unpublish() instead.
|
||||
*/
|
||||
@Deprecated(since = "2022", forRemoval = true)
|
||||
public void delete() {
|
||||
unpublish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(other instanceof NetworkTableEntry)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return m_handle == ((NetworkTableEntry) other).m_handle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return m_handle;
|
||||
}
|
||||
|
||||
private final Topic m_topic;
|
||||
protected int m_handle;
|
||||
}
|
||||
852
ntcore/src/generate/java/NetworkTableInstance.java.jinja
Normal file
852
ntcore/src/generate/java/NetworkTableInstance.java.jinja
Normal file
@@ -0,0 +1,852 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
package edu.wpi.first.networktables;
|
||||
|
||||
import edu.wpi.first.util.WPIUtilJNI;
|
||||
import edu.wpi.first.util.datalog.DataLog;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* NetworkTables Instance.
|
||||
*
|
||||
* <p>Instances are completely independent from each other. Table operations on one instance will
|
||||
* not be visible to other instances unless the instances are connected via the network. The main
|
||||
* limitation on instances is that you cannot have two servers on the same network port. The main
|
||||
* utility of instances is for unit testing, but they can also enable one program to connect to two
|
||||
* different NetworkTables networks.
|
||||
*
|
||||
* <p>The global "default" instance (as returned by {@link #getDefault()}) is always available, and
|
||||
* is intended for the common case when there is only a single NetworkTables instance being used in
|
||||
* the program.
|
||||
*
|
||||
* <p>Additional instances can be created with the {@link #create()} function. A reference must be
|
||||
* kept to the NetworkTableInstance returned by this function to keep it from being garbage
|
||||
* collected.
|
||||
*/
|
||||
public final class NetworkTableInstance implements AutoCloseable {
|
||||
/**
|
||||
* Client/server mode flag values (as returned by {@link #getNetworkMode()}). This is a bitmask.
|
||||
*/
|
||||
public static final int kNetModeNone = 0x00;
|
||||
|
||||
public static final int kNetModeServer = 0x01;
|
||||
public static final int kNetModeClient3 = 0x02;
|
||||
public static final int kNetModeClient4 = 0x04;
|
||||
public static final int kNetModeStarting = 0x08;
|
||||
public static final int kNetModeLocal = 0x10;
|
||||
|
||||
/** The default port that network tables operates on for NT3. */
|
||||
public static final int kDefaultPort3 = 1735;
|
||||
|
||||
/** The default port that network tables operates on for NT4. */
|
||||
public static final int kDefaultPort4 = 5810;
|
||||
|
||||
/**
|
||||
* Construct from native handle.
|
||||
*
|
||||
* @param handle Native handle
|
||||
*/
|
||||
private NetworkTableInstance(int handle) {
|
||||
m_owned = false;
|
||||
m_handle = handle;
|
||||
}
|
||||
|
||||
/** Destroys the instance (if created by {@link #create()}). */
|
||||
@Override
|
||||
public synchronized void close() {
|
||||
if (m_owned && m_handle != 0) {
|
||||
NetworkTablesJNI.destroyInstance(m_handle);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the native handle is valid.
|
||||
*
|
||||
* @return True if the native handle is valid, false otherwise.
|
||||
*/
|
||||
public boolean isValid() {
|
||||
return m_handle != 0;
|
||||
}
|
||||
|
||||
/* The default instance. */
|
||||
private static NetworkTableInstance s_defaultInstance;
|
||||
|
||||
/**
|
||||
* Get global default instance.
|
||||
*
|
||||
* @return Global default instance
|
||||
*/
|
||||
public static synchronized NetworkTableInstance getDefault() {
|
||||
if (s_defaultInstance == null) {
|
||||
s_defaultInstance = new NetworkTableInstance(NetworkTablesJNI.getDefaultInstance());
|
||||
}
|
||||
return s_defaultInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance. Note: A reference to the returned instance must be retained to ensure the
|
||||
* instance is not garbage collected.
|
||||
*
|
||||
* @return Newly created instance
|
||||
*/
|
||||
public static NetworkTableInstance create() {
|
||||
NetworkTableInstance inst = new NetworkTableInstance(NetworkTablesJNI.createInstance());
|
||||
inst.m_owned = true;
|
||||
return inst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the native handle for the instance.
|
||||
*
|
||||
* @return Native handle
|
||||
*/
|
||||
public int getHandle() {
|
||||
return m_handle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get (generic) topic.
|
||||
*
|
||||
* @param name topic name
|
||||
* @return Topic
|
||||
*/
|
||||
public Topic getTopic(String name) {
|
||||
Topic topic = m_topics.get(name);
|
||||
if (topic == null) {
|
||||
int handle = NetworkTablesJNI.getTopic(m_handle, name);
|
||||
topic = new Topic(this, handle);
|
||||
Topic oldTopic = m_topics.putIfAbsent(name, topic);
|
||||
if (oldTopic != null) {
|
||||
topic = oldTopic;
|
||||
}
|
||||
// also cache by handle
|
||||
m_topicsByHandle.putIfAbsent(handle, topic);
|
||||
}
|
||||
return topic;
|
||||
}
|
||||
{% for t in types %}
|
||||
/**
|
||||
* Get {{ t.java.ValueType }} topic.
|
||||
*
|
||||
* @param name topic name
|
||||
* @return {{ t.TypeName }}Topic
|
||||
*/
|
||||
public {{ t.TypeName }}Topic get{{ t.TypeName }}Topic(String name) {
|
||||
Topic topic = m_topics.get(name);
|
||||
if (topic instanceof {{ t.TypeName }}Topic) {
|
||||
return ({{ t.TypeName }}Topic) topic;
|
||||
}
|
||||
|
||||
int handle;
|
||||
if (topic == null) {
|
||||
handle = NetworkTablesJNI.getTopic(m_handle, name);
|
||||
} else {
|
||||
handle = topic.getHandle();
|
||||
}
|
||||
|
||||
topic = new {{ t.TypeName }}Topic(this, handle);
|
||||
m_topics.put(name, topic);
|
||||
|
||||
// also cache by handle
|
||||
m_topicsByHandle.put(handle, topic);
|
||||
|
||||
return ({{ t.TypeName }}Topic) topic;
|
||||
}
|
||||
{% endfor %}
|
||||
private Topic[] topicHandlesToTopics(int[] handles) {
|
||||
Topic[] topics = new Topic[handles.length];
|
||||
for (int i = 0; i < handles.length; i++) {
|
||||
topics[i] = getCachedTopic(handles[i]);
|
||||
}
|
||||
return topics;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all published topics.
|
||||
*
|
||||
* @return Array of topics.
|
||||
*/
|
||||
public Topic[] getTopics() {
|
||||
return topicHandlesToTopics(NetworkTablesJNI.getTopics(m_handle, "", 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get published topics starting with the given prefix. The results are optionally filtered by
|
||||
* string prefix to only return a subset of all topics.
|
||||
*
|
||||
* @param prefix topic name required prefix; only topics whose name starts with this string are
|
||||
* returned
|
||||
* @return Array of topic information.
|
||||
*/
|
||||
public Topic[] getTopics(String prefix) {
|
||||
return topicHandlesToTopics(NetworkTablesJNI.getTopics(m_handle, prefix, 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get published topics starting with the given prefix. The results are optionally filtered by
|
||||
* string prefix and data type to only return a subset of all topics.
|
||||
*
|
||||
* @param prefix topic name required prefix; only topics whose name starts with this string are
|
||||
* returned
|
||||
* @param types bitmask of data types; 0 is treated as a "don't care"
|
||||
* @return Array of topic information.
|
||||
*/
|
||||
public Topic[] getTopics(String prefix, int types) {
|
||||
return topicHandlesToTopics(NetworkTablesJNI.getTopics(m_handle, prefix, types));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get published topics starting with the given prefix. The results are optionally filtered by
|
||||
* string prefix and data type to only return a subset of all topics.
|
||||
*
|
||||
* @param prefix topic name required prefix; only topics whose name starts with this string are
|
||||
* returned
|
||||
* @param types array of data type strings
|
||||
* @return Array of topic information.
|
||||
*/
|
||||
public Topic[] getTopics(String prefix, String[] types) {
|
||||
return topicHandlesToTopics(NetworkTablesJNI.getTopicsStr(m_handle, prefix, types));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get information about all topics.
|
||||
*
|
||||
* @return Array of topic information.
|
||||
*/
|
||||
public TopicInfo[] getTopicInfo() {
|
||||
return NetworkTablesJNI.getTopicInfos(this, m_handle, "", 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get information about topics starting with the given prefix. The results are optionally
|
||||
* filtered by string prefix to only return a subset of all topics.
|
||||
*
|
||||
* @param prefix topic name required prefix; only topics whose name starts with this string are
|
||||
* returned
|
||||
* @return Array of topic information.
|
||||
*/
|
||||
public TopicInfo[] getTopicInfo(String prefix) {
|
||||
return NetworkTablesJNI.getTopicInfos(this, m_handle, prefix, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get information about topics starting with the given prefix. The results are optionally
|
||||
* filtered by string prefix and data type to only return a subset of all topics.
|
||||
*
|
||||
* @param prefix topic name required prefix; only topics whose name starts with this string are
|
||||
* returned
|
||||
* @param types bitmask of data types; 0 is treated as a "don't care"
|
||||
* @return Array of topic information.
|
||||
*/
|
||||
public TopicInfo[] getTopicInfo(String prefix, int types) {
|
||||
return NetworkTablesJNI.getTopicInfos(this, m_handle, prefix, types);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get information about topics starting with the given prefix. The results are optionally
|
||||
* filtered by string prefix and data type to only return a subset of all topics.
|
||||
*
|
||||
* @param prefix topic name required prefix; only topics whose name starts with this string are
|
||||
* returned
|
||||
* @param types array of data type strings
|
||||
* @return Array of topic information.
|
||||
*/
|
||||
public TopicInfo[] getTopicInfo(String prefix, String[] types) {
|
||||
return NetworkTablesJNI.getTopicInfosStr(this, m_handle, prefix, types);
|
||||
}
|
||||
|
||||
/* Cache of created entries. */
|
||||
private final ConcurrentMap<String, NetworkTableEntry> m_entries = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Gets the entry for a key.
|
||||
*
|
||||
* @param name Key
|
||||
* @return Network table entry.
|
||||
*/
|
||||
public NetworkTableEntry getEntry(String name) {
|
||||
NetworkTableEntry entry = m_entries.get(name);
|
||||
if (entry == null) {
|
||||
entry = new NetworkTableEntry(this, NetworkTablesJNI.getEntry(m_handle, name));
|
||||
NetworkTableEntry oldEntry = m_entries.putIfAbsent(name, entry);
|
||||
if (oldEntry != null) {
|
||||
entry = oldEntry;
|
||||
}
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
/* Cache of created topics. */
|
||||
private final ConcurrentMap<String, Topic> m_topics = new ConcurrentHashMap<>();
|
||||
private final ConcurrentMap<Integer, Topic> m_topicsByHandle = new ConcurrentHashMap<>();
|
||||
|
||||
Topic getCachedTopic(String name) {
|
||||
Topic topic = m_topics.get(name);
|
||||
if (topic == null) {
|
||||
int handle = NetworkTablesJNI.getTopic(m_handle, name);
|
||||
topic = new Topic(this, handle);
|
||||
Topic oldTopic = m_topics.putIfAbsent(name, topic);
|
||||
if (oldTopic != null) {
|
||||
topic = oldTopic;
|
||||
}
|
||||
// also cache by handle
|
||||
m_topicsByHandle.putIfAbsent(handle, topic);
|
||||
}
|
||||
return topic;
|
||||
}
|
||||
|
||||
Topic getCachedTopic(int handle) {
|
||||
Topic topic = m_topicsByHandle.get(handle);
|
||||
if (topic == null) {
|
||||
topic = new Topic(this, handle);
|
||||
Topic oldTopic = m_topicsByHandle.putIfAbsent(handle, topic);
|
||||
if (oldTopic != null) {
|
||||
topic = oldTopic;
|
||||
}
|
||||
}
|
||||
return topic;
|
||||
}
|
||||
|
||||
/* Cache of created tables. */
|
||||
private final ConcurrentMap<String, NetworkTable> m_tables = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Gets the table with the specified key.
|
||||
*
|
||||
* @param key the key name
|
||||
* @return The network table
|
||||
*/
|
||||
public NetworkTable getTable(String key) {
|
||||
// prepend leading / if not present
|
||||
String theKey;
|
||||
if (key.isEmpty() || "/".equals(key)) {
|
||||
theKey = "";
|
||||
} else if (key.charAt(0) == NetworkTable.PATH_SEPARATOR) {
|
||||
theKey = key;
|
||||
} else {
|
||||
theKey = NetworkTable.PATH_SEPARATOR + key;
|
||||
}
|
||||
|
||||
// cache created tables
|
||||
NetworkTable table = m_tables.get(theKey);
|
||||
if (table == null) {
|
||||
table = new NetworkTable(this, theKey);
|
||||
NetworkTable oldTable = m_tables.putIfAbsent(theKey, table);
|
||||
if (oldTable != null) {
|
||||
table = oldTable;
|
||||
}
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback Creation Functions
|
||||
*/
|
||||
|
||||
private final ReentrantLock m_connectionListenerLock = new ReentrantLock();
|
||||
private final Map<Integer, Consumer<ConnectionNotification>> m_connectionListeners =
|
||||
new HashMap<>();
|
||||
private int m_connectionListenerPoller;
|
||||
|
||||
@SuppressWarnings("PMD.AvoidCatchingThrowable")
|
||||
private void startConnectionListenerThread() {
|
||||
var connectionListenerThread =
|
||||
new Thread(
|
||||
() -> {
|
||||
boolean wasInterrupted = false;
|
||||
while (!Thread.interrupted()) {
|
||||
try {
|
||||
WPIUtilJNI.waitForObject(m_connectionListenerPoller);
|
||||
} catch (InterruptedException ex) {
|
||||
Thread.currentThread().interrupt();
|
||||
// don't try to destroy poller, as its handle is likely no longer valid
|
||||
wasInterrupted = true;
|
||||
break;
|
||||
}
|
||||
ConnectionNotification[] events =
|
||||
NetworkTablesJNI.readConnectionListenerQueue(this, m_connectionListenerPoller);
|
||||
for (ConnectionNotification event : events) {
|
||||
Consumer<ConnectionNotification> listener;
|
||||
m_connectionListenerLock.lock();
|
||||
try {
|
||||
listener = m_connectionListeners.get(event.listener);
|
||||
} finally {
|
||||
m_connectionListenerLock.unlock();
|
||||
}
|
||||
if (listener != null) {
|
||||
try {
|
||||
listener.accept(event);
|
||||
} catch (Throwable throwable) {
|
||||
System.err.println(
|
||||
"Unhandled exception during connection listener callback: "
|
||||
+ throwable.toString());
|
||||
throwable.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
m_connectionListenerLock.lock();
|
||||
try {
|
||||
if (!wasInterrupted) {
|
||||
NetworkTablesJNI.destroyConnectionListenerPoller(m_connectionListenerPoller);
|
||||
}
|
||||
m_connectionListenerPoller = 0;
|
||||
} finally {
|
||||
m_connectionListenerLock.unlock();
|
||||
}
|
||||
},
|
||||
"NTConnectionListener");
|
||||
connectionListenerThread.setDaemon(true);
|
||||
connectionListenerThread.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a connection listener.
|
||||
*
|
||||
* @param listener Listener to add
|
||||
* @param immediateNotify Notify listener of all existing connections
|
||||
* @return Listener handle
|
||||
*/
|
||||
public int addConnectionListener(
|
||||
Consumer<ConnectionNotification> listener, boolean immediateNotify) {
|
||||
m_connectionListenerLock.lock();
|
||||
try {
|
||||
if (m_connectionListenerPoller == 0) {
|
||||
m_connectionListenerPoller = NetworkTablesJNI.createConnectionListenerPoller(m_handle);
|
||||
startConnectionListenerThread();
|
||||
}
|
||||
int handle =
|
||||
NetworkTablesJNI.addPolledConnectionListener(m_connectionListenerPoller, immediateNotify);
|
||||
m_connectionListeners.put(handle, listener);
|
||||
return handle;
|
||||
} finally {
|
||||
m_connectionListenerLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a connection listener.
|
||||
*
|
||||
* @param listener Listener handle to remove
|
||||
*/
|
||||
public void removeConnectionListener(int listener) {
|
||||
m_connectionListenerLock.lock();
|
||||
try {
|
||||
m_connectionListeners.remove(listener);
|
||||
} finally {
|
||||
m_connectionListenerLock.unlock();
|
||||
}
|
||||
NetworkTablesJNI.removeConnectionListener(listener);
|
||||
}
|
||||
|
||||
/*
|
||||
* Client/Server Functions
|
||||
*/
|
||||
|
||||
/**
|
||||
* Set the network identity of this node. This is the name used during the initial connection
|
||||
* handshake, and is visible through ConnectionInfo on the remote node.
|
||||
*
|
||||
* @param name identity to advertise
|
||||
*/
|
||||
public void setNetworkIdentity(String name) {
|
||||
NetworkTablesJNI.setNetworkIdentity(m_handle, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current network mode.
|
||||
*
|
||||
* @return Bitmask of NetworkMode.
|
||||
*/
|
||||
public int getNetworkMode() {
|
||||
return NetworkTablesJNI.getNetworkMode(m_handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts local-only operation. Prevents calls to startServer or startClient from taking effect.
|
||||
* Has no effect if startServer or startClient has already been called.
|
||||
*/
|
||||
public void startLocal() {
|
||||
NetworkTablesJNI.startLocal(m_handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops local-only operation. startServer or startClient can be called after this call to start a
|
||||
* server or client.
|
||||
*/
|
||||
public void stopLocal() {
|
||||
NetworkTablesJNI.stopLocal(m_handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a server using the networktables.json as the persistent file, using the default
|
||||
* listening address and port.
|
||||
*/
|
||||
public void startServer() {
|
||||
startServer("networktables.json");
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a server using the specified persistent filename, using the default listening address
|
||||
* and port.
|
||||
*
|
||||
* @param persistFilename the name of the persist file to use
|
||||
*/
|
||||
public void startServer(String persistFilename) {
|
||||
startServer(persistFilename, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a server using the specified filename and listening address, using the default port.
|
||||
*
|
||||
* @param persistFilename the name of the persist file to use
|
||||
* @param listenAddress the address to listen on, or empty to listen on any address
|
||||
*/
|
||||
public void startServer(String persistFilename, String listenAddress) {
|
||||
startServer(persistFilename, listenAddress, kDefaultPort3, kDefaultPort4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a server using the specified filename, listening address, and port.
|
||||
*
|
||||
* @param persistFilename the name of the persist file to use
|
||||
* @param listenAddress the address to listen on, or empty to listen on any address
|
||||
* @param port3 port to communicate over (NT3)
|
||||
*/
|
||||
public void startServer(String persistFilename, String listenAddress, int port3) {
|
||||
startServer(persistFilename, listenAddress, port3, kDefaultPort4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a server using the specified filename, listening address, and port.
|
||||
*
|
||||
* @param persistFilename the name of the persist file to use
|
||||
* @param listenAddress the address to listen on, or empty to listen on any address
|
||||
* @param port3 port to communicate over (NT3)
|
||||
* @param port4 port to communicate over (NT4)
|
||||
*/
|
||||
public void startServer(String persistFilename, String listenAddress, int port3, int port4) {
|
||||
NetworkTablesJNI.startServer(m_handle, persistFilename, listenAddress, port3, port4);
|
||||
}
|
||||
|
||||
/** Stops the server if it is running. */
|
||||
public void stopServer() {
|
||||
NetworkTablesJNI.stopServer(m_handle);
|
||||
}
|
||||
|
||||
/** Starts a NT3 client. Use SetServer or SetServerTeam to set the server name and port. */
|
||||
public void startClient3() {
|
||||
NetworkTablesJNI.startClient3(m_handle);
|
||||
}
|
||||
|
||||
/** Starts a NT4 client. Use SetServer or SetServerTeam to set the server name and port. */
|
||||
public void startClient4() {
|
||||
NetworkTablesJNI.startClient4(m_handle);
|
||||
}
|
||||
|
||||
/** Stops the client if it is running. */
|
||||
public void stopClient() {
|
||||
NetworkTablesJNI.stopClient(m_handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets server address and port for client (without restarting client). Changes the port to the
|
||||
* default port.
|
||||
*
|
||||
* @param serverName server name
|
||||
*/
|
||||
public void setServer(String serverName) {
|
||||
setServer(serverName, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets server address and port for client (without restarting client).
|
||||
*
|
||||
* @param serverName server name
|
||||
* @param port port to communicate over (0=default)
|
||||
*/
|
||||
public void setServer(String serverName, int port) {
|
||||
NetworkTablesJNI.setServer(m_handle, serverName, port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets server addresses and port for client (without restarting client). Changes the port to the
|
||||
* default port. The client will attempt to connect to each server in round robin fashion.
|
||||
*
|
||||
* @param serverNames array of server names
|
||||
*/
|
||||
public void setServer(String[] serverNames) {
|
||||
setServer(serverNames, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets server addresses and port for client (without restarting client). The client will attempt
|
||||
* to connect to each server in round robin fashion.
|
||||
*
|
||||
* @param serverNames array of server names
|
||||
* @param port port to communicate over (0=default)
|
||||
*/
|
||||
public void setServer(String[] serverNames, int port) {
|
||||
int[] ports = new int[serverNames.length];
|
||||
for (int i = 0; i < serverNames.length; i++) {
|
||||
ports[i] = port;
|
||||
}
|
||||
setServer(serverNames, ports);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets server addresses and ports for client (without restarting client). The client will attempt
|
||||
* to connect to each server in round robin fashion.
|
||||
*
|
||||
* @param serverNames array of server names
|
||||
* @param ports array of port numbers (0=default)
|
||||
*/
|
||||
public void setServer(String[] serverNames, int[] ports) {
|
||||
NetworkTablesJNI.setServer(m_handle, serverNames, ports);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets server addresses and port for client (without restarting client). Changes the port to the
|
||||
* default port. The client will attempt to connect to each server in round robin fashion.
|
||||
*
|
||||
* @param team team number
|
||||
*/
|
||||
public void setServerTeam(int team) {
|
||||
setServerTeam(team, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets server addresses and port for client (without restarting client). Connects using commonly
|
||||
* known robot addresses for the specified team.
|
||||
*
|
||||
* @param team team number
|
||||
* @param port port to communicate over (0=default)
|
||||
*/
|
||||
public void setServerTeam(int team, int port) {
|
||||
NetworkTablesJNI.setServerTeam(m_handle, team, port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts requesting server address from Driver Station. This connects to the Driver Station
|
||||
* running on localhost to obtain the server IP address, and connects with the default port.
|
||||
*/
|
||||
public void startDSClient() {
|
||||
startDSClient(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts requesting server address from Driver Station. This connects to the Driver Station
|
||||
* running on localhost to obtain the server IP address.
|
||||
*
|
||||
* @param port server port to use in combination with IP from DS (0=default)
|
||||
*/
|
||||
public void startDSClient(int port) {
|
||||
NetworkTablesJNI.startDSClient(m_handle, port);
|
||||
}
|
||||
|
||||
/** Stops requesting server address from Driver Station. */
|
||||
public void stopDSClient() {
|
||||
NetworkTablesJNI.stopDSClient(m_handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes all updated values immediately to the local client/server. This does not flush to the
|
||||
* network.
|
||||
*/
|
||||
public void flushLocal() {
|
||||
NetworkTablesJNI.flushLocal(m_handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes all updated values immediately to the network. Note: This is rate-limited to protect
|
||||
* the network from flooding. This is primarily useful for synchronizing network updates with user
|
||||
* code.
|
||||
*/
|
||||
public void flush() {
|
||||
NetworkTablesJNI.flush(m_handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets information on the currently established network connections. If operating as a client,
|
||||
* this will return either zero or one values.
|
||||
*
|
||||
* @return array of connection information
|
||||
*/
|
||||
public ConnectionInfo[] getConnections() {
|
||||
return NetworkTablesJNI.getConnections(m_handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether or not the instance is connected to another node.
|
||||
*
|
||||
* @return True if connected.
|
||||
*/
|
||||
public boolean isConnected() {
|
||||
return NetworkTablesJNI.isConnected(m_handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts logging entry changes to a DataLog.
|
||||
*
|
||||
* @param log data log object; lifetime must extend until StopEntryDataLog is called or the
|
||||
* instance is destroyed
|
||||
* @param prefix only store entries with names that start with this prefix; the prefix is not
|
||||
* included in the data log entry name
|
||||
* @param logPrefix prefix to add to data log entry names
|
||||
* @return Data logger handle
|
||||
*/
|
||||
public int startEntryDataLog(DataLog log, String prefix, String logPrefix) {
|
||||
return NetworkTablesJNI.startEntryDataLog(m_handle, log, prefix, logPrefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops logging entry changes to a DataLog.
|
||||
*
|
||||
* @param logger data logger handle
|
||||
*/
|
||||
public static void stopEntryDataLog(int logger) {
|
||||
NetworkTablesJNI.stopEntryDataLog(logger);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts logging connection changes to a DataLog.
|
||||
*
|
||||
* @param log data log object; lifetime must extend until StopConnectionDataLog is called or the
|
||||
* instance is destroyed
|
||||
* @param name data log entry name
|
||||
* @return Data logger handle
|
||||
*/
|
||||
public int startConnectionDataLog(DataLog log, String name) {
|
||||
return NetworkTablesJNI.startConnectionDataLog(m_handle, log, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops logging connection changes to a DataLog.
|
||||
*
|
||||
* @param logger data logger handle
|
||||
*/
|
||||
public static void stopConnectionDataLog(int logger) {
|
||||
NetworkTablesJNI.stopConnectionDataLog(logger);
|
||||
}
|
||||
|
||||
private final ReentrantLock m_loggerLock = new ReentrantLock();
|
||||
private final Map<Integer, Consumer<LogMessage>> m_loggers = new HashMap<>();
|
||||
private int m_loggerPoller;
|
||||
|
||||
@SuppressWarnings("PMD.AvoidCatchingThrowable")
|
||||
private void startLogThread() {
|
||||
var loggerThread =
|
||||
new Thread(
|
||||
() -> {
|
||||
boolean wasInterrupted = false;
|
||||
while (!Thread.interrupted()) {
|
||||
try {
|
||||
WPIUtilJNI.waitForObject(m_loggerPoller);
|
||||
} catch (InterruptedException ex) {
|
||||
Thread.currentThread().interrupt();
|
||||
// don't try to destroy poller, as its handle is likely no longer valid
|
||||
wasInterrupted = true;
|
||||
break;
|
||||
}
|
||||
LogMessage[] events = NetworkTablesJNI.readLoggerQueue(this, m_loggerPoller);
|
||||
for (LogMessage event : events) {
|
||||
Consumer<LogMessage> logger;
|
||||
m_loggerLock.lock();
|
||||
try {
|
||||
logger = m_loggers.get(event.logger);
|
||||
} finally {
|
||||
m_loggerLock.unlock();
|
||||
}
|
||||
if (logger != null) {
|
||||
try {
|
||||
logger.accept(event);
|
||||
} catch (Throwable throwable) {
|
||||
System.err.println(
|
||||
"Unhandled exception during logger callback: " + throwable.toString());
|
||||
throwable.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
m_loggerLock.lock();
|
||||
try {
|
||||
if (!wasInterrupted) {
|
||||
NetworkTablesJNI.destroyLoggerPoller(m_loggerPoller);
|
||||
}
|
||||
} finally {
|
||||
m_loggerLock.unlock();
|
||||
}
|
||||
},
|
||||
"NTLogger");
|
||||
loggerThread.setDaemon(true);
|
||||
loggerThread.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add logger callback function. By default, log messages are sent to stderr; this function sends
|
||||
* log messages with the specified levels to the provided callback function instead. The callback
|
||||
* function will only be called for log messages with level greater than or equal to minLevel and
|
||||
* less than or equal to maxLevel; messages outside this range will be silently ignored.
|
||||
*
|
||||
* @param func log callback function
|
||||
* @param minLevel minimum log level
|
||||
* @param maxLevel maximum log level
|
||||
* @return Logger handle
|
||||
*/
|
||||
public int addLogger(Consumer<LogMessage> func, int minLevel, int maxLevel) {
|
||||
m_loggerLock.lock();
|
||||
try {
|
||||
if (m_loggerPoller == 0) {
|
||||
m_loggerPoller = NetworkTablesJNI.createLoggerPoller(m_handle);
|
||||
startLogThread();
|
||||
}
|
||||
int handle = NetworkTablesJNI.addPolledLogger(m_loggerPoller, minLevel, maxLevel);
|
||||
m_loggers.put(handle, func);
|
||||
return handle;
|
||||
} finally {
|
||||
m_loggerLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a logger.
|
||||
*
|
||||
* @param logger Logger handle to remove
|
||||
*/
|
||||
public void removeLogger(int logger) {
|
||||
m_loggerLock.lock();
|
||||
try {
|
||||
m_loggers.remove(logger);
|
||||
} finally {
|
||||
m_loggerLock.unlock();
|
||||
}
|
||||
NetworkTablesJNI.removeLogger(logger);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(other instanceof NetworkTableInstance)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return m_handle == ((NetworkTableInstance) other).m_handle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return m_handle;
|
||||
}
|
||||
|
||||
private boolean m_owned;
|
||||
private final int m_handle;
|
||||
}
|
||||
248
ntcore/src/generate/java/NetworkTableValue.java.jinja
Normal file
248
ntcore/src/generate/java/NetworkTableValue.java.jinja
Normal file
@@ -0,0 +1,248 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
package edu.wpi.first.networktables;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/** A network table entry value. */
|
||||
@SuppressWarnings({"UnnecessaryParentheses", "PMD.MethodReturnsInternalArray"})
|
||||
public final class NetworkTableValue {
|
||||
NetworkTableValue(NetworkTableType type, Object value, long time, long serverTime) {
|
||||
m_type = type;
|
||||
m_value = value;
|
||||
m_time = time;
|
||||
m_serverTime = serverTime;
|
||||
}
|
||||
|
||||
NetworkTableValue(NetworkTableType type, Object value, long time) {
|
||||
this(type, value, time, time == 0 ? 0 : 1);
|
||||
}
|
||||
|
||||
NetworkTableValue(NetworkTableType type, Object value) {
|
||||
this(type, value, NetworkTablesJNI.now(), 1);
|
||||
}
|
||||
|
||||
NetworkTableValue(int type, Object value, long time, long serverTime) {
|
||||
this(NetworkTableType.getFromInt(type), value, time, serverTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data type.
|
||||
*
|
||||
* @return The type.
|
||||
*/
|
||||
public NetworkTableType getType() {
|
||||
return m_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data value stored.
|
||||
*
|
||||
* @return The type.
|
||||
*/
|
||||
public Object getValue() {
|
||||
return m_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the creation time of the value in local time.
|
||||
*
|
||||
* @return The time, in the units returned by NetworkTablesJNI.now().
|
||||
*/
|
||||
public long getTime() {
|
||||
return m_time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the creation time of the value in server time.
|
||||
*
|
||||
* @return The server time.
|
||||
*/
|
||||
public long getServerTime() {
|
||||
return m_serverTime;
|
||||
}
|
||||
|
||||
/*
|
||||
* Type Checkers
|
||||
*/
|
||||
|
||||
/**
|
||||
* Determine if entry value contains a value or is unassigned.
|
||||
*
|
||||
* @return True if the entry value contains a value.
|
||||
*/
|
||||
public boolean isValid() {
|
||||
return m_type != NetworkTableType.kUnassigned;
|
||||
}
|
||||
{% for t in types %}
|
||||
/**
|
||||
* Determine if entry value contains a {{ t.java.ValueType }}.
|
||||
*
|
||||
* @return True if the entry value is of {{ t.java.ValueType }} type.
|
||||
*/
|
||||
public boolean is{{ t.TypeName }}() {
|
||||
return m_type == NetworkTableType.k{{ t.TypeName }};
|
||||
}
|
||||
{% endfor %}
|
||||
/*
|
||||
* Type-Safe Getters
|
||||
*/
|
||||
{% for t in types %}
|
||||
/**
|
||||
* Get the {{ t.java.ValueType }} value.
|
||||
*
|
||||
* @return The {{ t.java.ValueType }} value.
|
||||
* @throws ClassCastException if the entry value is not of {{ t.java.ValueType }} type.
|
||||
*/
|
||||
public {{ t.java.ValueType }} get{{ t.TypeName }}() {
|
||||
if (m_type != NetworkTableType.k{{ t.TypeName }}) {
|
||||
throw new ClassCastException("cannot convert " + m_type + " to {{ t.java.ValueType }}");
|
||||
}
|
||||
return {{ t.java.FromStorageBegin }}m_value{{ t.java.FromStorageEnd }};
|
||||
}
|
||||
{% endfor %}
|
||||
/*
|
||||
* Factory functions.
|
||||
*/
|
||||
{% for t in types %}
|
||||
/**
|
||||
* Creates a {{ t.java.ValueType }} value.
|
||||
*
|
||||
* @param value the value
|
||||
* @return The entry value
|
||||
*/
|
||||
public static NetworkTableValue make{{ t.TypeName }}({{ t.java.ValueType }} value) {
|
||||
return new NetworkTableValue(NetworkTableType.k{{ t.TypeName }}, {{ t.java.ToWrapObject }}(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {{ t.java.ValueType }} value.
|
||||
*
|
||||
* @param value the value
|
||||
* @param time the creation time to use (instead of the current time)
|
||||
* @return The entry value
|
||||
*/
|
||||
public static NetworkTableValue make{{ t.TypeName }}({{ t.java.ValueType }} value, long time) {
|
||||
return new NetworkTableValue(NetworkTableType.k{{ t.TypeName }}, {{ t.java.ToWrapObject }}(value), time);
|
||||
}
|
||||
{% if t.java.WrapValueType %}
|
||||
/**
|
||||
* Creates a {{ t.java.ValueType }} value.
|
||||
*
|
||||
* @param value the value
|
||||
* @return The entry value
|
||||
*/
|
||||
public static NetworkTableValue make{{ t.TypeName }}({{ t.java.WrapValueType }} value) {
|
||||
return new NetworkTableValue(NetworkTableType.k{{ t.TypeName }}, toNative{{ t.TypeName }}(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {{ t.java.ValueType }} value.
|
||||
*
|
||||
* @param value the value
|
||||
* @param time the creation time to use (instead of the current time)
|
||||
* @return The entry value
|
||||
*/
|
||||
public static NetworkTableValue make{{ t.TypeName }}({{ t.java.WrapValueType }} value, long time) {
|
||||
return new NetworkTableValue(NetworkTableType.k{{ t.TypeName }}, toNative{{ t.TypeName }}(value), time);
|
||||
}
|
||||
{% endif -%}
|
||||
{% endfor %}
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other == this) {
|
||||
return true;
|
||||
}
|
||||
if (!(other instanceof NetworkTableValue)) {
|
||||
return false;
|
||||
}
|
||||
NetworkTableValue ntOther = (NetworkTableValue) other;
|
||||
return m_type == ntOther.m_type && m_value.equals(ntOther.m_value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(m_type, m_value);
|
||||
}
|
||||
|
||||
// arraycopy() doesn't know how to unwrap boxed values; this is a false positive in PMD
|
||||
// (see https://sourceforge.net/p/pmd/bugs/804/)
|
||||
@SuppressWarnings("PMD.AvoidArrayLoops")
|
||||
static boolean[] toNativeBooleanArray(Boolean[] arr) {
|
||||
boolean[] out = new boolean[arr.length];
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
out[i] = arr[i];
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@SuppressWarnings("PMD.AvoidArrayLoops")
|
||||
static double[] toNativeDoubleArray(Number[] arr) {
|
||||
double[] out = new double[arr.length];
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
out[i] = arr[i].doubleValue();
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@SuppressWarnings("PMD.AvoidArrayLoops")
|
||||
static long[] toNativeIntegerArray(Number[] arr) {
|
||||
long[] out = new long[arr.length];
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
out[i] = arr[i].longValue();
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@SuppressWarnings("PMD.AvoidArrayLoops")
|
||||
static float[] toNativeFloatArray(Number[] arr) {
|
||||
float[] out = new float[arr.length];
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
out[i] = arr[i].floatValue();
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@SuppressWarnings("PMD.AvoidArrayLoops")
|
||||
static Boolean[] fromNativeBooleanArray(boolean[] arr) {
|
||||
Boolean[] out = new Boolean[arr.length];
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
out[i] = arr[i];
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@SuppressWarnings("PMD.AvoidArrayLoops")
|
||||
static Long[] fromNativeIntegerArray(long[] arr) {
|
||||
Long[] out = new Long[arr.length];
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
out[i] = arr[i];
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@SuppressWarnings("PMD.AvoidArrayLoops")
|
||||
static Float[] fromNativeFloatArray(float[] arr) {
|
||||
Float[] out = new Float[arr.length];
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
out[i] = arr[i];
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@SuppressWarnings("PMD.AvoidArrayLoops")
|
||||
static Double[] fromNativeDoubleArray(double[] arr) {
|
||||
Double[] out = new Double[arr.length];
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
out[i] = arr[i];
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
private NetworkTableType m_type;
|
||||
private Object m_value;
|
||||
private long m_time;
|
||||
private long m_serverTime;
|
||||
}
|
||||
301
ntcore/src/generate/java/NetworkTablesJNI.java.jinja
Normal file
301
ntcore/src/generate/java/NetworkTablesJNI.java.jinja
Normal file
@@ -0,0 +1,301 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
package edu.wpi.first.networktables;
|
||||
|
||||
import edu.wpi.first.util.RuntimeLoader;
|
||||
import edu.wpi.first.util.datalog.DataLog;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
public final class NetworkTablesJNI {
|
||||
static boolean libraryLoaded = false;
|
||||
static RuntimeLoader<NetworkTablesJNI> loader = null;
|
||||
|
||||
public static class Helper {
|
||||
private static AtomicBoolean extractOnStaticLoad = new AtomicBoolean(true);
|
||||
|
||||
public static boolean getExtractOnStaticLoad() {
|
||||
return extractOnStaticLoad.get();
|
||||
}
|
||||
|
||||
public static void setExtractOnStaticLoad(boolean load) {
|
||||
extractOnStaticLoad.set(load);
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
if (Helper.getExtractOnStaticLoad()) {
|
||||
try {
|
||||
loader =
|
||||
new RuntimeLoader<>(
|
||||
"ntcorejni", RuntimeLoader.getDefaultExtractionRoot(), NetworkTablesJNI.class);
|
||||
loader.loadLibrary();
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
libraryLoaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Force load the library.
|
||||
*
|
||||
* @throws IOException if the library fails to load
|
||||
*/
|
||||
public static synchronized void forceLoad() throws IOException {
|
||||
if (libraryLoaded) {
|
||||
return;
|
||||
}
|
||||
loader =
|
||||
new RuntimeLoader<>(
|
||||
"ntcorejni", RuntimeLoader.getDefaultExtractionRoot(), NetworkTablesJNI.class);
|
||||
loader.loadLibrary();
|
||||
libraryLoaded = true;
|
||||
}
|
||||
|
||||
private static int[] pubSubOptionTypes(PubSubOption... options) {
|
||||
int[] rv = new int[options.length];
|
||||
for (int i = 0; i < options.length; i++) {
|
||||
rv[i] = options[i].m_type;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
private static double[] pubSubOptionValues(PubSubOption... options) {
|
||||
double[] rv = new double[options.length];
|
||||
for (int i = 0; i < options.length; i++) {
|
||||
rv[i] = options[i].m_value;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
public static native int getDefaultInstance();
|
||||
|
||||
public static native int createInstance();
|
||||
|
||||
public static native void destroyInstance(int inst);
|
||||
|
||||
public static native int getInstanceFromHandle(int handle);
|
||||
|
||||
public static native int getEntry(int inst, String key);
|
||||
|
||||
private static native int getEntry(
|
||||
int topic, int type, String typeStr, int[] optionTypes, double[] optionValues);
|
||||
|
||||
public static int getEntry(int topic, int type, String typeStr, PubSubOption... options) {
|
||||
return getEntry(topic, type, typeStr, pubSubOptionTypes(options), pubSubOptionValues(options));
|
||||
}
|
||||
|
||||
public static native String getEntryName(int entry);
|
||||
|
||||
public static native long getEntryLastChange(int entry);
|
||||
|
||||
public static native int getType(int entry);
|
||||
|
||||
/* Topic functions */
|
||||
|
||||
public static native int[] getTopics(int inst, String prefix, int types);
|
||||
|
||||
public static native int[] getTopicsStr(int inst, String prefix, String[] types);
|
||||
|
||||
public static native TopicInfo[] getTopicInfos(
|
||||
NetworkTableInstance instObject, int inst, String prefix, int types);
|
||||
|
||||
public static native TopicInfo[] getTopicInfosStr(
|
||||
NetworkTableInstance instObject, int inst, String prefix, String[] types);
|
||||
|
||||
public static native int getTopic(int inst, String name);
|
||||
|
||||
public static native String getTopicName(int topic);
|
||||
|
||||
public static native int getTopicType(int topic);
|
||||
|
||||
public static native void setTopicPersistent(int topic, boolean value);
|
||||
|
||||
public static native boolean getTopicPersistent(int topic);
|
||||
|
||||
public static native void setTopicRetained(int topic, boolean value);
|
||||
|
||||
public static native boolean getTopicRetained(int topic);
|
||||
|
||||
public static native String getTopicTypeString(int topic);
|
||||
|
||||
public static native boolean getTopicExists(int topic);
|
||||
|
||||
public static native String getTopicProperty(int topic, String name);
|
||||
|
||||
public static native void setTopicProperty(int topic, String name, String value);
|
||||
|
||||
public static native void deleteTopicProperty(int topic, String name);
|
||||
|
||||
public static native String getTopicProperties(int topic);
|
||||
|
||||
public static native void setTopicProperties(int topic, String properties);
|
||||
|
||||
private static native int subscribe(
|
||||
int topic, int type, String typeStr, int[] optionTypes, double[] optionValues);
|
||||
|
||||
public static int subscribe(int topic, int type, String typeStr, PubSubOption... options) {
|
||||
return subscribe(topic, type, typeStr, pubSubOptionTypes(options), pubSubOptionValues(options));
|
||||
}
|
||||
|
||||
public static native void unsubscribe(int sub);
|
||||
|
||||
private static native int publish(
|
||||
int topic, int type, String typeStr, int[] optionTypes, double[] optionValues);
|
||||
|
||||
public static int publish(int topic, int type, String typeStr, PubSubOption... options) {
|
||||
return publish(topic, type, typeStr, pubSubOptionTypes(options), pubSubOptionValues(options));
|
||||
}
|
||||
|
||||
private static native int publishEx(
|
||||
int topic, int type, String typeStr, String properties, int[] optionTypes, double[] optionValues);
|
||||
|
||||
public static int publishEx(int topic, int type, String typeStr, String properties, PubSubOption... options) {
|
||||
return publishEx(topic, type, typeStr, properties, pubSubOptionTypes(options), pubSubOptionValues(options));
|
||||
}
|
||||
|
||||
public static native void unpublish(int pubentry);
|
||||
|
||||
public static native void releaseEntry(int entry);
|
||||
|
||||
public static native void release(int pubsubentry);
|
||||
|
||||
public static native int getTopicFromHandle(int pubsubentry);
|
||||
|
||||
private static native int subscribeMultiple(
|
||||
int inst, String[] prefixes, int[] optionTypes, double[] optionValues);
|
||||
|
||||
public static int subscribeMultiple(int inst, String[] prefixes, PubSubOption... options) {
|
||||
return subscribeMultiple(
|
||||
inst, prefixes, pubSubOptionTypes(options), pubSubOptionValues(options));
|
||||
}
|
||||
|
||||
public static native void unsubscribeMultiple(int sub);
|
||||
{% for t in types %}
|
||||
public static native Timestamped{{ t.TypeName }} getAtomic{{ t.TypeName }}(
|
||||
int subentry, {{ t.java.ValueType }} defaultValue);
|
||||
|
||||
public static native Timestamped{{ t.TypeName }}[] readQueue{{ t.TypeName }}(int subentry);
|
||||
|
||||
public static native {{ t.java.ValueType }}[] readQueueValues{{ t.TypeName }}(int subentry);
|
||||
|
||||
public static native boolean set{{ t.TypeName }}(int entry, long time, {{ t.java.ValueType }} value);
|
||||
|
||||
public static native {{ t.java.ValueType }} get{{ t.TypeName }}(int entry, {{ t.java.ValueType }} defaultValue);
|
||||
|
||||
public static native boolean setDefault{{ t.TypeName }}(int entry, long time, {{ t.java.ValueType }} defaultValue);
|
||||
{% endfor %}
|
||||
public static native NetworkTableValue[] readQueueValue(int subentry);
|
||||
|
||||
public static native NetworkTableValue getValue(int entry);
|
||||
|
||||
public static native void setEntryFlags(int entry, int flags);
|
||||
|
||||
public static native int getEntryFlags(int entry);
|
||||
|
||||
public static native TopicInfo getTopicInfo(NetworkTableInstance inst, int topic);
|
||||
|
||||
public static native int createTopicListenerPoller(int inst);
|
||||
|
||||
public static native void destroyTopicListenerPoller(int poller);
|
||||
|
||||
public static native int addPolledTopicListener(int poller, String[] prefixes, int flags);
|
||||
|
||||
public static native int addPolledTopicListener(int poller, int handle, int flags);
|
||||
|
||||
public static native TopicNotification[] readTopicListenerQueue(
|
||||
NetworkTableInstance inst, int poller);
|
||||
|
||||
public static native void removeTopicListener(int topicListener);
|
||||
|
||||
public static native int createValueListenerPoller(int inst);
|
||||
|
||||
public static native void destroyValueListenerPoller(int poller);
|
||||
|
||||
public static native int addPolledValueListener(int poller, int subentry, int flags);
|
||||
|
||||
public static native ValueNotification[] readValueListenerQueue(
|
||||
NetworkTableInstance inst, int poller);
|
||||
|
||||
public static native void removeValueListener(int valueListener);
|
||||
|
||||
public static native int createConnectionListenerPoller(int inst);
|
||||
|
||||
public static native void destroyConnectionListenerPoller(int poller);
|
||||
|
||||
public static native int addPolledConnectionListener(int poller, boolean immediateNotify);
|
||||
|
||||
public static native ConnectionNotification[] readConnectionListenerQueue(
|
||||
NetworkTableInstance inst, int poller);
|
||||
|
||||
public static native void removeConnectionListener(int connListener);
|
||||
|
||||
public static native void setNetworkIdentity(int inst, String name);
|
||||
|
||||
public static native int getNetworkMode(int inst);
|
||||
|
||||
public static native void startLocal(int inst);
|
||||
|
||||
public static native void stopLocal(int inst);
|
||||
|
||||
public static native void startServer(
|
||||
int inst, String persistFilename, String listenAddress, int port3, int port4);
|
||||
|
||||
public static native void stopServer(int inst);
|
||||
|
||||
public static native void startClient3(int inst);
|
||||
|
||||
public static native void startClient4(int inst);
|
||||
|
||||
public static native void stopClient(int inst);
|
||||
|
||||
public static native void setServer(int inst, String serverName, int port);
|
||||
|
||||
public static native void setServer(int inst, String[] serverNames, int[] ports);
|
||||
|
||||
public static native void setServerTeam(int inst, int team, int port);
|
||||
|
||||
public static native void startDSClient(int inst, int port);
|
||||
|
||||
public static native void stopDSClient(int inst);
|
||||
|
||||
public static native void flushLocal(int inst);
|
||||
|
||||
public static native void flush(int inst);
|
||||
|
||||
public static native ConnectionInfo[] getConnections(int inst);
|
||||
|
||||
public static native boolean isConnected(int inst);
|
||||
|
||||
public static native long now();
|
||||
|
||||
private static native int startEntryDataLog(int inst, long log, String prefix, String logPrefix);
|
||||
|
||||
public static int startEntryDataLog(int inst, DataLog log, String prefix, String logPrefix) {
|
||||
return startEntryDataLog(inst, log.getImpl(), prefix, logPrefix);
|
||||
}
|
||||
|
||||
public static native void stopEntryDataLog(int logger);
|
||||
|
||||
private static native int startConnectionDataLog(int inst, long log, String name);
|
||||
|
||||
public static int startConnectionDataLog(int inst, DataLog log, String name) {
|
||||
return startConnectionDataLog(inst, log.getImpl(), name);
|
||||
}
|
||||
|
||||
public static native void stopConnectionDataLog(int logger);
|
||||
|
||||
public static native int createLoggerPoller(int inst);
|
||||
|
||||
public static native void destroyLoggerPoller(int poller);
|
||||
|
||||
public static native int addPolledLogger(int poller, int minLevel, int maxLevel);
|
||||
|
||||
public static native LogMessage[] readLoggerQueue(NetworkTableInstance inst, int poller);
|
||||
|
||||
public static native void removeLogger(int logger);
|
||||
}
|
||||
49
ntcore/src/generate/java/Publisher.java.jinja
Normal file
49
ntcore/src/generate/java/Publisher.java.jinja
Normal file
@@ -0,0 +1,49 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
package edu.wpi.first.networktables;
|
||||
|
||||
import {{ java.ConsumerFunctionPackage|default('java.util.function') }}.{{ java.FunctionTypePrefix }}Consumer;
|
||||
|
||||
/** NetworkTables {{ TypeName }} publisher. */
|
||||
public interface {{ TypeName }}Publisher extends Publisher, {{ java.FunctionTypePrefix }}Consumer{{ java.FunctionTypeSuffix }} {
|
||||
/**
|
||||
* Get the corresponding topic.
|
||||
*
|
||||
* @return Topic
|
||||
*/
|
||||
@Override
|
||||
{{ TypeName }}Topic getTopic();
|
||||
|
||||
/**
|
||||
* Publish a new value using current NT time.
|
||||
*
|
||||
* @param value value to publish
|
||||
*/
|
||||
default void set({{ java.ValueType }} value) {
|
||||
set(value, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish a new value.
|
||||
*
|
||||
* @param value value to publish
|
||||
* @param time timestamp; 0 indicates current NT time should be used
|
||||
*/
|
||||
void set({{ java.ValueType }} value, long time);
|
||||
|
||||
/**
|
||||
* Publish a default value.
|
||||
* On reconnect, a default value will never be used in preference to a
|
||||
* published value.
|
||||
*
|
||||
* @param value value
|
||||
*/
|
||||
void setDefault({{ java.ValueType }} value);
|
||||
|
||||
@Override
|
||||
default void accept({{ java.ValueType }} value) {
|
||||
set(value);
|
||||
}
|
||||
}
|
||||
83
ntcore/src/generate/java/Subscriber.java.jinja
Normal file
83
ntcore/src/generate/java/Subscriber.java.jinja
Normal file
@@ -0,0 +1,83 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
package edu.wpi.first.networktables;
|
||||
|
||||
import {{ java.SupplierFunctionPackage|default('java.util.function') }}.{{ java.FunctionTypePrefix }}Supplier;
|
||||
|
||||
/** NetworkTables {{ TypeName }} subscriber. */
|
||||
@SuppressWarnings("PMD.MissingOverride")
|
||||
public interface {{ TypeName }}Subscriber extends Subscriber, {{ java.FunctionTypePrefix }}Supplier{{ java.FunctionTypeSuffix }} {
|
||||
/**
|
||||
* Get the corresponding topic.
|
||||
*
|
||||
* @return Topic
|
||||
*/
|
||||
@Override
|
||||
{{ TypeName }}Topic getTopic();
|
||||
|
||||
/**
|
||||
* Get the last published value.
|
||||
* If no value has been published, returns the stored default value.
|
||||
*
|
||||
* @return value
|
||||
*/
|
||||
{{ java.ValueType }} get();
|
||||
|
||||
/**
|
||||
* Get the last published value.
|
||||
* If no value has been published, returns the passed defaultValue.
|
||||
*
|
||||
* @param defaultValue default value to return if no value has been published
|
||||
* @return value
|
||||
*/
|
||||
{{ java.ValueType }} get({{ java.ValueType }} defaultValue);
|
||||
{% if java.FunctionTypePrefix %}
|
||||
@Override
|
||||
default {{ java.ValueType }} getAs{{ java.FunctionTypePrefix }}() {
|
||||
return get();
|
||||
}
|
||||
{% endif %}
|
||||
/**
|
||||
* Get the last published value along with its timestamp
|
||||
* If no value has been published, returns the stored default value and a
|
||||
* timestamp of 0.
|
||||
*
|
||||
* @return timestamped value
|
||||
*/
|
||||
Timestamped{{ TypeName }} getAtomic();
|
||||
|
||||
/**
|
||||
* Get the last published value along with its timestamp
|
||||
* If no value has been published, returns the passed defaultValue and a
|
||||
* timestamp of 0.
|
||||
*
|
||||
* @param defaultValue default value to return if no value has been published
|
||||
* @return timestamped value
|
||||
*/
|
||||
Timestamped{{ TypeName }} getAtomic({{ java.ValueType }} defaultValue);
|
||||
|
||||
/**
|
||||
* Get an array of all value changes since the last call to readQueue.
|
||||
* Also provides a timestamp for each value.
|
||||
*
|
||||
* <p>The "poll storage" subscribe option can be used to set the queue
|
||||
* depth.
|
||||
*
|
||||
* @return Array of timestamped values; empty array if no new changes have
|
||||
* been published since the previous call.
|
||||
*/
|
||||
Timestamped{{ TypeName }}[] readQueue();
|
||||
|
||||
/**
|
||||
* Get an array of all value changes since the last call to readQueue.
|
||||
*
|
||||
* <p>The "poll storage" subscribe option can be used to set the queue
|
||||
* depth.
|
||||
*
|
||||
* @return Array of values; empty array if no new changes have been
|
||||
* published since the previous call.
|
||||
*/
|
||||
{{ java.ValueType }}[] readQueueValues();
|
||||
}
|
||||
40
ntcore/src/generate/java/Timestamped.java.jinja
Normal file
40
ntcore/src/generate/java/Timestamped.java.jinja
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
package edu.wpi.first.networktables;
|
||||
|
||||
/** NetworkTables timestamped {{ TypeName }}. */
|
||||
@SuppressWarnings("PMD.ArrayIsStoredDirectly")
|
||||
public final class Timestamped{{ TypeName }} {
|
||||
/**
|
||||
* Create a timestamped value.
|
||||
*
|
||||
* @param timestamp timestamp in local time base
|
||||
* @param serverTime timestamp in server time base
|
||||
* @param value value
|
||||
*/
|
||||
public Timestamped{{ TypeName }}(long timestamp, long serverTime, {{ java.ValueType }} value) {
|
||||
this.timestamp = timestamp;
|
||||
this.serverTime = serverTime;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Timestamp in local time base.
|
||||
*/
|
||||
@SuppressWarnings("MemberName")
|
||||
public final long timestamp;
|
||||
|
||||
/**
|
||||
* Timestamp in server time base. May be 0 or 1 for locally set values.
|
||||
*/
|
||||
@SuppressWarnings("MemberName")
|
||||
public final long serverTime;
|
||||
|
||||
/**
|
||||
* Value.
|
||||
*/
|
||||
@SuppressWarnings("MemberName")
|
||||
public final {{ java.ValueType }} value;
|
||||
}
|
||||
222
ntcore/src/generate/java/Topic.java.jinja
Normal file
222
ntcore/src/generate/java/Topic.java.jinja
Normal file
@@ -0,0 +1,222 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
package edu.wpi.first.networktables;
|
||||
|
||||
/** NetworkTables {{ TypeName }} topic. */
|
||||
public final class {{ TypeName }}Topic extends Topic {
|
||||
{%- if TypeString %}
|
||||
/** The default type string for this topic type. */
|
||||
public static final String kTypeString = {{ TypeString }};
|
||||
{% endif %}
|
||||
/**
|
||||
* Construct from a generic topic.
|
||||
*
|
||||
* @param topic Topic
|
||||
*/
|
||||
public {{ TypeName }}Topic(Topic topic) {
|
||||
super(topic.m_inst, topic.m_handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor; use NetworkTableInstance.get{{TypeName}}Topic() instead.
|
||||
*
|
||||
* @param inst Instance
|
||||
* @param handle Native handle
|
||||
*/
|
||||
public {{ TypeName }}Topic(NetworkTableInstance inst, int handle) {
|
||||
super(inst, handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new subscriber to the topic.
|
||||
*
|
||||
* <p>The subscriber is only active as long as the returned object
|
||||
* is not closed.
|
||||
*
|
||||
* <p>Subscribers that do not match the published data type do not return
|
||||
* any values. To determine if the data type matches, use the appropriate
|
||||
* Topic functions.
|
||||
*
|
||||
{%- if not TypeString %}
|
||||
* @param typeString type string
|
||||
{% endif %}
|
||||
* @param defaultValue default value used when a default is not provided to a
|
||||
* getter function
|
||||
* @param options subscribe options
|
||||
* @return subscriber
|
||||
*/
|
||||
public {{ TypeName }}Subscriber subscribe(
|
||||
{%- if not TypeString %}
|
||||
String typeString,
|
||||
{% endif %}
|
||||
{{ java.ValueType }} defaultValue,
|
||||
PubSubOption... options) {
|
||||
return new {{ TypeName }}EntryImpl(
|
||||
this,
|
||||
NetworkTablesJNI.subscribe(
|
||||
m_handle, NetworkTableType.k{{ TypeName }}.getValue(),
|
||||
{{ TypeString|default('typeString') }}, options),
|
||||
defaultValue);
|
||||
}
|
||||
{% if TypeString %}
|
||||
/**
|
||||
* Create a new subscriber to the topic, with specified type string.
|
||||
*
|
||||
* <p>The subscriber is only active as long as the returned object
|
||||
* is not closed.
|
||||
*
|
||||
* <p>Subscribers that do not match the published data type do not return
|
||||
* any values. To determine if the data type matches, use the appropriate
|
||||
* Topic functions.
|
||||
*
|
||||
* @param typeString type string
|
||||
* @param defaultValue default value used when a default is not provided to a
|
||||
* getter function
|
||||
* @param options subscribe options
|
||||
* @return subscriber
|
||||
*/
|
||||
public {{ TypeName }}Subscriber subscribeEx(
|
||||
String typeString,
|
||||
{{ java.ValueType }} defaultValue,
|
||||
PubSubOption... options) {
|
||||
return new {{ TypeName }}EntryImpl(
|
||||
this,
|
||||
NetworkTablesJNI.subscribe(
|
||||
m_handle, NetworkTableType.k{{ TypeName }}.getValue(),
|
||||
typeString, options),
|
||||
defaultValue);
|
||||
}
|
||||
{% endif %}
|
||||
/**
|
||||
* Create a new publisher to the topic.
|
||||
*
|
||||
* <p>The publisher is only active as long as the returned object
|
||||
* is not closed.
|
||||
*
|
||||
* <p>It is not possible to publish two different data types to the same
|
||||
* topic. Conflicts between publishers are typically resolved by the server on
|
||||
* a first-come, first-served basis. Any published values that do not match
|
||||
* the topic's data type are dropped (ignored). To determine if the data type
|
||||
* matches, use the appropriate Topic functions.
|
||||
*
|
||||
{%- if not TypeString %}
|
||||
* @param typeString type string
|
||||
{% endif %}
|
||||
* @param options publish options
|
||||
* @return publisher
|
||||
*/
|
||||
public {{ TypeName }}Publisher publish(
|
||||
{%- if not TypeString %}
|
||||
String typeString,
|
||||
{% endif %}
|
||||
PubSubOption... options) {
|
||||
return new {{ TypeName }}EntryImpl(
|
||||
this,
|
||||
NetworkTablesJNI.publish(
|
||||
m_handle, NetworkTableType.k{{ TypeName }}.getValue(),
|
||||
{{ TypeString|default('typeString') }}, options),
|
||||
{{ java.EmptyValue }});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new publisher to the topic, with type string and initial properties.
|
||||
*
|
||||
* <p>The publisher is only active as long as the returned object
|
||||
* is not closed.
|
||||
*
|
||||
* <p>It is not possible to publish two different data types to the same
|
||||
* topic. Conflicts between publishers are typically resolved by the server on
|
||||
* a first-come, first-served basis. Any published values that do not match
|
||||
* the topic's data type are dropped (ignored). To determine if the data type
|
||||
* matches, use the appropriate Topic functions.
|
||||
*
|
||||
* @param typeString type string
|
||||
* @param properties JSON properties
|
||||
* @param options publish options
|
||||
* @return publisher
|
||||
*/
|
||||
public {{ TypeName }}Publisher publishEx(
|
||||
String typeString,
|
||||
String properties,
|
||||
PubSubOption... options) {
|
||||
return new {{ TypeName }}EntryImpl(
|
||||
this,
|
||||
NetworkTablesJNI.publishEx(
|
||||
m_handle, NetworkTableType.k{{ TypeName }}.getValue(),
|
||||
typeString, properties, options),
|
||||
{{ java.EmptyValue }});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new entry for the topic.
|
||||
*
|
||||
* <p>Entries act as a combination of a subscriber and a weak publisher. The
|
||||
* subscriber is active as long as the entry is not closed. The publisher is
|
||||
* created when the entry is first written to, and remains active until either
|
||||
* unpublish() is called or the entry is closed.
|
||||
*
|
||||
* <p>It is not possible to use two different data types with the same
|
||||
* topic. Conflicts between publishers are typically resolved by the server on
|
||||
* a first-come, first-served basis. Any published values that do not match
|
||||
* the topic's data type are dropped (ignored), and the entry will show no new
|
||||
* values if the data type does not match. To determine if the data type
|
||||
* matches, use the appropriate Topic functions.
|
||||
*
|
||||
{%- if not TypeString %}
|
||||
* @param typeString type string
|
||||
{% endif %}
|
||||
* @param defaultValue default value used when a default is not provided to a
|
||||
* getter function
|
||||
* @param options publish and/or subscribe options
|
||||
* @return entry
|
||||
*/
|
||||
public {{ TypeName }}Entry getEntry(
|
||||
{%- if not TypeString %}
|
||||
String typeString,
|
||||
{% endif %}
|
||||
{{ java.ValueType }} defaultValue,
|
||||
PubSubOption... options) {
|
||||
return new {{ TypeName }}EntryImpl(
|
||||
this,
|
||||
NetworkTablesJNI.getEntry(
|
||||
m_handle, NetworkTableType.k{{ TypeName }}.getValue(),
|
||||
{{ TypeString|default('typeString') }}, options),
|
||||
defaultValue);
|
||||
}
|
||||
{% if TypeString %}
|
||||
/**
|
||||
* Create a new entry for the topic, with specified type string.
|
||||
*
|
||||
* <p>Entries act as a combination of a subscriber and a weak publisher. The
|
||||
* subscriber is active as long as the entry is not closed. The publisher is
|
||||
* created when the entry is first written to, and remains active until either
|
||||
* unpublish() is called or the entry is closed.
|
||||
*
|
||||
* <p>It is not possible to use two different data types with the same
|
||||
* topic. Conflicts between publishers are typically resolved by the server on
|
||||
* a first-come, first-served basis. Any published values that do not match
|
||||
* the topic's data type are dropped (ignored), and the entry will show no new
|
||||
* values if the data type does not match. To determine if the data type
|
||||
* matches, use the appropriate Topic functions.
|
||||
*
|
||||
* @param typeString type string
|
||||
* @param defaultValue default value used when a default is not provided to a
|
||||
* getter function
|
||||
* @param options publish and/or subscribe options
|
||||
* @return entry
|
||||
*/
|
||||
public {{ TypeName }}Entry getEntryEx(
|
||||
String typeString,
|
||||
{{ java.ValueType }} defaultValue,
|
||||
PubSubOption... options) {
|
||||
return new {{ TypeName }}EntryImpl(
|
||||
this,
|
||||
NetworkTablesJNI.getEntry(
|
||||
m_handle, NetworkTableType.k{{ TypeName }}.getValue(),
|
||||
typeString, options),
|
||||
defaultValue);
|
||||
}
|
||||
{% endif %}
|
||||
}
|
||||
Reference in New Issue
Block a user