/// <summary> /// Register a pipe with the junction. /// </summary> /// <remarks> /// <para> /// Pipes are registered by unique name and type, /// which must be either <c>Junction.INPUT</c> /// or <c>Junction.OUTPUT</c>. /// </para> /// <para> /// NOTE: You cannot have an INPUT pipe and an OUTPUT /// pipe registered with the same name. All pipe names /// must be unique regardless of type. /// </para> /// </remarks> /// <param name="name">name of the pipe</param> /// <param name="type">type (INPUT/OUTPUT) of the pipe</param> /// <param name="pipe">Pipefitting</param> /// <returns>true if successfully registered. false if another pipe exists by that name.</returns> public virtual bool RegisterPipe(string name, string type, IPipeFitting pipe) { bool success = true; if (PipesMaps.TryGetValue(name, out IPipeFitting value) == false && PipesMaps.TryAdd(name, pipe) && PipeTypesMap.TryAdd(name, type)) { switch (type) { case INPUT: InputPipes.Add(name); break; case OUTPUT: OutputPipes.Add(name); break; default: success = false; break; } } else { success = false; } return(success); }
public void TestConnectingAndDisconnectingIOPipes() { // create output pipes 1 IPipeFitting pipe1 = new Pipe(); IPipeFitting pipe2 = new Pipe(); // create filter IPipeFitting filter = new Filter("TestFilter"); // connect input fitting bool connectedInput = pipe1.Connect(filter); // connect output fitting bool connectedOutput = filter.Connect(pipe2); // test assertions Assert.IsTrue(pipe1 is Pipe, "pipe1 is Pipe"); Assert.IsTrue(pipe2 is Pipe, "pipe2 is Pipe"); Assert.IsTrue(filter is Filter, "Expecting filter is Filter"); Assert.IsTrue(connectedInput, "Expecting connected input"); Assert.IsTrue(connectedOutput, "Expected connected output"); // disconnect pipe 2 from filter IPipeFitting disconnectedPipe = filter.Disconnect(); Assert.IsTrue(disconnectedPipe == pipe2, "Expecting disconnected pipe2 from filter"); }
/// <summary> /// Disconnect the Pipe Fitting connected to the output. /// </summary> /// <remarks> /// <para> /// This disconnects the output fitting, returning a /// reference to it. If you were splicing another fitting /// into a pipeline, you need to keep (at least briefly) /// a reference to both sides of the pipeline in order to /// connect them to the input and output of whatever /// fiting that you're splicing in. /// </para> /// </remarks> /// <returns>IPipeFitting the now disconnected output fitting</returns> public virtual IPipeFitting Disconnect() { IPipeFitting disconnectedFitting = Output; Output = null; return(disconnectedFitting); }
/// <summary> /// Constructor with an optional output <c>Pipe</c> /// </summary> /// <param name="output"></param> public Pipe(IPipeFitting output = null) { if (output != null) { Connect(output); } }
/// <summary> /// Constructor. /// </summary> /// <remarks> /// <para> /// Create the TeeMerge and the two optional constructor inputs. /// This is the most common configuration, though you can connect /// as many inputs as necessary by calling <c>connectInput</c> /// repeatedly. /// </para> /// <para> /// Connect the single output fitting normally by calling the /// <c>connect</c> method, as you would with any other IPipeFitting. /// </para> /// </remarks> /// <param name="input1">Input pipe</param> /// <param name="input2">Input pipe</param> public TeeMerge(IPipeFitting input1 = null, IPipeFitting input2 = null) { if (input1 != null) { ConnectInput(input1); } if (input2 != null) { ConnectInput(input2); } }
/// <summary> /// Connect another PipeFitting to the output. /// </summary> /// <remarks> /// <para> /// PipeFittings connect to and write to other /// PipeFittings in a one-way, syncrhonous chain. /// </para> /// </remarks> /// <param name="output">Pipefitting to connect</param> /// <returns>Boolean true if no other fitting was already connected.</returns> public virtual bool Connect(IPipeFitting output) { bool success = false; if (Output == null) { Output = output; success = true; } return(success); }
/// <summary> /// Constructor. /// </summary> /// <remarks> /// <para> /// Create the TeeSplit and connect the up two optional outputs. /// This is the most common configuration, though you can connect /// as many outputs as necessary by calling <c>connect</c>. /// </para> /// </remarks> /// <param name="output1">Output pipe</param> /// <param name="output2">Output pipe</param> public TeeSplit(IPipeFitting output1 = null, IPipeFitting output2 = null) { if (output1 != null) { Connect(output1); } if (output2 != null) { Connect(output2); } }
/// <summary> /// Constructor. /// </summary> /// <param name="name">Name of the filter</param> /// <param name="output">Output pipe</param> /// <param name="filter">Filter function</param> /// <param name="params">Filter function parameters</param> public Filter(string name, IPipeFitting output = null, Func <IPipeMessage, object, bool> filter = null, object @params = null) : base(output) { this.name = name; if (filter != null) { SetFilter(filter); } if (@params != null) { SetParams(@params); } }
/// <summary> /// Disconnect a given output fitting. /// </summary> /// <remarks> /// <para> /// If the fitting passed in is connected /// as an output of this <c>TeeSplit</c>, then /// it is disconnected and the reference returned. /// </para> /// <para> /// If the fitting passed in is not connected as an /// output of this <c>TeeSplit</c>, then <c>null</c> /// is returned. /// </para> /// </remarks> /// <param name="target">Pipe to disconnect</param> /// <returns>the disconnected IPipeFitting to connect for output.</returns> public virtual IPipeFitting DisconnectFitting(IPipeFitting target) { IPipeFitting removed = null; int index = outputs.FindIndex(output => output == target); if (index != -1) { removed = outputs[index]; outputs.RemoveAt(index); } return(removed); }
/// <summary> /// Disconnect the most recently connected output fitting. (LIFO) /// </summary> /// <remarks> /// <para> /// To disconnect all outputs, you must call this /// method repeatedly untill it returns null. /// </para> /// </remarks> /// <returns>the disconnected IPipeFitting to connect for output.</returns> public virtual IPipeFitting Disconnect() { if (outputs.Count > 0) { IPipeFitting pipe = outputs[outputs.Count - 1]; outputs.RemoveAt(outputs.Count - 1); return(pipe); } else { return(null); } }
public void TestConnectingAndDisconnectingTwoPipes() { // create two pipes IPipeFitting pipe1 = new Pipe(); IPipeFitting pipe2 = new Pipe(); // connect them bool success = pipe1.Connect(pipe2); // test assertions Assert.IsTrue(pipe1 is Pipe, "pipe1 is Pipe"); Assert.IsTrue(pipe2 is Pipe, "pipe2 is Pipe"); Assert.IsTrue(success, "Expecting connected pipe1 to pipe2"); // disconnect pipe 2 from pipe 1 IPipeFitting disconnectedPipe = pipe1.Disconnect(); Assert.IsTrue(disconnectedPipe == pipe2, "Expecting disconnected pipe2 from pipe1"); }
/// <summary> /// Handle Notification. /// </summary> /// <remarks> /// <para> /// This provides the handling for common junction activities. It /// accepts input and output pipes in response to <c>IPipeAware</c> /// interface calls. /// </para> /// <para> /// Override in subclass, and call <c>super.handleNotification</c> /// if none of the subclass-specific notification names are matched. /// </para> /// </remarks> /// <param name="notification"></param> public override void HandleNotification(INotification notification) { switch (notification.Name) { // accept an input pipe // register the pipe and if successful // set this mediator as its listener case JunctionMediator.ACCEPT_INPUT_PIPE: string inputPipeName = notification.Type; IPipeFitting inputPipe = (IPipeFitting)notification.Body; if (Junction.RegisterPipe(inputPipeName, Junction.INPUT, inputPipe)) { Junction.AddPipeListener(inputPipeName, this, HandlePipeMessage); } break; // accept an output pipe case JunctionMediator.ACCEPT_OUTPUT_PIPE: string outputPipeName = notification.Type; IPipeFitting outputPipe = (IPipeFitting)notification.Body; Junction.RegisterPipe(outputPipeName, Junction.OUTPUT, outputPipe); break; } }
/// <summary> /// Can't connect anything beyond this. /// </summary> /// <param name="output"></param> /// <returns></returns> public virtual bool Connect(IPipeFitting output) { return(false); }
/// <summary> /// Connect an input IPipeFitting. /// </summary> /// <remarks> /// <para> /// NOTE: You can connect as many inputs as you want /// by calling this method repeatedly. /// </para> /// </remarks> /// <param name="input">the IPipeFitting to connect for input.</param> /// <returns>true if pipe connected successfully</returns> public virtual bool ConnectInput(IPipeFitting input) { return(input.Connect(this)); }
/// <summary> /// Queue constructor /// </summary> /// <param name="output">Optional output pipe</param> public Queue(IPipeFitting output = null) : base(output) { }
/// <summary> /// Connect the output IPipeFitting. /// </summary> /// <remarks> /// <para> /// NOTE: You can connect as many outputs as you want /// by calling this method repeatedly. /// </para> /// </remarks> /// <param name="output">the IPipeFitting to connect for output.</param> /// <returns>true if connect was successful</returns> public virtual bool Connect(IPipeFitting output) { outputs.Add(output); return(true); }