137 lines
3.4 KiB
Java
137 lines
3.4 KiB
Java
record Message(String type, String value) {}
|
|
|
|
Map<String, BlockingQueue<Message>> mailboxes =
|
|
new ConcurrentHashMap<>();
|
|
|
|
BlockingQueue<Message> mailbox(String name) {
|
|
return mailboxes.computeIfAbsent(
|
|
name,
|
|
_ -> new LinkedBlockingQueue<>()
|
|
);
|
|
}
|
|
|
|
void listen(String mailboxName, Consumer<Message> receiver) {
|
|
try {
|
|
while (true)
|
|
receiver.accept(mailbox(mailboxName).take());
|
|
} catch (InterruptedException _) {
|
|
Thread.currentThread().interrupt();
|
|
}
|
|
}
|
|
|
|
String rot13(String text) {
|
|
var result = new StringBuilder();
|
|
|
|
for (var character : text.toCharArray()) {
|
|
if (character >= 'a' && character <= 'z')
|
|
character = (char) ('a' + (character - 'a' + 13) % 26);
|
|
else if (character >= 'A' && character <= 'Z')
|
|
character = (char) ('A' + (character - 'A' + 13) % 26);
|
|
|
|
result.append(character);
|
|
}
|
|
|
|
return result.toString();
|
|
}
|
|
|
|
void runConsoleIn() {
|
|
try {
|
|
while (true) {
|
|
var text = IO.readln();
|
|
|
|
if (text == null)
|
|
return;
|
|
|
|
mailbox("consoleIn.outbox")
|
|
.put(new Message("TEXT", text));
|
|
}
|
|
} catch (InterruptedException _) {
|
|
Thread.currentThread().interrupt();
|
|
}
|
|
}
|
|
|
|
Map<String, Thread> rot13Subscriptions = new HashMap<>();
|
|
Map<String, Thread> consoleOutSubscriptions = new HashMap<>();
|
|
|
|
void subscribe(
|
|
Map<String, Thread> subscriptions,
|
|
String mailboxName,
|
|
Consumer<Message> receiver) {
|
|
subscriptions.computeIfAbsent(
|
|
mailboxName,
|
|
name -> Thread.ofVirtual().start(() -> listen(name, receiver))
|
|
);
|
|
}
|
|
|
|
void processWithRot13(Message message) {
|
|
if (!message.type().equals("TEXT"))
|
|
return;
|
|
|
|
try {
|
|
mailbox("rot13.outbox").put(
|
|
new Message("TEXT", rot13(message.value()))
|
|
);
|
|
} catch (InterruptedException _) {
|
|
Thread.currentThread().interrupt();
|
|
}
|
|
}
|
|
|
|
void runRot13() {
|
|
try {
|
|
while (true) {
|
|
var message = mailbox("rot13.inbox").take();
|
|
|
|
if (message.type().equals("TOPIC"))
|
|
subscribe(
|
|
rot13Subscriptions,
|
|
message.value(),
|
|
this::processWithRot13
|
|
);
|
|
else
|
|
processWithRot13(message);
|
|
}
|
|
} catch (InterruptedException _) {
|
|
Thread.currentThread().interrupt();
|
|
}
|
|
}
|
|
|
|
void print(Message message) {
|
|
if (message.type().equals("TEXT"))
|
|
IO.println(message.value());
|
|
}
|
|
|
|
void runConsoleOut() {
|
|
try {
|
|
while (true) {
|
|
var message = mailbox("consoleOut.inbox").take();
|
|
|
|
if (message.type().equals("TOPIC"))
|
|
subscribe(
|
|
consoleOutSubscriptions,
|
|
message.value(),
|
|
this::print
|
|
);
|
|
else
|
|
print(message);
|
|
}
|
|
} catch (InterruptedException _) {
|
|
Thread.currentThread().interrupt();
|
|
}
|
|
}
|
|
|
|
void main() throws Exception {
|
|
Thread.ofVirtual().start(this::runConsoleIn);
|
|
Thread.ofVirtual().start(this::runRot13);
|
|
Thread.ofVirtual().start(this::runConsoleOut);
|
|
|
|
mailbox("rot13.inbox").put(
|
|
new Message("TOPIC", "consoleIn.outbox")
|
|
);
|
|
|
|
mailbox("consoleOut.inbox").put(
|
|
new Message("TOPIC", "rot13.outbox")
|
|
);
|
|
|
|
Thread.currentThread().join();
|
|
}
|