import {createModel, Signal, signal} from '@preact/signals-core'; import {createEntityCollection} from "../utils/entity"; import {Part} from "./part"; import {Region} from "./region"; import {RuleDef, RuleRegistry, RuleContext, RuleEngineHost, dispatchCommand as dispatchRuleCommand} from "./rule"; export type Context = { type: string; } export const GameContext = createModel((root: Context) => { const parts = createEntityCollection(); const regions = createEntityCollection(); const rules = signal(new Map()); const ruleContexts = signal[]>([]); const contexts = signal[]>([]); contexts.value = [signal(root)]; function pushContext(context: Context) { const ctxSignal = signal(context); contexts.value = [...contexts.value, ctxSignal]; return context; } function popContext() { if (contexts.value.length > 1) { contexts.value = contexts.value.slice(0, -1); } } function latestContext(type: T['type']): Signal | undefined { for(let i = contexts.value.length - 1; i >= 0; i--){ if(contexts.value[i].value.type === type){ return contexts.value[i] as Signal; } } return undefined; } function registerRule(name: string, rule: RuleDef) { const newRules = new Map(rules.value); newRules.set(name, rule); rules.value = newRules; } function unregisterRule(name: string) { const newRules = new Map(rules.value); newRules.delete(name); rules.value = newRules; } function addRuleContext(ctx: RuleContext) { ruleContexts.value = [...ruleContexts.value, ctx]; } function removeRuleContext(ctx: RuleContext) { ruleContexts.value = ruleContexts.value.filter(c => c !== ctx); } function dispatchCommand(this: GameContextInstance, input: string) { return dispatchRuleCommand({ rules: rules.value, ruleContexts: ruleContexts.value, addRuleContext, removeRuleContext, pushContext, popContext, latestContext, parts, regions, } as any, input); } return { parts, regions, rules, ruleContexts, contexts, pushContext, popContext, latestContext, registerRule, unregisterRule, dispatchCommand, } }) /** 创建游戏上下文实�?*/ export function createGameContext(root: Context = { type: 'game' }) { return new GameContext(root); } export type GameContextInstance = ReturnType;