コード例 #1
0
ファイル: Presence.cs プロジェクト: Mazyod/PhoenixSharp
        /**
         * Used to sync a diff of presence join and leave
         * events from the server, as they happen. Like `syncState`, `syncDiff`
         * accepts optional `onJoin` and `onLeave` callbacks to react to a user
         * joining or leaving from a device.
         */
        private static State SyncDiff(
            State state,
            Diff diff,
            OnJoinDelegate onJoin,
            OnLeaveDelegate onLeave
            )
        {
            foreach (var key in diff.Joins.Keys)
            {
                var newPresence = diff.Joins[key];
                var found       = state.TryGetValue(key, out var currentPresence);
                state[key] = newPresence;
                if (found)
                {
                    var joinedRefs = state[key].Metas.Select(m => m["phx_ref"]).ToList();
                    var curMetas   = currentPresence.Metas.Where(m => joinedRefs.IndexOf(m["phx_ref"]) < 0).ToList();
                    state[key].Metas.InsertRange(0, curMetas);
                }

                onJoin?.Invoke(key, currentPresence, newPresence);
            }

            foreach (var key in diff.Leaves.Keys)
            {
                var leftPresence = diff.Leaves[key];
                var found        = state.TryGetValue(key, out var currentPresence);
                if (!found)
                {
                    continue;
                }

                var refsToRemove  = leftPresence.Metas.Select(m => m["phx_ref"]).ToList();
                var filteredMetas = currentPresence.Metas.Where(
                    m => refsToRemove.IndexOf(m["phx_ref"]) < 0).ToList();

                var newPresence = new MetadataContainer {
                    Metas = filteredMetas
                };
                onLeave?.Invoke(key, newPresence, leftPresence);
                if (newPresence.Metas.Count == 0)
                {
                    state.Remove(key);
                }
                else
                {
                    state[key] = newPresence;
                }
            }

            return(state);
        }
コード例 #2
0
        public static State SyncDiff(State currentState, Diff diff, OnJoinDelegate onJoin, OnLeaveDelegate onLeave)
        {
            var state = Clone(currentState);

            foreach (var entry in diff["joins"])
            {
                Item currentItem = null;
                if (state.ContainsKey(entry.Key))
                {
                    currentItem = state[entry.Key];
                }
                state[entry.Key] = entry.Value;
                if (currentItem != null)
                {
                    var joinedRefs = state[entry.Key]["metas"].Select(m => m["phx_ref"]).ToList();
                    var curMetas   = currentItem["metas"].Where(m => !joinedRefs.Contains(m["phx_ref"])).ToList();
                    state[entry.Key]["metas"] = curMetas.Concat(state[entry.Key]["metas"]).ToList();
                }
                onJoin?.Invoke(entry.Key, currentItem, entry.Value);
            }
            foreach (var entry in diff["leaves"])
            {
                if (!state.ContainsKey(entry.Key))
                {
                    continue;
                }
                var currentItem  = state[entry.Key];
                var refsToRemove = entry.Value["metas"].Select(m => m["phx_ref"]).ToList();
                currentItem["metas"] = currentItem["metas"].Where(m => !refsToRemove.Contains(m["phx_ref"])).ToList();
                onLeave?.Invoke(entry.Key, currentItem, entry.Value);
                if (currentItem["metas"].Count() == 0)
                {
                    state.Remove(entry.Key);
                }
            }
            return(state);
        }