PresenterCCViewFactory.ts 3.26 KB
import { Presenter, setPresenterViewFactory, Subpresenter, setSubpresenterwFactory } from "../../common/classbase/PresenterBase";
import { ResUtils } from "simba-cc-resutils";
import { CCView, CCSubview } from "../../common/classbase/CCViewBase";
import { Subview } from "../../common/classbase/ViewBase";

const PresenterMap: { [key: string]: string } = {};
const ViewMap: { [key: string]: { cls: { new(): CCView }, prefab: string } } = {};

export function RegPresenter(viewType: string) {
    return function (target: { new(): Presenter<any, any>, uuid: string }) {
        PresenterMap[target.uuid] = viewType;
    }
}

export function RegView(viewType: string, prefabPath: string) {
    return function (target: { new(): CCView }) {
        ViewMap[viewType] = { cls: target, prefab: prefabPath };
    }
}

const ViewTypeSubviewMap: { [key: string]: { cls: { new(): CCSubview } } } = {};
const ViewTypeSubpresenterMap: { [key: string]: { cls: { new(): Subpresenter } } } = {};

export function RegSubpresenter(viewType: string) {
    return function (target: { new(): Subpresenter }) {
        ViewTypeSubpresenterMap[viewType] = { cls: target };
        Object.defineProperty(target, "_viewType", { configurable: false, enumerable: false, value: viewType, writable: false });
    }
}

export function RegSubview(viewType: string) {
    return function (target: { new(): CCSubview }) {
        ViewTypeSubviewMap[viewType] = { cls: target };
        Object.defineProperty(target, "_viewType", { configurable: false, enumerable: false, value: viewType, writable: false });
    }
}

let factory: any = async (presenterCls) => {
    let ret = ViewMap[PresenterMap[presenterCls.uuid]];
    if (ret) {
        let node = await ResUtils.createWithPrefab(ret.prefab);
        let comp = node.getComponent(ret.cls);
        if (!comp) {
            comp = node.addComponent(ret.cls);
        }
        return comp;
    }

    throw new Error("Create view failed. " + presenterCls.uuid);
};

factory.preloadView = async (presenterCls: { new(): Presenter, uuid: string }) => {
    let ret = ViewMap[PresenterMap[presenterCls.uuid]];
    if (ret) {
        await ResUtils.loadRes(ret.prefab, cc.Prefab);
    }
}

setPresenterViewFactory(factory);

// setSubviewFactory(async (p: Subpresenter) => {
//     if (p.view) throw new Error("Subpresenter already has view.");
//     const viewType = p.constructor["_viewType"];
//     if (!viewType) throw new Error("Subpresenter not registered.");
//     if (!ViewTypeSubviewMap[viewType]) throw new Error("Subview not registered. " + viewType);
//     const data = ViewTypeSubviewMap[viewType];
//     if (!data.prefab) throw new Error("Subview prefab not registered. " + viewType);
//     let node = await ResUtils.createWithPrefab(data.prefab);
//     let ret = node.getComponent(data.cls);
//     if (!ret) {
//         ret = node.addComponent(data.cls);
//     }
//     p.attachView(ret);
//     return ret;
// });

setSubpresenterwFactory((v: Subview) => {
    const viewType = v.constructor["_viewType"];
    if (!viewType) throw new Error("Subview not registered.");
    let data = ViewTypeSubpresenterMap[viewType];
    if (!data) throw new Error("Subpresenter not registered for view type. " + viewType);
    let presenter = new data.cls;
    presenter.attachView(v);
    return presenter;
});