/// <summary> /// Tries to move the child node down. /// </summary> /// <param name="Child">Child node to move.</param> /// <param name="Caller">Information about caller.</param> /// <returns>If the child node was moved down.</returns> public virtual async Task <bool> MoveDownAsync(MeteringNode Child, RequestOrigin Caller) { if (!this.ChildrenOrdered || this.children == null) { return(false); } if (!await this.CanEditAsync(Caller) || !await Child.CanEditAsync(Caller)) { return(false); } lock (this.children) { int c = this.children.Count; int i = this.children.IndexOf(Child); if (i < 0 || i + 1 >= c) { return(false); } this.children.RemoveAt(i); this.children.Insert(i + 1, Child); } await MeteringTopology.NewEvent(new NodeMovedDown() { NodeId = Child.NodeId, Partition = Child.Partition, SourceId = Child.SourceId, Timestamp = DateTime.Now }); return(true); }
/// <summary> /// Persists changes to the node, and generates a node updated event. /// </summary> protected virtual async Task NodeUpdated() { this.updated = DateTime.Now; await Database.Update(this); await MeteringTopology.NewEvent(new NodeUpdated() { Parameters = await this.GetDisplayableParameterAraryAsync(await Translator.GetDefaultLanguageAsync(), RequestOrigin.Empty), HasChildren = this.HasChildren, ChildrenOrdered = this.ChildrenOrdered, IsReadable = this.IsReadable, IsControllable = this.IsControllable, HasCommands = this.HasCommands, ParentId = this.NodeId, ParentPartition = this.Partition, Updated = this.Updated, State = this.State, NodeId = this.NodeId, OldId = this.oldId, Partition = this.Partition, LogId = MeteringTopology.EmptyIfSame(this.LogId, this.NodeId), LocalId = MeteringTopology.EmptyIfSame(this.LocalId, this.NodeId), SourceId = this.SourceId, Timestamp = DateTime.Now }); this.oldId = this.nodeId; }
/// <summary> /// Removes a child from the node. /// </summary> /// <param name="Child">Child to remove.</param> /// <returns>If the Child node was found and removed.</returns> public virtual async Task <bool> RemoveAsync(INode Child) { MeteringNode Node = Child as MeteringNode; if (Node == null) { throw new Exception("Child must be a metering node."); } if (!this.childrenLoaded) { await this.LoadChildren(); } int i; lock (this.synchObject) { if (this.children != null) { i = this.children.IndexOf(Node); if (i >= 0) { this.children.RemoveAt(i); if (i == 0 && this.children.Count == 0) { this.children = null; } } } else { i = -1; } } Node.parentId = Guid.Empty; Node.parent = null; if (Node.objectId != Guid.Empty) { await Database.Update(Child); this.RaiseUpdate(); await MeteringTopology.NewEvent(new NodeRemoved() { NodeId = Node.NodeId, Partition = Node.Partition, SourceId = Node.SourceId, Timestamp = DateTime.Now }); } return(i >= 0); }
internal async Task NodeStateChanged() { await MeteringTopology.NewEvent(new NodeStatusChanged() { Messages = await this.GetMessageArrayAsync(RequestOrigin.Empty), State = this.state, NodeId = this.NodeId, Partition = this.Partition, SourceId = this.SourceId, Timestamp = DateTime.Now }); }
private static async Task LoadRoot() { Root Result = null; foreach (MeteringNode Node in await Database.Find <MeteringNode>(new FilterFieldEqualTo("ParentId", Guid.Empty))) { if (Node is Root) { if (Result is null) { Result = (Root)Node; } else { await Database.Delete(Node); } } } if (Result is null) { Result = new Root() { NodeId = await(await Translator.GetDefaultLanguageAsync()).GetStringAsync(typeof(MeteringTopology), 14, "Root") }; await Database.Insert(Result); Language Language = await Translator.GetDefaultLanguageAsync(); await MeteringTopology.NewEvent(new NodeAdded() { Parameters = await Result.GetDisplayableParameterAraryAsync(Language, RequestOrigin.Empty), NodeType = Result.GetType().FullName, Sniffable = Result is ISniffable, DisplayName = await Result.GetTypeNameAsync(Language), HasChildren = Result.HasChildren, ChildrenOrdered = Result.ChildrenOrdered, IsReadable = Result.IsReadable, IsControllable = Result.IsControllable, HasCommands = Result.HasCommands, ParentId = string.Empty, ParentPartition = string.Empty, Updated = Result.Updated, State = Result.State, NodeId = Result.NodeId, Partition = Result.Partition, LogId = NodeAdded.EmptyIfSame(Result.LogId, Result.NodeId), LocalId = NodeAdded.EmptyIfSame(Result.LocalId, Result.NodeId), SourceId = Result.SourceId, Timestamp = DateTime.Now }); } lock (nodes) { nodes[Result.NodeId] = Result; } root = Result; }
/// <summary> /// Adds a new child to the node. /// </summary> /// <param name="Child">New child to add.</param> public virtual async Task AddAsync(INode Child) { MeteringNode Node = Child as MeteringNode; if (Node == null) { throw new Exception("Child must be a metering node."); } if (this.objectId == Guid.Empty) { throw new Exception("Parent node must be persisted before you can add nodes to it."); } if (!this.childrenLoaded) { await this.LoadChildren(); } Node.parentId = this.objectId; MeteringNode After = null; int c; lock (this.synchObject) { if (this.children == null) { this.children = new List <MeteringNode>(); } else if ((c = this.children.Count) > 0) { After = this.children[c - 1]; } this.children.Add(Node); Node.parent = this; } if (Node.objectId == Guid.Empty) { await Database.Insert(Node); MeteringTopology.RegisterNode(Node); Language Language = await Translator.GetDefaultLanguageAsync(); NodeAdded Event = new NodeAdded() { Parameters = await Node.GetDisplayableParameterAraryAsync(Language, RequestOrigin.Empty), NodeType = Node.GetType().FullName, Sniffable = this is ISniffable, DisplayName = await Node.GetTypeNameAsync(Language), HasChildren = Node.HasChildren, ChildrenOrdered = Node.ChildrenOrdered, IsReadable = Node.IsReadable, IsControllable = Node.IsControllable, HasCommands = Node.HasCommands, ParentId = this.NodeId, ParentPartition = this.Partition, Updated = Node.Updated, State = Node.State, NodeId = Node.NodeId, Partition = Node.Partition, LogId = MeteringTopology.EmptyIfSame(Node.LogId, Node.NodeId), LocalId = MeteringTopology.EmptyIfSame(Node.LocalId, Node.NodeId), SourceId = Node.SourceId, Timestamp = DateTime.Now }; if (this.ChildrenOrdered && After != null) { Event.AfterNodeId = After.nodeId; Event.AfterPartition = After.Partition; } await MeteringTopology.NewEvent(Event); } else { await Node.NodeUpdated(); } this.RaiseUpdate(); }