Implement local notification.

The default behavior is to only notify remote changes, but for some
applications (e.g. GUI's) it's advantageous to know about local
changes as well.

This is (slightly) optimized in that local changes only result in
additional resources being consumed if (any) local listeners have been
created.
This commit is contained in:
Peter Johnson
2015-09-23 00:56:08 -07:00
parent 75358e6c45
commit 424bf51a7b
14 changed files with 173 additions and 42 deletions

View File

@@ -888,7 +888,7 @@ JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
*/
JNIEXPORT jint JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI_addEntryListener
(JNIEnv *envouter, jclass, jstring prefix, jobject listener,
jboolean immediateNotify)
jboolean immediateNotify, jboolean localNotify)
{
// the shared pointer to the weak global will keep it around until the
// entry listener is destroyed
@@ -935,7 +935,8 @@ JNIEXPORT jint JNICALL Java_edu_wpi_first_wpilibj_networktables_NetworkTablesJNI
done:
jvm->DetachCurrentThread();
},
immediateNotify != JNI_FALSE);
immediateNotify != JNI_FALSE,
localNotify != JNI_FALSE);
}
/*

View File

@@ -240,7 +240,12 @@ public class NetworkTable implements ITable, IRemote {
}
public void addTableListener(ITableListener listener) {
addTableListener(listener, false);
addTableListener(listener, false, false);
}
public void addTableListener(ITableListener listener,
boolean immediateNotify) {
addTableListener(listener, immediateNotify, false);
}
private class TableListenerAdapter extends ListenerBase implements NetworkTablesJNI.EntryListenerFunction {
@@ -264,7 +269,8 @@ public class NetworkTable implements ITable, IRemote {
private final Hashtable<ITableListener,List<ListenerBase>> listenerMap = new Hashtable<ITableListener,List<ListenerBase>>();
public synchronized void addTableListener(ITableListener listener,
boolean immediateNotify) {
boolean immediateNotify,
boolean localNotify) {
List<ListenerBase> adapters = listenerMap.get(listener);
if (adapters == null) {
adapters = new ArrayList<ListenerBase>();
@@ -272,10 +278,15 @@ public class NetworkTable implements ITable, IRemote {
}
TableListenerAdapter adapter =
new TableListenerAdapter(path.length() + 1, this, listener);
adapter.uid = NetworkTablesJNI.addEntryListener(path + PATH_SEPARATOR, adapter, immediateNotify);
adapter.uid = NetworkTablesJNI.addEntryListener(path + PATH_SEPARATOR, adapter, immediateNotify, localNotify);
adapters.add(adapter);
}
public void addTableListener(String key, ITableListener listener,
boolean immediateNotify) {
addTableListener(key, listener, immediateNotify, false);
}
private class KeyListenerAdapter extends ListenerBase implements NetworkTablesJNI.EntryListenerFunction {
private final String relativeKey;
private final String fullKey;
@@ -297,7 +308,8 @@ public class NetworkTable implements ITable, IRemote {
}
public synchronized void addTableListener(String key, ITableListener listener,
boolean immediateNotify) {
boolean immediateNotify,
boolean localNotify) {
List<ListenerBase> adapters = listenerMap.get(listener);
if (adapters == null) {
adapters = new ArrayList<ListenerBase>();
@@ -306,10 +318,14 @@ 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);
adapter.uid = NetworkTablesJNI.addEntryListener(fullKey, adapter, immediateNotify, localNotify);
adapters.add(adapter);
}
public void addSubTableListener(final ITableListener listener) {
addSubTableListener(listener, false);
}
private class SubListenerAdapter extends ListenerBase implements NetworkTablesJNI.EntryListenerFunction {
private final int prefixLen;
private final ITable targetSource;
@@ -335,7 +351,8 @@ public class NetworkTable implements ITable, IRemote {
}
}
public synchronized void addSubTableListener(final ITableListener listener) {
public synchronized void addSubTableListener(final ITableListener listener,
boolean localNotify) {
List<ListenerBase> adapters = listenerMap.get(listener);
if (adapters == null) {
adapters = new ArrayList<ListenerBase>();
@@ -343,7 +360,7 @@ public class NetworkTable implements ITable, IRemote {
}
SubListenerAdapter adapter =
new SubListenerAdapter(path.length() + 1, this, listener);
adapter.uid = NetworkTablesJNI.addEntryListener(path + PATH_SEPARATOR, adapter, true);
adapter.uid = NetworkTablesJNI.addEntryListener(path + PATH_SEPARATOR, adapter, true, localNotify);
adapters.add(adapter);
}

View File

@@ -109,7 +109,7 @@ public class NetworkTablesJNI {
public interface EntryListenerFunction {
void apply(int uid, String key, Object value, boolean isNew);
}
public static native int addEntryListener(String prefix, EntryListenerFunction listener, boolean immediateNotify);
public static native int addEntryListener(String prefix, EntryListenerFunction listener, boolean immediateNotify, boolean localNotify);
public static native void removeEntryListener(int entryListenerUid);
public interface ConnectionListenerFunction {

View File

@@ -310,6 +310,16 @@ public interface ITable {
*/
public void addTableListener(ITableListener listener,
boolean immediateNotify);
/**
* 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
*/
public void addTableListener(ITableListener listener, boolean immediateNotify,
boolean localNotify);
/**
* Add a listener for changes to a specific key the table
@@ -320,11 +330,30 @@ public interface ITable {
*/
public void addTableListener(String key, ITableListener listener,
boolean immediateNotify);
/**
* 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
*/
public void addTableListener(String key, ITableListener listener,
boolean immediateNotify, boolean localNotify);
/**
* This will immediately notify the listener of all current sub tables
* @param listener
*/
public void addSubTableListener(final ITableListener listener);
/**
* This will immediately notify the listener of all current sub tables
* @param listener
* @param localNotify if true then this listener will be notified of all
* local changes in addition to all remote changes
*/
public void addSubTableListener(final ITableListener listener,
boolean localNotify);
/**
* Remove a listener from receiving table events
* @param listener the listener to be removed