|
|
@@ -81,6 +81,8 @@ public class NetworkTable : ITable, IRemote |
|
|
/// <summary>The default port NetworkTables listens on.</summary>
|
|
|
public const uint DefaultPort = 1735;
|
|
|
|
|
|
+ private static object s_lockObject = new object();
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// The default file name used for Persistent Storage.
|
|
|
/// </summary>
|
|
|
@@ -94,8 +96,11 @@ public class NetworkTable : ITable, IRemote |
|
|
|
|
|
private static void CheckInit()
|
|
|
{
|
|
|
- if (Running)
|
|
|
- throw new InvalidOperationException("Network Tables has already been initialized");
|
|
|
+ lock (s_lockObject)
|
|
|
+ {
|
|
|
+ if (Running)
|
|
|
+ throw new InvalidOperationException("Network Tables has already been initialized");
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
@@ -108,35 +113,41 @@ private static void CheckInit() |
|
|
/// </remarks>
|
|
|
public static void Initialize()
|
|
|
{
|
|
|
- if (Running)
|
|
|
- Shutdown();
|
|
|
- if (Client)
|
|
|
- {
|
|
|
- CoreMethods.StartClient(IPAddress, Port);
|
|
|
- }
|
|
|
- else
|
|
|
+ lock (s_lockObject)
|
|
|
{
|
|
|
- CoreMethods.StartServer(PersistentFilename, "", Port);
|
|
|
+ if (Running)
|
|
|
+ Shutdown();
|
|
|
+ if (Client)
|
|
|
+ {
|
|
|
+ CoreMethods.StartClient(IPAddress, Port);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ CoreMethods.StartServer(PersistentFilename, "", Port);
|
|
|
+ }
|
|
|
+ Running = true;
|
|
|
}
|
|
|
- Running = true;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// Shuts down NetworkTables.
|
|
|
/// </summary>
|
|
|
public static void Shutdown()
|
|
|
{
|
|
|
- if (!Running)
|
|
|
- return;
|
|
|
- if (Client)
|
|
|
- {
|
|
|
- CoreMethods.StopClient();
|
|
|
- }
|
|
|
- else
|
|
|
+ lock (s_lockObject)
|
|
|
{
|
|
|
- CoreMethods.StopServer();
|
|
|
+ if (!Running)
|
|
|
+ return;
|
|
|
+ if (Client)
|
|
|
+ {
|
|
|
+ CoreMethods.StopClient();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ CoreMethods.StopServer();
|
|
|
+ }
|
|
|
+ Running = false;
|
|
|
}
|
|
|
- Running = false;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
@@ -148,10 +159,13 @@ public static void Shutdown() |
|
|
/// before <see cref="Initialize"/> or <see cref="GetTable(string)"/>.</remarks>
|
|
|
public static void SetClientMode()
|
|
|
{
|
|
|
- if (Client)
|
|
|
- return;
|
|
|
- CheckInit();
|
|
|
- Client = true;
|
|
|
+ lock (s_lockObject)
|
|
|
+ {
|
|
|
+ if (Client)
|
|
|
+ return;
|
|
|
+ CheckInit();
|
|
|
+ Client = true;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
@@ -163,10 +177,13 @@ public static void SetClientMode() |
|
|
/// before <see cref="Initialize"/> or <see cref="GetTable(string)"/></remarks>
|
|
|
public static void SetServerMode()
|
|
|
{
|
|
|
- if (!Client)
|
|
|
- return;
|
|
|
- CheckInit();
|
|
|
- Client = false;
|
|
|
+ lock (s_lockObject)
|
|
|
+ {
|
|
|
+ if (!Client)
|
|
|
+ return;
|
|
|
+ CheckInit();
|
|
|
+ Client = false;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
@@ -178,7 +195,10 @@ public static void SetServerMode() |
|
|
/// <see cref="GetTable(string)"/> if the system is a client.</remarks>
|
|
|
public static void SetTeam(int team)
|
|
|
{
|
|
|
- SetIPAddress($"roboRIO-{team}-FRC.local");
|
|
|
+ lock (s_lockObject)
|
|
|
+ {
|
|
|
+ SetIPAddress($"roboRIO-{team}-FRC.local");
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
@@ -187,10 +207,13 @@ public static void SetTeam(int team) |
|
|
/// <param name="address">The IP address to connect to in client mode</param>
|
|
|
public static void SetIPAddress(string address)
|
|
|
{
|
|
|
- if (IPAddress == address)
|
|
|
- return;
|
|
|
- CheckInit();
|
|
|
- IPAddress = address;
|
|
|
+ lock (s_lockObject)
|
|
|
+ {
|
|
|
+ if (IPAddress == address)
|
|
|
+ return;
|
|
|
+ CheckInit();
|
|
|
+ IPAddress = address;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
@@ -202,10 +225,13 @@ public static void SetIPAddress(string address) |
|
|
/// <returns>The <see cref="NetworkTable"/> requested.</returns>
|
|
|
public static NetworkTable GetTable(string key)
|
|
|
{
|
|
|
- if (!Running) Initialize();
|
|
|
- if (key == "")
|
|
|
- return new NetworkTable(key);
|
|
|
- return new NetworkTable(PathSeperatorChar + key);
|
|
|
+ lock (s_lockObject)
|
|
|
+ {
|
|
|
+ if (!Running) Initialize();
|
|
|
+ if (key == "" || key[0] == PathSeperatorChar)
|
|
|
+ return new NetworkTable(key);
|
|
|
+ return new NetworkTable(PathSeperatorChar + key);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
@@ -912,6 +938,9 @@ public void RemoveTableListener(Action<ITable, string, object, NotifyFlags> list |
|
|
private readonly Dictionary<IRemoteConnectionListener, int> m_connectionListenerMap =
|
|
|
new Dictionary<IRemoteConnectionListener, int>();
|
|
|
|
|
|
+ private readonly Dictionary<Action<IRemote, ConnectionInfo, bool>, int> m_actionConnectionListenerMap
|
|
|
+ = new Dictionary<Action<IRemote, ConnectionInfo, bool>, int>();
|
|
|
+
|
|
|
///<inheritdoc/>
|
|
|
public void AddConnectionListener(IRemoteConnectionListener listener, bool immediateNotify)
|
|
|
{
|
|
|
@@ -923,8 +952,8 @@ public void AddConnectionListener(IRemoteConnectionListener listener, bool immed |
|
|
|
|
|
ConnectionListenerFunction func = (uid, connected, conn) =>
|
|
|
{
|
|
|
- if (connected) listener.Connected(this);
|
|
|
- else listener.Disconnected(this);
|
|
|
+ if (connected) listener.Connected(this, conn);
|
|
|
+ else listener.Disconnected(this, conn);
|
|
|
};
|
|
|
|
|
|
int id = CoreMethods.AddConnectionListener(func, immediateNotify);
|
|
|
@@ -943,6 +972,34 @@ public void RemoveConnectionListener(IRemoteConnectionListener listener) |
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /// <inheritdoc/>
|
|
|
+ public void AddConnectionListener(Action<IRemote, ConnectionInfo, bool> listener, bool immediateNotify)
|
|
|
+ {
|
|
|
+ if (m_actionConnectionListenerMap.ContainsKey(listener))
|
|
|
+ {
|
|
|
+ throw new ArgumentException("Cannot add the same listener twice", nameof(listener));
|
|
|
+ }
|
|
|
+
|
|
|
+ ConnectionListenerFunction func = (uid, connected, conn) =>
|
|
|
+ {
|
|
|
+ listener(this, conn, connected);
|
|
|
+ };
|
|
|
+
|
|
|
+ int id = CoreMethods.AddConnectionListener(func, immediateNotify);
|
|
|
+
|
|
|
+ m_actionConnectionListenerMap.Add(listener, id);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <inheritdoc/>
|
|
|
+ public void RemoveConnectionListener(Action<IRemote, ConnectionInfo, bool> listener)
|
|
|
+ {
|
|
|
+ int val;
|
|
|
+ if (m_actionConnectionListenerMap.TryGetValue(listener, out val))
|
|
|
+ {
|
|
|
+ CoreMethods.RemoveConnectionListener(val);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// Gets if the NetworkTables is connected to a client or server.
|
|
|
/// </summary>
|
|
|
|