2022-10-30 07:08:37 +01:00
|
|
|
import { IRoomInstance, IRoomInstanceContainer, IRoomObject, IRoomObjectController, IRoomObjectManager, IRoomObjectModel, IRoomRendererBase } from '../api';
|
2022-10-30 05:02:19 +01:00
|
|
|
import { Disposable } from '../core';
|
2022-10-30 07:08:37 +01:00
|
|
|
import { RoomObjectModel } from './object';
|
2021-03-17 03:02:09 +01:00
|
|
|
|
|
|
|
export class RoomInstance extends Disposable implements IRoomInstance
|
|
|
|
{
|
|
|
|
private _id: string;
|
|
|
|
private _container: IRoomInstanceContainer;
|
|
|
|
private _renderer: IRoomRendererBase;
|
|
|
|
private _managers: Map<number, IRoomObjectManager>;
|
|
|
|
private _updateCategories: number[];
|
|
|
|
private _model: IRoomObjectModel;
|
|
|
|
|
|
|
|
constructor(id: string, container: IRoomInstanceContainer)
|
|
|
|
{
|
|
|
|
super();
|
|
|
|
|
2022-03-03 01:21:30 +01:00
|
|
|
this._id = id;
|
|
|
|
this._container = container;
|
|
|
|
this._renderer = null;
|
|
|
|
this._managers = new Map();
|
|
|
|
this._updateCategories = [];
|
|
|
|
this._model = new RoomObjectModel();
|
2021-03-17 03:02:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
protected onDispose(): void
|
|
|
|
{
|
|
|
|
this.removeAllManagers();
|
|
|
|
|
|
|
|
this.destroyRenderer();
|
|
|
|
|
|
|
|
this._container = null;
|
|
|
|
|
|
|
|
this._model.dispose();
|
|
|
|
}
|
|
|
|
|
|
|
|
public setRenderer(renderer: IRoomRendererBase): void
|
|
|
|
{
|
2022-11-02 23:44:30 +01:00
|
|
|
if(renderer === this._renderer) return;
|
2021-03-17 03:02:09 +01:00
|
|
|
|
2022-11-02 23:44:30 +01:00
|
|
|
if(this._renderer) this.destroyRenderer();
|
2021-03-17 03:02:09 +01:00
|
|
|
|
|
|
|
this._renderer = renderer;
|
|
|
|
|
2022-11-02 23:44:30 +01:00
|
|
|
if(!this._renderer) return;
|
2021-03-17 03:02:09 +01:00
|
|
|
|
|
|
|
this._renderer.reset();
|
|
|
|
|
2022-11-02 23:44:30 +01:00
|
|
|
if(this._managers.size)
|
2021-03-17 03:02:09 +01:00
|
|
|
{
|
2022-11-02 23:44:30 +01:00
|
|
|
for(const manager of this._managers.values())
|
2021-03-17 03:02:09 +01:00
|
|
|
{
|
2022-11-02 23:44:30 +01:00
|
|
|
if(!manager) continue;
|
2021-03-17 03:02:09 +01:00
|
|
|
|
|
|
|
const objects = manager.objects;
|
|
|
|
|
2022-11-02 23:44:30 +01:00
|
|
|
if(!objects.length) continue;
|
2021-03-17 03:02:09 +01:00
|
|
|
|
2022-11-02 23:44:30 +01:00
|
|
|
for(const object of objects.getValues())
|
2021-03-17 03:02:09 +01:00
|
|
|
{
|
2022-11-02 23:44:30 +01:00
|
|
|
if(!object) continue;
|
2021-03-17 03:02:09 +01:00
|
|
|
|
|
|
|
this._renderer.addObject(object);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private destroyRenderer(): void
|
|
|
|
{
|
2022-11-02 23:44:30 +01:00
|
|
|
if(!this._renderer) return;
|
2021-03-17 03:02:09 +01:00
|
|
|
|
|
|
|
this._renderer.dispose();
|
|
|
|
|
|
|
|
this._renderer = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getManager(category: number): IRoomObjectManager
|
|
|
|
{
|
|
|
|
const manager = this._managers.get(category);
|
|
|
|
|
2022-11-02 23:44:30 +01:00
|
|
|
if(!manager) return null;
|
2021-03-17 03:02:09 +01:00
|
|
|
|
|
|
|
return manager;
|
|
|
|
}
|
|
|
|
|
|
|
|
private getManagerOrCreate(category: number): IRoomObjectManager
|
|
|
|
{
|
|
|
|
let manager = this.getManager(category);
|
|
|
|
|
2022-11-02 23:44:30 +01:00
|
|
|
if(manager) return manager;
|
2021-03-17 03:02:09 +01:00
|
|
|
|
|
|
|
manager = this._container.createRoomObjectManager(category);
|
|
|
|
|
2022-11-02 23:44:30 +01:00
|
|
|
if(!manager) return null;
|
2021-03-17 03:02:09 +01:00
|
|
|
|
|
|
|
this._managers.set(category, manager);
|
|
|
|
|
|
|
|
return manager;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getTotalObjectsForManager(category: number): number
|
|
|
|
{
|
|
|
|
const manager = this.getManager(category);
|
|
|
|
|
2022-11-02 23:44:30 +01:00
|
|
|
if(!manager) return 0;
|
2021-03-17 03:02:09 +01:00
|
|
|
|
|
|
|
return manager.totalObjects;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getRoomObject(id: number, category: number): IRoomObject
|
|
|
|
{
|
|
|
|
const manager = this.getManager(category);
|
|
|
|
|
2022-11-02 23:44:30 +01:00
|
|
|
if(!manager) return null;
|
2021-03-17 03:02:09 +01:00
|
|
|
|
|
|
|
const object = manager.getObject(id);
|
|
|
|
|
2022-11-02 23:44:30 +01:00
|
|
|
if(!object) return null;
|
2021-03-17 03:02:09 +01:00
|
|
|
|
|
|
|
return object;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getRoomObjectsForCategory(category: number): IRoomObject[]
|
|
|
|
{
|
|
|
|
const manager = this.getManager(category);
|
|
|
|
|
|
|
|
return (manager ? manager.objects.getValues() : []);
|
|
|
|
}
|
|
|
|
|
|
|
|
public getRoomObjectByIndex(index: number, category: number): IRoomObject
|
|
|
|
{
|
|
|
|
const manager = this.getManager(category);
|
|
|
|
|
2022-11-02 23:44:30 +01:00
|
|
|
if(!manager) return null;
|
2021-03-17 03:02:09 +01:00
|
|
|
|
|
|
|
const object = manager.getObjectByIndex(index);
|
|
|
|
|
2022-11-02 23:44:30 +01:00
|
|
|
if(!object) return null;
|
2021-03-17 03:02:09 +01:00
|
|
|
|
|
|
|
return object;
|
|
|
|
}
|
|
|
|
|
|
|
|
public createRoomObject(id: number, stateCount: number, type: string, category: number): IRoomObjectController
|
|
|
|
{
|
|
|
|
const manager = this.getManagerOrCreate(category);
|
|
|
|
|
2022-11-02 23:44:30 +01:00
|
|
|
if(!manager) return null;
|
2021-03-17 03:02:09 +01:00
|
|
|
|
|
|
|
const object = manager.createObject(id, stateCount, type);
|
|
|
|
|
2022-11-02 23:44:30 +01:00
|
|
|
if(!object) return null;
|
2021-03-17 03:02:09 +01:00
|
|
|
|
2022-11-02 23:44:30 +01:00
|
|
|
if(this._renderer) this._renderer.addObject(object);
|
2021-03-17 03:02:09 +01:00
|
|
|
|
|
|
|
return object;
|
|
|
|
}
|
|
|
|
|
|
|
|
public createRoomObjectAndInitalize(objectId: number, type: string, category: number): IRoomObject
|
|
|
|
{
|
2022-11-02 23:44:30 +01:00
|
|
|
if(!this._container) return null;
|
2021-03-17 03:02:09 +01:00
|
|
|
|
|
|
|
return this._container.createRoomObjectAndInitalize(this._id, objectId, type, category);
|
|
|
|
}
|
|
|
|
|
|
|
|
public removeRoomObject(id: number, category: number): void
|
|
|
|
{
|
|
|
|
const manager = this.getManager(category);
|
|
|
|
|
2022-11-02 23:44:30 +01:00
|
|
|
if(!manager) return;
|
2021-03-17 03:02:09 +01:00
|
|
|
|
|
|
|
const object = manager.getObject(id);
|
|
|
|
|
2022-11-02 23:44:30 +01:00
|
|
|
if(!object) return;
|
2021-03-17 03:02:09 +01:00
|
|
|
|
|
|
|
object.tearDown();
|
|
|
|
|
2022-11-02 23:44:30 +01:00
|
|
|
if(this._renderer) this._renderer.removeObject(object);
|
2021-03-17 03:02:09 +01:00
|
|
|
|
|
|
|
manager.removeObject(id);
|
|
|
|
}
|
|
|
|
|
|
|
|
public removeAllManagers(): void
|
|
|
|
{
|
2022-11-02 23:44:30 +01:00
|
|
|
for(const manager of this._managers.values())
|
2021-03-17 03:02:09 +01:00
|
|
|
{
|
2022-11-02 23:44:30 +01:00
|
|
|
if(!manager) continue;
|
2021-03-17 03:02:09 +01:00
|
|
|
|
2022-11-02 23:44:30 +01:00
|
|
|
if(this._renderer)
|
2021-03-17 03:02:09 +01:00
|
|
|
{
|
|
|
|
const objects = manager.objects;
|
|
|
|
|
2022-11-02 23:44:30 +01:00
|
|
|
if(objects.length)
|
2021-03-17 03:02:09 +01:00
|
|
|
{
|
2022-11-02 23:44:30 +01:00
|
|
|
for(const object of objects.getValues())
|
2021-03-17 03:02:09 +01:00
|
|
|
{
|
2022-11-02 23:44:30 +01:00
|
|
|
if(!object) continue;
|
2021-03-17 03:02:09 +01:00
|
|
|
|
|
|
|
this._renderer.removeObject(object);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
manager.dispose();
|
|
|
|
}
|
|
|
|
|
|
|
|
this._managers.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
public addUpdateCategory(category: number): void
|
|
|
|
{
|
|
|
|
const index = this._updateCategories.indexOf(category);
|
|
|
|
|
2022-11-02 23:44:30 +01:00
|
|
|
if(index >= 0) return;
|
2021-03-17 03:02:09 +01:00
|
|
|
|
|
|
|
this._updateCategories.push(category);
|
|
|
|
}
|
|
|
|
|
|
|
|
public removeUpdateCategory(category: number): void
|
|
|
|
{
|
|
|
|
const index = this._updateCategories.indexOf(category);
|
|
|
|
|
2022-11-02 23:44:30 +01:00
|
|
|
if(index === -1) return;
|
2021-03-17 03:02:09 +01:00
|
|
|
|
|
|
|
this._updateCategories.splice(index, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
public update(time: number, update: boolean = false): void
|
|
|
|
{
|
2022-11-02 23:44:30 +01:00
|
|
|
for(const category of this._updateCategories)
|
2021-03-17 03:02:09 +01:00
|
|
|
{
|
|
|
|
const manager = this.getManager(category);
|
|
|
|
|
2022-11-02 23:44:30 +01:00
|
|
|
if(!manager) continue;
|
2021-03-17 03:02:09 +01:00
|
|
|
|
|
|
|
const objects = manager.objects;
|
|
|
|
|
2022-11-02 23:44:30 +01:00
|
|
|
if(!objects.length) continue;
|
2021-03-17 03:02:09 +01:00
|
|
|
|
2022-11-02 23:44:30 +01:00
|
|
|
for(const object of objects.getValues())
|
2021-03-17 03:02:09 +01:00
|
|
|
{
|
2022-11-02 23:44:30 +01:00
|
|
|
if(!object) continue;
|
2021-03-17 03:02:09 +01:00
|
|
|
|
|
|
|
const logic = object.logic;
|
|
|
|
|
|
|
|
(logic && logic.update(time));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this._renderer && this._renderer.update(time, update);
|
|
|
|
}
|
|
|
|
|
|
|
|
public hasUninitializedObjects(): boolean
|
|
|
|
{
|
2022-11-02 23:44:30 +01:00
|
|
|
for(const manager of this._managers.values())
|
2021-03-17 03:02:09 +01:00
|
|
|
{
|
2022-11-02 23:44:30 +01:00
|
|
|
if(!manager) continue;
|
2021-03-17 03:02:09 +01:00
|
|
|
|
2022-11-02 23:44:30 +01:00
|
|
|
for(const object of manager.objects.getValues())
|
2021-03-17 03:02:09 +01:00
|
|
|
{
|
2022-11-02 23:44:30 +01:00
|
|
|
if(!object) continue;
|
2021-03-17 03:02:09 +01:00
|
|
|
|
2022-11-02 23:44:30 +01:00
|
|
|
if(!object.isReady) return true;
|
2021-03-17 03:02:09 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public get id(): string
|
|
|
|
{
|
|
|
|
return this._id;
|
|
|
|
}
|
|
|
|
|
|
|
|
public get container(): IRoomInstanceContainer
|
|
|
|
{
|
|
|
|
return this._container;
|
|
|
|
}
|
|
|
|
|
|
|
|
public get renderer(): IRoomRendererBase
|
|
|
|
{
|
|
|
|
return this._renderer;
|
|
|
|
}
|
|
|
|
|
|
|
|
public get managers(): Map<number, IRoomObjectManager>
|
|
|
|
{
|
|
|
|
return this._managers;
|
|
|
|
}
|
|
|
|
|
|
|
|
public get model(): IRoomObjectModel
|
|
|
|
{
|
|
|
|
return this._model;
|
|
|
|
}
|
2022-10-30 03:59:33 +01:00
|
|
|
}
|