Beispiel #1
0
        /// <summary>
        /// Handles view model update from a browser client.
        /// </summary>
        /// <param name="connectionId">Identifies the client connection.</param>
        /// <param name="vmId">Identifies the view model.</param>
        /// <param name="iData">View model update.</param>
        public virtual void OnUpdateVM(string connectionId, string vmId, Dictionary <string, object> data)
        {
            bool isRecreated = false;

            if (!_activeVMs.ContainsKey(vmId))
            {
                // No view model found; it must have expired and needs to be recreated.
                isRecreated = true;
                OnRequestVM(connectionId, vmId);
                if (!_activeVMs.ContainsKey(vmId))
                {
                    return;
                }
            }

            // Update the new values from the client to the server view model.
            var vmInstance = _activeVMs[vmId].Instance;

            // Invoke the interception delegate.
            UpdateVMFilter.Invoke(vmId, vmInstance, data, filteredData =>
            {
                lock (vmInstance)
                {
                    foreach (var kvp in filteredData as Dictionary <string, object> )
                    {
                        UpdateVM(vmInstance, kvp.Key, kvp.Value != null ? kvp.Value.ToString() : "");
                    }
                }

                // If the updates cause some properties of this and other view models to change, push those new values back to the client.
                // For multicast view models, use their PushUpdates method to push to any other connected clients.
                if (vmInstance is MulticastVM)
                {
                    vmInstance.PushUpdates();
                }
                else
                {
                    // Unless the view model was recreated, exclude the changes that trigger this update if their values don't change.
                    if (!isRecreated)
                    {
                        foreach (var kvp in data)
                        {
                            if (vmInstance.IsEqualToChangedPropertyValue(kvp.Key, kvp.Value))
                            {
                                vmInstance.ChangedProperties.TryRemove(kvp.Key, out object dummy);
                            }
                        }
                    }

                    PushUpdates();
                }
            });
        }
Beispiel #2
0
        /// <summary>
        /// Handles view model update from a browser client.
        /// </summary>
        /// <param name="connectionId">Identifies the client connection.</param>
        /// <param name="vmId">Identifies the view model.</param>
        /// <param name="iData">View model update.</param>
        public virtual void OnUpdateVM(string connectionId, string vmId, Dictionary <string, object> data)
        {
            bool isRecreated = false;

            if (!_activeVMs.ContainsKey(vmId))
            {
                // No view model found; it must have expired and needs to be recreated.
                isRecreated = true;
                OnRequestVM(connectionId, vmId);
                if (!_activeVMs.ContainsKey(vmId))
                {
                    return;
                }
            }

            // Update the new values from the client to the server view model.
            var vmInstance = _activeVMs[vmId].Instance;

            // Invoke the interception delegate.
            UpdateVMFilter.Invoke(vmId, vmInstance, data, filteredData =>
            {
                lock (vmInstance)
                {
                    foreach (var kvp in filteredData as Dictionary <string, object> )
                    {
                        UpdateVM(vmInstance, kvp.Key, kvp.Value != null ? kvp.Value.ToString() : "");

                        // If the view model was recreated, include the changes that trigger this update to overwrite their initial values.
                        if (isRecreated && !vmInstance.ChangedProperties.ContainsKey(kvp.Key))
                        {
                            vmInstance.ChangedProperties.TryAdd(kvp.Key, kvp.Value);
                        }
                    }
                }

                // If the updates cause some properties of this and other view models to change, push those new values back to the client.
                PushUpdates();
            });
        }
