Skip to content

Commit 25e86f4

Browse files
committed
Implement types and WIP pipe fittings
1 parent 6f2ebfe commit 25e86f4

File tree

16 files changed

+659
-682
lines changed

16 files changed

+659
-682
lines changed

src/plumbing/Filter.as

Lines changed: 0 additions & 184 deletions
This file was deleted.

src/plumbing/Filter.ts

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
import { Pipe } from "./Pipe";
2+
import {
3+
FilterControlMessage,
4+
FilterControlMessageType,
5+
IPipeFitting,
6+
PipeMessage,
7+
PipeMessageType,
8+
} from "../types";
9+
import { FilterControlFunction } from "../types/pipe";
10+
11+
/**
12+
* Pipe Filter.
13+
*
14+
* Filters may modify the contents of messages before writing them to
15+
* their output pipe fitting. They may also have their parameters and
16+
* filter function passed to them by control message, as well as having
17+
* their Bypass/Filter operation mode toggled via control message.
18+
*/
19+
export class Filter extends Pipe {
20+
/**
21+
* Constructor.
22+
*
23+
* Optionally connect the output and set the parameters.
24+
*/
25+
constructor({
26+
name,
27+
output,
28+
filter,
29+
params,
30+
}: {
31+
name: string;
32+
output: IPipeFitting;
33+
filter: FilterControlFunction;
34+
params?: object | undefined;
35+
}) {
36+
super(output);
37+
this.name = name;
38+
this.filter = filter;
39+
this.params = params;
40+
}
41+
42+
/**
43+
* Handle the incoming message.
44+
*
45+
* If message type is normal, filter the message (unless in bypass mode)
46+
* and write the result to the output pipe fitting if the filter
47+
* operation is successful.
48+
*
49+
* The `FilterControlMessage.SET_PARAMS` message type tells the `Filter`
50+
* that the message class is FilterControlMessage, which it
51+
* casts the message to in order to retrieve the filter parameters
52+
* object if the message is addressed to this filter.
53+
*
54+
*
55+
* The `FilterControlMessage.SET_FILTER` message type tells the `Filter`
56+
* that the message class is FilterControlMessage, which it
57+
* casts the message to in order to retrieve the filter function.
58+
*
59+
*
60+
* The `FilterControlMessageType.BYPASS` message type tells the `Filter`
61+
* that it should go into Bypass mode operation, passing all normal
62+
* messages through unfiltered.
63+
*
64+
*
65+
* The `FilterControlMessage.FILTER` message type tells the `Filter`
66+
* that it should go into Filtering mode operation, filtering all
67+
* normal messages before writing out. This is the default
68+
* mode of operation and so this message type need only be sent to
69+
* cancel a previous BYPASS message.
70+
*
71+
*
72+
* The Filter only acts on the control message if it is targeted
73+
* to this named filter instance. Otherwise, it writes through to the
74+
* output.
75+
*
76+
* @return boolean True if the filter process does not throw an error and subsequent operations in the pipeline succeed.
77+
*/
78+
public override write(message: PipeMessage): boolean {
79+
let outputMessage: PipeMessage;
80+
let success: boolean = true;
81+
82+
// Filter normal messages
83+
switch (message.type) {
84+
case PipeMessageType.NORMAL:
85+
try {
86+
if (this.mode === FilterControlMessageType.FILTER) {
87+
outputMessage = this.applyFilter(message);
88+
} else {
89+
outputMessage = message;
90+
}
91+
success = this.output?.write(outputMessage) || false;
92+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
93+
} catch (e: unknown) {
94+
success = false;
95+
}
96+
break;
97+
98+
// Accept parameters from control message
99+
case FilterControlMessageType.SET_PARAMS:
100+
if (this.isTarget(message)) {
101+
this.params = (message as FilterControlMessage).params;
102+
} else {
103+
success = this.output?.write(message) || false;
104+
}
105+
break;
106+
107+
// Accept filter function from control message
108+
case FilterControlMessageType.SET_FILTER:
109+
if (this.isTarget(message)) {
110+
this.filter = (message as FilterControlMessage).filter;
111+
} else {
112+
success = this.output?.write(message) || false;
113+
}
114+
break;
115+
116+
// Toggle between Filter or Bypass operational modes
117+
case FilterControlMessageType.BYPASS:
118+
case FilterControlMessageType.FILTER:
119+
if (this.isTarget(message)) {
120+
this.mode = (message as FilterControlMessage).type;
121+
} else {
122+
success = this.output?.write(message) || false;
123+
}
124+
break;
125+
126+
// Write control messages for other fittings through
127+
default:
128+
success = this.output?.write(message) || false;
129+
}
130+
return success;
131+
}
132+
133+
/**
134+
* Is the message directed at this filter instance?
135+
*/
136+
protected isTarget(message: PipeMessage): boolean {
137+
return (message as FilterControlMessage).name === this.name;
138+
}
139+
140+
/**
141+
* Filter the message.
142+
*/
143+
protected applyFilter(message: PipeMessage): PipeMessage {
144+
this.filter(message, this.params);
145+
return message;
146+
}
147+
148+
protected mode: string = FilterControlMessageType.FILTER;
149+
protected filter: (
150+
message: PipeMessage,
151+
params: object | undefined,
152+
) => boolean;
153+
protected params: object | undefined = undefined;
154+
protected name: string;
155+
}

0 commit comments

Comments
 (0)