void OnDieDisconnected(Central.IDie die, bool result, string errorMessage) { var ourDie = dice.Find(d => d.die.address == die.address); if (ourDie != null) { if (result) { ourDie.setState.Invoke(Die.ConnectionState.Available); // Reset connection count now that nothing is connected to the die ourDie.currentConnectionCount = 0; } else { // Could not disconnect the die, indicate that! ourDie.setError.Invoke(Die.LastError.ConnectionError); } var callbackCopy = ourDie.onDisconnectionResult; ourDie.onDisconnectionResult = null; callbackCopy?.Invoke(ourDie.die, result, errorMessage); } else { Debug.LogError("Received Die disconnected notification for unknown die " + die.name); } }
/// <summary> /// Called by Central when it receives custom advertising data, this allows us to change the /// appearance of the scanned die before even connecting to it! /// </sumary> void OnDieAdvertisingData(Central.IDie die, int rssi, byte[] data) { // Find the die by its address, in both lists of dice we expect to know and new dice var ourDie = dice.FirstOrDefault(d => d.die.address == die.address); if (ourDie != null) { // Marshall the data into the struct we expect int size = Marshal.SizeOf(typeof(Die.CustomAdvertisingData)); if (data.Length == size) { System.IntPtr ptr = Marshal.AllocHGlobal(size); Marshal.Copy(data, 0, ptr, size); var customData = Marshal.PtrToStructure <Die.CustomAdvertisingData>(ptr); Marshal.FreeHGlobal(ptr); // Update die data ourDie.die.UpdateAdvertisingData(rssi, customData); onDieDiscovered?.Invoke(ourDie.die); } else { Debug.LogError("Incorrect advertising data length " + data.Length + ", expected: " + size); } } }
/// <summary> /// Called by Central when it receives data for a connected die! /// </sumary> void OnDieData(Central.IDie die, byte[] data) { // Pass on the data var ourDie = dice.FirstOrDefault(d => d.die.address == die.address); if (ourDie != null) { ourDie.die.OnData(data); } else { Debug.LogError("Received data for die " + die.name + " that isn't part of the pool"); } }
/// <summary> /// Called by Central when a die gets disconnected unexpectedly /// </sumary> void OnDieDisconnectedUnexpectedly(Central.IDie die, string errorMessage) { Debug.LogError(die.name + ": Die disconnected"); var ourDie = dice.FirstOrDefault(d => d.die.address == die.address); if (ourDie != null) { ourDie.setState.Invoke(Die.ConnectionState.Available); ourDie.setError.Invoke(Die.LastError.Disconnected); // Reset connection count since it didn't succeed ourDie.currentConnectionCount = 0; // Forget the die for now DestroyDie(ourDie); } }
/// <summary> /// Called by Central when a new die is discovered! /// </sumary> void OnDieDiscovered(Central.IDie die) { // If the die exists, tell it that it's advertising now // otherwise create it (and tell it that its advertising :) var ourDie = dice.FirstOrDefault(d => { if (!string.IsNullOrEmpty(d.die.address)) { return(d.die.address == die.address); } else { return(d.die.name == die.name); } }); if (ourDie == null) { // Never seen this die before ourDie = CreateDie(die); ourDie.setState.Invoke(Die.ConnectionState.Available); onDieDiscovered?.Invoke(ourDie.die); } else { // Update die address if necessary if (string.IsNullOrEmpty(ourDie.die.address)) { ourDie.die.UpdateAddress(die.address); } onDieDiscovered?.Invoke(ourDie.die); if (ourDie.die.connectionState != Die.ConnectionState.Available) { // All other are errors Debug.LogError("Die " + ourDie.die.name + " in invalid state " + ourDie.die.connectionState); ourDie.setState(Die.ConnectionState.Available); } } }
/// <summary> /// Creates a new die for the pool /// </sumary> PoolDie CreateDie(Central.IDie centralDie, uint deviceId = 0, int faceCount = 0, DesignAndColor design = DesignAndColor.Unknown) { var dieObj = new GameObject(name); dieObj.transform.SetParent(transform); Die die = dieObj.AddComponent <Die>(); System.Action <Die.ConnectionState> setStateAction; System.Action <Die.LastError> setLastErrorAction; die.Setup(centralDie.name, centralDie.address, deviceId, faceCount, design, out setStateAction, out setLastErrorAction); var ourDie = new PoolDie() { die = die, centralDie = centralDie, setState = setStateAction, setError = setLastErrorAction, }; dice.Add(ourDie); return(ourDie); }
/// <summary> /// Called by central when a die is properly connected to (i.e. two-way communication is working) /// We still need to do a bit of work before the die can be available for general us though /// </sumary> void OnDieConnected(Central.IDie die, bool result, string errorMessage) { var ourDie = dice.Find(d => d.die.address == die.address); if (ourDie != null) { if (result) { // Remember that the die was just connected to (and trigger events) ourDie.setState.Invoke(Die.ConnectionState.Identifying); // And have it update its info (unique Id, appearance, etc...) so it can finally be ready ourDie.die.UpdateInfo(OnDieReady); // Reset error ourDie.setError(Die.LastError.None); } else { // Remember that the die was just connected to (and trigger events) ourDie.setState.Invoke(Die.ConnectionState.Available); // Could not connect to the die, indicate that! ourDie.setError(Die.LastError.ConnectionError); // Reset connection count since it didn't succeed ourDie.currentConnectionCount = 0; // Trigger callback var callbackCopy = ourDie.onConnectionResult; ourDie.onConnectionResult = null; callbackCopy?.Invoke(ourDie.die, false, errorMessage); } } else { Debug.LogError("Received Die connected notification for unknown die " + die.name); } }
void OnDieDisconnected(Central.IDie die) { onDieDisconnected?.Invoke((Die)die); }
void OnDieReady(Central.IDie die) { onDieConnected?.Invoke((Die)die); }