Skip to content

feat: resource resource reference #195

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions examples/src/image.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Game, GameObject, RESOURCE_TYPE, resource } from "@eva/eva.js"
import { Img, ImgSystem } from "@eva/plugin-renderer-img";
export const name = 'image';
export async function init(canvas) {
window.resource = resource
resource.addResource([
{
name: 'imageName',
Expand Down Expand Up @@ -39,6 +40,7 @@ export async function init(canvas) {
y: 0,
},
});
window.image = image

image.addComponent(
new Img({
Expand Down
54 changes: 48 additions & 6 deletions packages/eva.js/lib/loader/Resource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,35 @@ type ResourceProcessFn = (resource: ResourceStruct) => any;
type PreProcessResourceHandler = (res: ResourceBase) => void;


class ResourceItem implements ResourceStruct {
name: string;
type: RESOURCE_TYPE;
src: {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里的定义,可能会导致类型提示都失效了

[propName: string]: SrcBase;
};
complete?: boolean;
preload?: boolean;
data?: {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里的定义,可能会导致类型提示都失效了

[propName: string]: any;
};
instance?: any;

private _rc: number = 0;

constructor(res) {
Object.assign(this, res)
this.data = {}
}

ref() {
this._rc++;
}
release() {
this._rc--;
}
}


/**
* Resource manager
* @public
Expand All @@ -107,7 +136,7 @@ class Resource extends EE {
private preProcessResourceHandlers: PreProcessResourceHandler[] = []

/** Resource cache */
public resourcesMap: Record<ResourceName, ResourceStruct> = {};
public resourcesMap: Record<ResourceName, ResourceItem> = {};

/** Collection of make resource instance function */
private makeInstanceFunctions: Record<string, ResourceProcessFn> = {};
Expand Down Expand Up @@ -136,7 +165,7 @@ class Resource extends EE {
}

/** Add single resource config and then preload */
public loadSingle(resource: ResourceBase): Promise<ResourceStruct> {
public loadSingle(resource: ResourceBase): Promise<ResourceBase> {
this.addResource([resource]);
return this.getResource(resource.name);
}
Expand All @@ -153,8 +182,7 @@ class Resource extends EE {
continue;
}

this.resourcesMap[res.name] = res;
this.resourcesMap[res.name].data = {};
this.resourcesMap[res.name] = new ResourceItem(res);
}
}

Expand Down Expand Up @@ -184,9 +212,19 @@ class Resource extends EE {
}

/** Get resource by name */
public async getResource(name: string): Promise<ResourceStruct> {
public async getResource(name: string): Promise<ResourceItem> {
this.loadResource({ names: [name] });
return this.promiseMap[name] || Promise.resolve({});
if (this.promiseMap[name]) {
this.resourcesMap[name]?.ref()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getResource方法能确保一定是在用到资源的时候被调用吗?

return this.promiseMap[name];
} else {
return Promise.resolve(new ResourceItem({}, this));
}
}

public getResourceItem(name: string): ResourceItem {
this.loadResource({ names: [name] });
return this.resourcesMap[name];
}

/** Make resource instance by resource type */
Expand All @@ -197,6 +235,10 @@ class Resource extends EE {

/** destory this resource manager */
async destroy(name: string) {
if (this.resourcesMap[name]._rc > 0) {
throw `Resource: ${name} , is in use and cannot be destroyed`;
}

await this._destroy(name);
}
private async _destroy(name, loadError = false) {
Expand Down
1 change: 1 addition & 0 deletions packages/plugin-renderer-img/lib/system.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export default class Img extends Renderer {
this.containerManager?.getContainer(changed.gameObject.id)?.removeChild(sprite.sprite);
sprite.sprite.destroy({ children: true });
delete this.imgs[changed.gameObject.id];
resource.getResourceItem((changed.component as ImgComponent).resource)?.release()
}
}
}
Expand Down