cvmts/protocol: Make protocols stateless

Instead of creating an instance of a protocol per user and storing state there, we just have the protocol implementations take in all of the state they should need in processMessage(), and store them all globally (with some wrappers to make it easier to handle this). This makes things slightly cleaner (and probably also helps memory usage, since we now don't need to create protocol instances as soon as a user connects/swaps, and they don't need to be garbage collected since they are held in the manager.)
This commit is contained in:
modeco80
2025-06-15 15:03:13 -04:00
parent bce2a0172a
commit 4211941560
6 changed files with 317 additions and 247 deletions

View File

@@ -1,24 +1,23 @@
import { IProtocol } from "./Protocol";
import { User } from "../User";
import { IProtocol } from './Protocol';
import { User } from '../User';
// The protocol manager. Holds protocol factories, and provides the ability
// to create a protocol by name. Avoids direct dependency on a given list of protocols,
// and allows (relatively simple) expansion.
// The protocol manager.
// Holds protocols, and provides the ability to obtain them by name.
//
// Avoids direct dependency on a given list of protocols,
// and allows (relatively simple) expansion of the supported protocols.
export class ProtocolManager {
private protocols = new Map<String, () => IProtocol>();
private protocols = new Map<String, IProtocol>();
// Registers a protocol with the given name.
// Registers a protocol with the given name, creates it, and stores it for later use.
registerProtocol(name: string, protocolFactory: () => IProtocol) {
if (!this.protocols.has(name)) this.protocols.set(name, protocolFactory);
if (!this.protocols.has(name)) this.protocols.set(name, protocolFactory());
}
// Creates an instance of a given protocol for a user.
createProtocol(name: string, user: User): IProtocol {
if (!this.protocols.has(name)) throw new Error(`ProtocolManager does not have protocol \"${name}\"`);
let factory = this.protocols.get(name)!;
let proto = factory();
proto.init(user);
// Gets an instance of a protocol.
getProtocol(name: string): IProtocol {
let proto = this.protocols.get(name);
if (proto == undefined) throw new Error(`ProtocolManager does not have protocol \"${name}\"`);
return proto;
}
}