import {_decorator,Button,Component,Label} from 'cc'; import type {PlatformGameSnapshot} from '../../framework/sdk/contracts/index.ts'; import type {TemplateRoomActions,TemplateRoomPresentation} from './template-game.ts'; const {ccclass,property}=_decorator; /** Template lobby-to-room handoff surface; concrete subgames replace this presentation. */ @ccclass('TemplateRoomView') export class TemplateRoomView extends Component implements TemplateRoomPresentation { @property(Label) roomLabel:Label|null=null; @property(Label) playersLabel:Label|null=null; @property(Button) prepareButton:Button|null=null; @property(Button) exitButton:Button|null=null; private actions:TemplateRoomActions|null=null; private bound=false; private pending:'prepare'|'exit'|null=null; private timer:ReturnType|null=null; private snapshot:PlatformGameSnapshot|null=null; private readonly prepare=()=>this.invoke('prepare'); private readonly exit=()=>this.invoke('exit'); render(snapshot:PlatformGameSnapshot,actions:TemplateRoomActions):void{ if(!this.roomLabel||!this.playersLabel||!this.prepareButton||!this.exitButton)throw Error('TemplateRoomView missing controls'); this.actions=actions;this.snapshot=snapshot; if(!this.bound){this.prepareButton.node.on(Button.EventType.CLICK,this.prepare);this.exitButton.node.on(Button.EventType.CLICK,this.exit);this.bound=true;} this.roomLabel.string=`房间号:${snapshot.room.roomcode}`; this.playersLabel.string=snapshot.seats.map(p=>`${p.seat+1} ${p.nickname}${p.playerId===snapshot.self.playerId?'(我)':''} ${!p.online?'离线':p.ready?'已准备':'未准备'}`).join('\n'); const self=snapshot.seats.find(p=>p.playerId===snapshot.self.playerId); if(self?.ready||snapshot.connection.phase!=='logged-in')this.clearPending(); this.prepareButton.interactable=this.pending===null&&snapshot.connection.phase==='logged-in'&&snapshot.room.stage===0&&!self?.ready; this.exitButton.interactable=this.pending===null&&snapshot.connection.phase==='logged-in'; } private invoke(kind:'prepare'|'exit'):void{ if(!this.actions||this.pending)return; try{this.actions[kind]();this.pending=kind;this.prepareButton!.interactable=false;this.exitButton!.interactable=false; this.timer=setTimeout(()=>{this.clearPending();if(this.snapshot&&this.actions)this.render(this.snapshot,this.actions);this.node.emit('room-action-timeout');},15000); }catch(error){this.node.emit('room-action-error',error);} } private clearPending():void{if(this.timer!==null)clearTimeout(this.timer);this.timer=null;this.pending=null;} close():void{this.clearPending();if(this.bound){this.prepareButton?.node.off(Button.EventType.CLICK,this.prepare);this.exitButton?.node.off(Button.EventType.CLICK,this.exit);}this.bound=false;this.actions=null;} onDestroy():void{this.close();} }