| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- import {
- _decorator,
- BlockInputEvents,
- Button,
- Camera,
- Canvas,
- Component,
- director,
- Director,
- Label,
- Node,
- ProgressBar,
- } from 'cc';
- import { AppKernel } from '../../app/AppKernel';
- import { LaunchProgress, LaunchStateMachine } from './LaunchStateMachine';
- import { LaunchDialog } from './states/LaunchState';
- const { ccclass, property } = _decorator;
- @ccclass('LaunchController')
- export class LaunchController extends Component {
- @property(Canvas)
- canvas: Canvas | null = null;
- @property(Label)
- progressLabel: Label | null = null;
- @property(ProgressBar)
- progressBar: ProgressBar | null = null;
- @property(Node)
- dialogNode: Node | null = null;
- @property(Label)
- dialogLabel: Label | null = null;
- @property(Button)
- dialogConfirmButton: Button | null = null;
- @property(Button)
- dialogCancelButton: Button | null = null;
- private launchStateMachine: LaunchStateMachine | null = null;
- private dialogResolve: ((confirmed: boolean) => void) | null = null;
- protected onLoad(): void {
- director.addPersistRootNode(this.node);
- AppKernel.initialize();
- this.initEvents();
- this.launchStateMachine = new LaunchStateMachine({
- kernel: AppKernel.Instance,
- error: null,
- progress: (value) => this.updateProgress(value),
- dialog: (message) => this.showDialog(message),
- });
- }
- private initEvents(): void {
- director.on(Director.EVENT_AFTER_SCENE_LAUNCH, this.onChangeScene, this,);
- AppKernel.events.once('launch:completed', this.onLaunchCompleted, this);
- }
- private onLaunchCompleted(): void {
- if (!this.node.isValid) return;
- this.node.active = false;
- if (director.isPersistRootNode(this.node)) {
- director.removePersistRootNode(this.node);
- }
- this.node.destroy();
- }
- protected async start(): Promise<void> {
- await this.launchStateMachine?.run();
- }
- protected onDestroy(): void {
- this.finishDialog(false);
- AppKernel.events.offTarget(this);
- director.off(Director.EVENT_AFTER_SCENE_LAUNCH, this.onChangeScene, this);
- }
- private readonly onChangeScene = (): void => {
- if (!this.node.isValid) return;
- const scene = director.getScene();
- const lobbyCanvas = scene?.getComponentsInChildren(Canvas)?.find(item => item != this.canvas);
- this.canvas.enabled = false;
- if (lobbyCanvas) {
- this.node.setParent(lobbyCanvas.node, true);
- this.node.setSiblingIndex(lobbyCanvas.node.children.length - 1);
- }
- };
- private updateProgress(value: LaunchProgress): void {
- if (value.title !== undefined && this.progressLabel) {
- this.progressLabel.string = value.title;
- }
- if (value.progress !== undefined && this.progressBar) {
- this.progressBar.progress = value.progress;
- }
- }
- private showDialog({ message }: LaunchDialog): Promise<boolean> {
- if (
- !this.dialogNode
- || !this.dialogLabel
- || !this.dialogConfirmButton
- || !this.dialogCancelButton
- ) {
- if (typeof globalThis.confirm === 'function') {
- return Promise.resolve(globalThis.confirm(message));
- }
- console.warn('[LaunchController] dialog nodes are not configured');
- return Promise.resolve(false);
- }
- this.finishDialog(false);
- this.dialogLabel.string = message;
- this.dialogNode.active = true;
- return new Promise<boolean>((resolve) => {
- this.dialogResolve = resolve;
- this.dialogConfirmButton?.node.once(
- Button.EventType.CLICK,
- this.onDialogConfirm,
- this,
- );
- this.dialogCancelButton?.node.once(
- Button.EventType.CLICK,
- this.onDialogCancel,
- this,
- );
- });
- }
- private readonly onDialogConfirm = (): void => {
- this.finishDialog(true);
- };
- private readonly onDialogCancel = (): void => {
- this.finishDialog(false);
- };
- private finishDialog(confirmed: boolean): void {
- this.dialogConfirmButton?.node.off(
- Button.EventType.CLICK,
- this.onDialogConfirm,
- this,
- );
- this.dialogCancelButton?.node.off(
- Button.EventType.CLICK,
- this.onDialogCancel,
- this,
- );
- if (this.dialogNode) this.dialogNode.active = false;
- const resolve = this.dialogResolve;
- this.dialogResolve = null;
- resolve?.(confirmed);
- }
- }
|