mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-30 02:31:44 +00:00
Provide more extensive listener features.
This enables listeners to be notified of not only value updates, but also flag changes and deletions by using a bitmask to specify what notifications are desired. The old API (which only provided a new/not new) flag is still supported. This also subsumes the feature to listen to local changes (that's one of the bitmask options).
This commit is contained in:
@@ -887,8 +887,7 @@ JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
|
||||
* Signature: (Ljava/lang/String;Ledu/wpi/first/wpilibj/networktables/NetworkTablesJNI/EntryListenerFunction;Z)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_addEntryListener
|
||||
(JNIEnv *envouter, jclass, jstring prefix, jobject listener,
|
||||
jboolean immediateNotify, jboolean localNotify)
|
||||
(JNIEnv *envouter, jclass, jstring prefix, jobject listener, jint flags)
|
||||
{
|
||||
// the shared pointer to the weak global will keep it around until the
|
||||
// entry listener is destroyed
|
||||
@@ -901,13 +900,13 @@ JNIEXPORT jint JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
|
||||
|
||||
// method ids, on the other hand, are safe to retain
|
||||
jmethodID mid = envouter->GetMethodID(
|
||||
cls, "apply", "(ILjava/lang/String;Ljava/lang/Object;Z)V");
|
||||
cls, "apply", "(ILjava/lang/String;Ljava/lang/Object;I)V");
|
||||
if (!mid) return 0;
|
||||
|
||||
return nt::AddEntryListener(
|
||||
JavaStringRef(envouter, prefix),
|
||||
[=](unsigned int uid, nt::StringRef name,
|
||||
std::shared_ptr<nt::Value> value, bool is_new) {
|
||||
std::shared_ptr<nt::Value> value, unsigned int flags_) {
|
||||
// need to attach as we're coming from a separate thread here
|
||||
if (!jvm) return;
|
||||
JNIEnv *env;
|
||||
@@ -929,14 +928,13 @@ JNIEXPORT jint JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
|
||||
goto done;
|
||||
}
|
||||
env->CallVoidMethod(handler, mid, (jint)uid, ToJavaString(env, name),
|
||||
jobj, (jboolean)(is_new ? 1 : 0));
|
||||
jobj, (jint)(flags_));
|
||||
if (env->ExceptionCheck()) env->ExceptionDescribe();
|
||||
}
|
||||
done:
|
||||
jvm->DetachCurrentThread();
|
||||
},
|
||||
immediateNotify != JNI_FALSE,
|
||||
localNotify != JNI_FALSE);
|
||||
flags);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -240,12 +240,15 @@ public class NetworkTable implements ITable, IRemote {
|
||||
}
|
||||
|
||||
public void addTableListener(ITableListener listener) {
|
||||
addTableListener(listener, false, false);
|
||||
addTableListenerEx(listener, NOTIFY_NEW | NOTIFY_UPDATE);
|
||||
}
|
||||
|
||||
public void addTableListener(ITableListener listener,
|
||||
boolean immediateNotify) {
|
||||
addTableListener(listener, immediateNotify, false);
|
||||
int flags = NOTIFY_NEW | NOTIFY_UPDATE;
|
||||
if (immediateNotify)
|
||||
flags |= NOTIFY_IMMEDIATE;
|
||||
addTableListenerEx(listener, flags);
|
||||
}
|
||||
|
||||
private class TableListenerAdapter extends ListenerBase implements NetworkTablesJNI.EntryListenerFunction {
|
||||
@@ -259,18 +262,17 @@ public class NetworkTable implements ITable, IRemote {
|
||||
this.targetListener = targetListener;
|
||||
}
|
||||
|
||||
public void apply(int uid, String key, Object value, boolean isNew) {
|
||||
public void apply(int uid, String key, Object value, int flags) {
|
||||
String relativeKey = key.substring(prefixLen);
|
||||
if (relativeKey.indexOf(PATH_SEPARATOR) != -1)
|
||||
return;
|
||||
targetListener.valueChanged(targetSource, relativeKey, value, isNew);
|
||||
targetListener.valueChangedEx(targetSource, relativeKey, value, flags);
|
||||
}
|
||||
}
|
||||
|
||||
private final Hashtable<ITableListener,List<ListenerBase>> listenerMap = new Hashtable<ITableListener,List<ListenerBase>>();
|
||||
public synchronized void addTableListener(ITableListener listener,
|
||||
boolean immediateNotify,
|
||||
boolean localNotify) {
|
||||
public synchronized void addTableListenerEx(ITableListener listener,
|
||||
int flags) {
|
||||
List<ListenerBase> adapters = listenerMap.get(listener);
|
||||
if (adapters == null) {
|
||||
adapters = new ArrayList<ListenerBase>();
|
||||
@@ -278,13 +280,16 @@ public class NetworkTable implements ITable, IRemote {
|
||||
}
|
||||
TableListenerAdapter adapter =
|
||||
new TableListenerAdapter(path.length() + 1, this, listener);
|
||||
adapter.uid = NetworkTablesJNI.addEntryListener(path + PATH_SEPARATOR, adapter, immediateNotify, localNotify);
|
||||
adapter.uid = NetworkTablesJNI.addEntryListener(path + PATH_SEPARATOR, adapter, flags);
|
||||
adapters.add(adapter);
|
||||
}
|
||||
|
||||
public void addTableListener(String key, ITableListener listener,
|
||||
boolean immediateNotify) {
|
||||
addTableListener(key, listener, immediateNotify, false);
|
||||
int flags = NOTIFY_NEW | NOTIFY_UPDATE;
|
||||
if (immediateNotify)
|
||||
flags |= NOTIFY_IMMEDIATE;
|
||||
addTableListenerEx(key, listener, flags);
|
||||
}
|
||||
|
||||
private class KeyListenerAdapter extends ListenerBase implements NetworkTablesJNI.EntryListenerFunction {
|
||||
@@ -300,16 +305,16 @@ public class NetworkTable implements ITable, IRemote {
|
||||
this.targetListener = targetListener;
|
||||
}
|
||||
|
||||
public void apply(int uid, String key, Object value, boolean isNew) {
|
||||
public void apply(int uid, String key, Object value, int flags) {
|
||||
if (!key.equals(fullKey))
|
||||
return;
|
||||
targetListener.valueChanged(targetSource, relativeKey, value, isNew);
|
||||
targetListener.valueChangedEx(targetSource, relativeKey, value, flags);
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void addTableListener(String key, ITableListener listener,
|
||||
boolean immediateNotify,
|
||||
boolean localNotify) {
|
||||
public synchronized void addTableListenerEx(String key,
|
||||
ITableListener listener,
|
||||
int flags) {
|
||||
List<ListenerBase> adapters = listenerMap.get(listener);
|
||||
if (adapters == null) {
|
||||
adapters = new ArrayList<ListenerBase>();
|
||||
@@ -318,7 +323,7 @@ public class NetworkTable implements ITable, IRemote {
|
||||
String fullKey = path + PATH_SEPARATOR + key;
|
||||
KeyListenerAdapter adapter =
|
||||
new KeyListenerAdapter(key, fullKey, this, listener);
|
||||
adapter.uid = NetworkTablesJNI.addEntryListener(fullKey, adapter, immediateNotify, localNotify);
|
||||
adapter.uid = NetworkTablesJNI.addEntryListener(fullKey, adapter, flags);
|
||||
adapters.add(adapter);
|
||||
}
|
||||
|
||||
@@ -338,7 +343,7 @@ public class NetworkTable implements ITable, IRemote {
|
||||
this.targetListener = targetListener;
|
||||
}
|
||||
|
||||
public void apply(int uid, String key, Object value, boolean isNew) {
|
||||
public void apply(int uid, String key, Object value, int flags) {
|
||||
String relativeKey = key.substring(prefixLen);
|
||||
int endSubTable = relativeKey.indexOf(PATH_SEPARATOR);
|
||||
if (endSubTable == -1)
|
||||
@@ -347,7 +352,7 @@ public class NetworkTable implements ITable, IRemote {
|
||||
if (notifiedTables.contains(subTableKey))
|
||||
return;
|
||||
notifiedTables.add(subTableKey);
|
||||
targetListener.valueChanged(targetSource, subTableKey, targetSource.getSubTable(subTableKey), true);
|
||||
targetListener.valueChangedEx(targetSource, subTableKey, targetSource.getSubTable(subTableKey), flags);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -360,7 +365,10 @@ public class NetworkTable implements ITable, IRemote {
|
||||
}
|
||||
SubListenerAdapter adapter =
|
||||
new SubListenerAdapter(path.length() + 1, this, listener);
|
||||
adapter.uid = NetworkTablesJNI.addEntryListener(path + PATH_SEPARATOR, adapter, true, localNotify);
|
||||
int flags = NOTIFY_NEW | NOTIFY_IMMEDIATE;
|
||||
if (localNotify)
|
||||
flags |= NOTIFY_LOCAL;
|
||||
adapter.uid = NetworkTablesJNI.addEntryListener(path + PATH_SEPARATOR, adapter, flags);
|
||||
adapters.add(adapter);
|
||||
}
|
||||
|
||||
|
||||
@@ -107,9 +107,9 @@ public class NetworkTablesJNI {
|
||||
public static native void flush();
|
||||
|
||||
public interface EntryListenerFunction {
|
||||
void apply(int uid, String key, Object value, boolean isNew);
|
||||
void apply(int uid, String key, Object value, int flags);
|
||||
}
|
||||
public static native int addEntryListener(String prefix, EntryListenerFunction listener, boolean immediateNotify, boolean localNotify);
|
||||
public static native int addEntryListener(String prefix, EntryListenerFunction listener, int flags);
|
||||
public static native void removeEntryListener(int entryListenerUid);
|
||||
|
||||
public interface ConnectionListenerFunction {
|
||||
|
||||
@@ -297,6 +297,14 @@ public interface ITable {
|
||||
*/
|
||||
public String[] getStringArray(String key, String[] defaultValue);
|
||||
|
||||
/** Notifier flag values. */
|
||||
public static final int NOTIFY_IMMEDIATE = 0x01;
|
||||
public static final int NOTIFY_LOCAL = 0x02;
|
||||
public static final int NOTIFY_NEW = 0x04;
|
||||
public static final int NOTIFY_DELETE = 0x08;
|
||||
public static final int NOTIFY_UPDATE = 0x10;
|
||||
public static final int NOTIFY_FLAGS = 0x20;
|
||||
|
||||
/**
|
||||
* Add a listener for changes to the table
|
||||
* @param listener the listener to add
|
||||
@@ -313,13 +321,9 @@ public interface ITable {
|
||||
/**
|
||||
* Add a listener for changes to the table
|
||||
* @param listener the listener to add
|
||||
* @param immediateNotify if true then this listener will be notified of all
|
||||
* current entries (marked as new)
|
||||
* @param localNotify if true then this listener will be notified of all
|
||||
* local changes in addition to all remote changes
|
||||
* @param flags bitmask specifying desired notifications
|
||||
*/
|
||||
public void addTableListener(ITableListener listener, boolean immediateNotify,
|
||||
boolean localNotify);
|
||||
public void addTableListenerEx(ITableListener listener, int flags);
|
||||
|
||||
/**
|
||||
* Add a listener for changes to a specific key the table
|
||||
@@ -334,13 +338,10 @@ public interface ITable {
|
||||
* Add a listener for changes to a specific key the table
|
||||
* @param key the key to listen for
|
||||
* @param listener the listener to add
|
||||
* @param immediateNotify if true then this listener will be notified of all
|
||||
* current entries (marked as new)
|
||||
* @param localNotify if true then this listener will be notified of all
|
||||
* local changes in addition to all remote changes
|
||||
* @param flags bitmask specifying desired notifications
|
||||
*/
|
||||
public void addTableListener(String key, ITableListener listener,
|
||||
boolean immediateNotify, boolean localNotify);
|
||||
public void addTableListenerEx(String key, ITableListener listener,
|
||||
int flags);
|
||||
/**
|
||||
* This will immediately notify the listener of all current sub tables
|
||||
* @param listener
|
||||
|
||||
@@ -9,11 +9,26 @@ package edu.wpi.first.wpilibj.tables;
|
||||
public interface ITableListener {
|
||||
/**
|
||||
* Called when a key-value pair is changed in a {@link ITable}
|
||||
* WARNING: If a new key-value is put in this method value changed will immediatly be called which could lead to recursive code
|
||||
* @param source the table the key-value pair exists in
|
||||
* @param key the key associated with the value that changed
|
||||
* @param value the new value
|
||||
* @param isNew true if the key did not previously exist in the table, otherwise it is false
|
||||
*/
|
||||
public void valueChanged(ITable source, String key, Object value, boolean isNew);
|
||||
|
||||
/**
|
||||
* Extended version of valueChanged. Called when a key-value pair is
|
||||
* changed in a {@link ITable}. The default implementation simply calls
|
||||
* valueChanged(). If this is overridden, valueChanged() will not be
|
||||
* called.
|
||||
* @param source the table the key-value pair exists in
|
||||
* @param key the key associated with the value that changed
|
||||
* @param value the new value
|
||||
* @param flags update flags; for example, NOTIFY_NEW if the key did not
|
||||
* previously exist in the table
|
||||
*/
|
||||
default public void valueChangedEx(ITable source, String key, Object value, int flags) {
|
||||
// NOTIFY_NEW = 0x04
|
||||
valueChanged(source, key, value, (flags & 0x04) != 0);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user