-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathApplicationContext.ts
More file actions
77 lines (65 loc) · 2.5 KB
/
ApplicationContext.ts
File metadata and controls
77 lines (65 loc) · 2.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import type { Application } from '@/domain/Application/Application';
import { OperatingSystem } from '@/domain/OperatingSystem';
import type { CategoryCollection } from '@/domain/Collection/CategoryCollection';
import { EventSource } from '@/infrastructure/Events/EventSource';
import { assertInRange } from '@/application/Common/Enum';
import { CategoryCollectionState } from './State/CategoryCollectionState';
import type { IApplicationContext, IApplicationContextChangedEvent } from './IApplicationContext';
import type { ICategoryCollectionState } from './State/ICategoryCollectionState';
type StateMachine = Map<OperatingSystem, ICategoryCollectionState>;
export class ApplicationContext implements IApplicationContext {
public readonly contextChanged = new EventSource<IApplicationContextChangedEvent>();
public collection: CategoryCollection;
public get currentOs(): OperatingSystem {
return this.collection.os;
}
public get state(): ICategoryCollectionState {
return this.getState(this.collection.os);
}
private readonly states: StateMachine;
public constructor(
public readonly app: Application,
initialContext: OperatingSystem,
) {
this.collection = this.getCollection(initialContext);
this.states = initializeStates(app);
}
public changeContext(os: OperatingSystem): void {
if (this.currentOs === os) {
return;
}
const event: IApplicationContextChangedEvent = {
newState: this.getState(os),
oldState: this.getState(this.currentOs),
};
this.collection = this.getCollection(os);
this.contextChanged.notify(event);
}
private getCollection(os: OperatingSystem): CategoryCollection {
validateOperatingSystem(os, this.app);
return this.app.getCollection(os);
}
private getState(os: OperatingSystem): ICategoryCollectionState {
const state = this.states.get(os);
if (!state) {
throw new Error(`Operating system "${OperatingSystem[os]}" state is unknown.`);
}
return state;
}
}
function validateOperatingSystem(
os: OperatingSystem,
app: Application,
): void {
assertInRange(os, OperatingSystem);
if (!app.getSupportedOsList().includes(os)) {
throw new Error(`Operating system "${OperatingSystem[os]}" is not supported.`);
}
}
function initializeStates(app: Application): StateMachine {
const machine = new Map<OperatingSystem, ICategoryCollectionState>();
for (const collection of app.collections) {
machine.set(collection.os, new CategoryCollectionState(collection));
}
return machine;
}