Beispiel #3
0
        /// <summary>
        /// Handles view model update from a browser client.
        /// </summary>
        /// <param name="connectionId">Identifies the client connection.</param>
        /// <param name="vmId">Identifies the view model.</param>
        /// <param name="iData">View model update.</param>
        public virtual void OnUpdateVM(string connectionId, string vmId, Dictionary <string, object> data)
        {
            bool isRecreated = false;

            if (!_activeVMs.ContainsKey(vmId))
            {
                // No view model found; it must have expired and needs to be recreated.
                isRecreated = true;
                OnRequestVM(connectionId, vmId);
                if (!_activeVMs.ContainsKey(vmId))
                {
                    return;
                }
            }

            // Update the new values from the client to the server view model.
            var vmInstance = _activeVMs[vmId].Instance;

            // Invoke the interception delegate.
            UpdateVMFilter.Invoke(vmId, vmInstance, data, filteredData =>
            {
                lock (vmInstance)
                {
                    foreach (var kvp in filteredData as Dictionary <string, object> )
                    {
                        UpdateVM(vmInstance, kvp.Key, kvp.Value != null ? kvp.Value.ToString() : "");
                    }
                }

                // If the updates cause some properties of this and other view models to change, push those new values back to the client.
                lock (vmInstance)
                {
                    var vmInfo            = _activeVMs.Values.FirstOrDefault(vm => vm.Instance == vmInstance);
                    var changedProperties = new Dictionary <string, object>(vmInstance.ChangedProperties);

                    // Unless the view model was recreated, exclude the changes that trigger this update if their values don't change.
                    if (!isRecreated)
                    {
                        foreach (var kvp in data)
                        {
                            if (vmInstance.IsEqualToChangedPropertyValue(kvp.Key, kvp.Value))
                            {
                                changedProperties.Remove(kvp.Key);
                            }
                        }
                    }

                    if (changedProperties.Count > 0)
                    {
                        var vmData = vmInstance.Serialize(changedProperties);
                        PushUpdates(vmInfo, vmData);
                    }

                    if (vmInstance is MulticastVM)
                    {
                        (vmInstance as MulticastVM).PushUpdatesExcept(vmInfo.ConnectionId);
                    }
                    else
                    {
                        vmInstance.AcceptChangedProperties();
                    }
                }

                // Push updates on other view model instances in case they too change.
                foreach (var vmInfo in _activeVMs.Values.Where(vm => vm.Instance != vmInstance))
                {
                    PushUpdates(vmInfo);
                }
            });
        }
Beispiel #4
0
        /// <summary>
        /// Handles view model update from a browser client.
        /// </summary>
        /// <param name="connectionId">Identifies the client connection.</param>
        /// <param name="vmId">Identifies the view model.</param>
        /// <param name="iData">View model update.</param>
        public async Task OnUpdateVMAsync(string connectionId, string vmId, Dictionary <string, object> data)
        {
            if (!_activeVMs.ContainsKey(vmId))
            {
                Logger.LogError($"Update to '{vmId}' received before connect request");
                return;
            }

            // Update the new values from the client to the server view model.
            var vmInstance = _activeVMs[vmId].Instance;

            // Invoke the interception delegate.
            await UpdateVMFilter.Invoke(vmId, vmInstance, data, async filteredData =>
            {
                List <Task> asyncCommands = null;

                lock (vmInstance)
                {
                    foreach (var kvp in filteredData as Dictionary <string, object> )
                    {
                        UpdateVM(vmInstance, kvp.Key, kvp.Value != null ? kvp.Value.ToString() : "");
                    }

                    if (vmInstance.AsyncCommands.Count > 0)
                    {
                        asyncCommands = new List <Task>(vmInstance.AsyncCommands);
                        vmInstance.AsyncCommands.Clear();
                    }
                }

                /// Await for any asynchronous command executed during deserialization.
                if (asyncCommands != null)
                {
                    await Task.WhenAll(asyncCommands);
                }

                // If the updates cause some properties of this and other view models to change, push those new values back to the client.
                lock (vmInstance)
                {
                    var vmInfo = _activeVMs.Values.FirstOrDefault(vm => vm.Instance == vmInstance);
                    if (vmInfo != null)
                    {
                        var changedProperties = new Dictionary <string, object>(vmInstance.ChangedProperties);

                        // Exclude the changes that trigger this update if their values don't change.
                        foreach (var kvp in data)
                        {
                            if (vmInstance.IsEqualToChangedPropertyValue(kvp.Key, kvp.Value))
                            {
                                changedProperties.Remove(kvp.Key);
                            }
                        }

                        if (changedProperties.Count > 0)
                        {
                            var vmData = vmInstance.Serialize(changedProperties);
                            PushUpdates(vmInfo, vmData);
                        }

                        if (vmInstance is MulticastVM)
                        {
                            (vmInstance as MulticastVM).PushUpdatesExcept(vmInfo.ConnectionId);
                        }
                        else
                        {
                            vmInstance.AcceptChangedProperties();
                        }
                    }
                }

                // Push updates on other view model instances in case they too change.
                foreach (var vmInfo in _activeVMs.Values.Where(vm => vm.Instance != vmInstance))
                {
                    PushUpdates(vmInfo);
                }
            });
        }