#region License Information /* HeuristicLab * Copyright (C) 2002-2014 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Core.Networks; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Threading; namespace HeuristicLab.Networks.Programmable { [Item("ProgrammableNode", "Abstract base class for programmable nodes of a network.")] [StorableClass] public abstract class ProgrammableNode : ProgrammableNetworkItem, IProgrammableNode { public static new Image StaticItemImage { get { return HeuristicLab.Common.Resources.VSImageLibrary.RadialChart; } } #region Node Members new public INetwork Parent { get { return CompiledNetworkItem.Parent; } set { // NOTE: never call setter directly as the Parent property is set by the network which contains the node CompiledNetworkItem.Parent = value; } } [Storable] private PortCollection ports; protected PortCollection Ports { get { return CompiledNetworkItem.Ports; } } private ReadOnlyKeyedItemCollection readOnlyPorts; IKeyedItemCollection INode.Ports { get { if (readOnlyPorts == null) readOnlyPorts = Ports.AsReadOnly(); return readOnlyPorts; } } #endregion protected override string CodeTemplate { get { return CodeResources.ProgrammableNodeCode; } } new protected CompiledProgrammableNode CompiledNetworkItem { get { return (CompiledProgrammableNode)base.CompiledNetworkItem; } } [StorableConstructor] protected ProgrammableNode(bool deserializing) : base(deserializing) { } protected ProgrammableNode(ProgrammableNode original, Cloner cloner) : base(original, cloner) { // ports are cloned in CompiledProgrammableNode readOnlyPorts = null; } protected ProgrammableNode() : base("ProgrammableNode") { ports = new PortCollection(); readOnlyPorts = null; } protected ProgrammableNode(string name) : base(name) { ports = new PortCollection(); readOnlyPorts = null; } protected ProgrammableNode(string name, string description) : base(name, description) { ports = new PortCollection(); readOnlyPorts = null; } #region CompiledProgrammableNode [Item("CompiledProgrammableNode", "Abstract base class for compiled programmable nodes of a network.")] public abstract class CompiledProgrammableNode : CompiledProgrammableNetworkItem, INode { public static new Image StaticItemImage { get { return HeuristicLab.Common.Resources.VSImageLibrary.RadialChart; } } #region Node Members new public INetwork Parent { get { return (INetwork)base.Parent; } set { // NOTE: never call setter directly as the Parent property is set by the network which contains the node base.Parent = value; } } public override IEnumerable Children { get { return base.Children.Concat(Ports.AsEnumerable()); } } public PortCollection Ports { get { return Context.ports; } } IKeyedItemCollection INode.Ports { get { return Ports; } } #endregion new protected ProgrammableNode Context { get { return (ProgrammableNode)base.Context; } } protected CompiledProgrammableNode(CompiledProgrammableNode original, Cloner cloner) : base(original, cloner) { Context.ports = cloner.Clone(original.Context.ports); } protected CompiledProgrammableNode(ProgrammableNode context) : base(context) { } public override void Initialize() { base.Initialize(); Ports.Clear(); } private void MessagePort_MessageReceived(object sender, EventArgs e) { ProcessMessage(e.Value, (IMessagePort)sender, e.Value2); } protected virtual void ProcessMessage(IMessage message, IMessagePort port, CancellationToken token) { } #region Events public override void RegisterEvents() { base.RegisterEvents(); Ports.ItemsAdded += Ports_ItemsAdded; Ports.ItemsRemoved += Ports_ItemsRemoved; Ports.ItemsReplaced += Ports_ItemsReplaced; Ports.CollectionReset += Ports_CollectionReset; foreach (var p in Ports) { p.Parent = this; RegisterPortEvents(p); } } public override void DeregisterEvents() { foreach (var p in Ports) { DeregisterPortEvents(p); p.Parent = null; } Ports.ItemsAdded -= Ports_ItemsAdded; Ports.ItemsRemoved -= Ports_ItemsRemoved; Ports.ItemsReplaced -= Ports_ItemsReplaced; Ports.CollectionReset -= Ports_CollectionReset; base.DeregisterEvents(); } protected virtual void Ports_ItemsAdded(object sender, Collections.CollectionItemsChangedEventArgs e) { foreach (var p in e.Items) { p.Parent = this; RegisterPortEvents(p); } } protected virtual void Ports_ItemsRemoved(object sender, Collections.CollectionItemsChangedEventArgs e) { foreach (var p in e.Items) { p.Parent = null; DeregisterPortEvents(p); } } protected virtual void Ports_ItemsReplaced(object sender, Collections.CollectionItemsChangedEventArgs e) { foreach (var p in e.OldItems) { p.Parent = null; DeregisterPortEvents(p); } foreach (var p in e.Items) { p.Parent = this; RegisterPortEvents(p); } } protected virtual void Ports_CollectionReset(object sender, Collections.CollectionItemsChangedEventArgs e) { foreach (var p in e.OldItems) { p.Parent = null; DeregisterPortEvents(p); } foreach (var p in e.Items) { p.Parent = this; RegisterPortEvents(p); } } #endregion #region Port Events protected virtual void RegisterPortEvents(IPort port) { var mp = port as IMessagePort; if (mp != null) mp.MessageReceived += MessagePort_MessageReceived; } protected virtual void DeregisterPortEvents(IPort port) { var mp = port as IMessagePort; if (mp != null) mp.MessageReceived -= MessagePort_MessageReceived; } #endregion } #endregion } }