add resId to cache DoricResource on native
This commit is contained in:
parent
d746c5b4d4
commit
5b80e4e0e1
@ -29,6 +29,7 @@ import pub.doric.performance.DoricPerformanceProfile;
|
||||
import pub.doric.plugin.AnimatePlugin;
|
||||
import pub.doric.plugin.CoordinatorPlugin;
|
||||
import pub.doric.plugin.DoricJavaPlugin;
|
||||
import pub.doric.plugin.ImageDecoderPlugin;
|
||||
import pub.doric.plugin.KeyboardPlugin;
|
||||
import pub.doric.plugin.ModalPlugin;
|
||||
import pub.doric.plugin.NavBarPlugin;
|
||||
@ -114,6 +115,7 @@ public class DoricRegistry {
|
||||
this.registerNativePlugin(NotchPlugin.class);
|
||||
this.registerNativePlugin(KeyboardPlugin.class);
|
||||
this.registerNativePlugin(ResourceLoaderPlugin.class);
|
||||
this.registerNativePlugin(ImageDecoderPlugin.class);
|
||||
|
||||
this.registerViewNode(RootNode.class);
|
||||
this.registerViewNode(TextNode.class);
|
||||
|
@ -15,10 +15,12 @@
|
||||
*/
|
||||
package pub.doric.plugin;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.github.pengfeizhou.jscore.JSObject;
|
||||
import com.github.pengfeizhou.jscore.JavaValue;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import pub.doric.DoricContext;
|
||||
import pub.doric.async.AsyncResult;
|
||||
import pub.doric.extension.bridge.DoricMethod;
|
||||
@ -34,6 +36,7 @@ import pub.doric.utils.DoricLog;
|
||||
*/
|
||||
@DoricPlugin(name = "resourceLoader")
|
||||
public class ResourceLoaderPlugin extends DoricJavaPlugin {
|
||||
private Map<String, DoricResource> cachedResources = new HashMap<>();
|
||||
|
||||
public ResourceLoaderPlugin(DoricContext doricContext) {
|
||||
super(doricContext);
|
||||
@ -41,11 +44,16 @@ public class ResourceLoaderPlugin extends DoricJavaPlugin {
|
||||
|
||||
@DoricMethod
|
||||
public void load(JSObject resource, final DoricPromise promise) {
|
||||
final String resId = resource.getProperty("resId").asString().value();
|
||||
final String type = resource.getProperty("type").asString().value();
|
||||
final String identifier = resource.getProperty("identifier").asString().value();
|
||||
DoricResource doricResource = getDoricContext().getDriver().getRegistry().getResourceManager().load(getDoricContext(), type, identifier);
|
||||
DoricResource doricResource = getDoricContext().getDriver().getRegistry().getResourceManager().load(
|
||||
getDoricContext(),
|
||||
resId,
|
||||
type,
|
||||
identifier);
|
||||
if (doricResource != null) {
|
||||
doricResource.fetchRaw().setCallback(new AsyncResult.Callback<byte[]>() {
|
||||
doricResource.fetch().setCallback(new AsyncResult.Callback<byte[]>() {
|
||||
@Override
|
||||
public void onResult(byte[] rawData) {
|
||||
promise.resolve(new JavaValue(rawData));
|
||||
|
@ -26,6 +26,7 @@ import pub.doric.async.AsyncResult;
|
||||
public abstract class DoricResource {
|
||||
protected final DoricContext doricContext;
|
||||
protected final String identifier;
|
||||
private AsyncResult<byte[]> rawResult;
|
||||
|
||||
public DoricResource(DoricContext doricContext, String identifier) {
|
||||
this.doricContext = doricContext;
|
||||
@ -33,4 +34,11 @@ public abstract class DoricResource {
|
||||
}
|
||||
|
||||
public abstract AsyncResult<byte[]> fetchRaw();
|
||||
|
||||
public AsyncResult<byte[]> fetch() {
|
||||
if (rawResult == null) {
|
||||
rawResult = fetchRaw();
|
||||
}
|
||||
return rawResult;
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ package pub.doric.resource;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
@ -29,6 +30,7 @@ import pub.doric.DoricContext;
|
||||
*/
|
||||
public class DoricResourceManager {
|
||||
private final Map<String, DoricResourceLoader> mResourceLoaders = new HashMap<>();
|
||||
private final Map<String, DoricResource> cachedResources = new WeakHashMap<>();
|
||||
|
||||
public void registerLoader(DoricResourceLoader loader) {
|
||||
mResourceLoaders.put(loader.resourceType(), loader);
|
||||
@ -39,11 +41,18 @@ public class DoricResourceManager {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public DoricResource load(@NonNull DoricContext doricContext, @NonNull String type, @NonNull String identifier) {
|
||||
DoricResourceLoader loader = mResourceLoaders.get(type);
|
||||
if (loader != null) {
|
||||
return loader.load(doricContext, identifier);
|
||||
public DoricResource load(@NonNull DoricContext doricContext,
|
||||
@NonNull String resId,
|
||||
@NonNull String type,
|
||||
@NonNull String identifier) {
|
||||
DoricResource resource = cachedResources.get(resId);
|
||||
if (resource == null) {
|
||||
DoricResourceLoader loader = mResourceLoaders.get(type);
|
||||
if (loader != null) {
|
||||
resource = loader.load(doricContext, identifier);
|
||||
cachedResources.put(resId, resource);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return resource;
|
||||
}
|
||||
}
|
||||
|
@ -397,11 +397,13 @@ public class ImageNode extends ViewNode<ImageView> {
|
||||
return;
|
||||
}
|
||||
JSObject resource = prop.asObject();
|
||||
final String resourceId = resource.getProperty("resId").asString().value();
|
||||
final String type = resource.getProperty("type").asString().value();
|
||||
final String identifier = resource.getProperty("identifier").asString().value();
|
||||
DoricResource doricResource = getDoricContext().getDriver().getRegistry().getResourceManager().load(getDoricContext(), type, identifier);
|
||||
DoricResource doricResource = getDoricContext().getDriver().getRegistry().getResourceManager()
|
||||
.load(getDoricContext(), resourceId, type, identifier);
|
||||
if (doricResource != null) {
|
||||
doricResource.fetchRaw().setCallback(new AsyncResult.Callback<byte[]>() {
|
||||
doricResource.fetch().setCallback(new AsyncResult.Callback<byte[]>() {
|
||||
@Override
|
||||
public void onResult(byte[] imageData) {
|
||||
loadIntoTarget(Glide.with(getContext()).load(imageData));
|
||||
|
@ -2145,11 +2145,13 @@ var __extends$f = (undefined && undefined.__extends) || (function () {
|
||||
})();
|
||||
var Resource = /** @class */ (function () {
|
||||
function Resource(type, identifier) {
|
||||
this.resId = uniqueId("resource");
|
||||
this.type = type;
|
||||
this.identifier = identifier;
|
||||
}
|
||||
Resource.prototype.toModel = function () {
|
||||
return {
|
||||
resId: this.resId,
|
||||
type: this.type,
|
||||
identifier: this.identifier,
|
||||
};
|
||||
|
@ -1610,11 +1610,13 @@ function text(config) {
|
||||
|
||||
class Resource {
|
||||
constructor(type, identifier) {
|
||||
this.resId = uniqueId("resource");
|
||||
this.type = type;
|
||||
this.identifier = identifier;
|
||||
}
|
||||
toModel() {
|
||||
return {
|
||||
resId: this.resId,
|
||||
type: this.type,
|
||||
identifier: this.identifier,
|
||||
};
|
||||
|
@ -3138,11 +3138,13 @@ function text(config) {
|
||||
|
||||
class Resource {
|
||||
constructor(type, identifier) {
|
||||
this.resId = uniqueId("resource");
|
||||
this.type = type;
|
||||
this.identifier = identifier;
|
||||
}
|
||||
toModel() {
|
||||
return {
|
||||
resId: this.resId,
|
||||
type: this.type,
|
||||
identifier: this.identifier,
|
||||
};
|
||||
|
2
doric-js/index.d.ts
vendored
2
doric-js/index.d.ts
vendored
@ -1688,8 +1688,10 @@ declare module 'doric/lib/src/util/resource' {
|
||||
export abstract class Resource implements Modeling {
|
||||
type: string;
|
||||
identifier: string;
|
||||
resId: string;
|
||||
constructor(type: string, identifier: string);
|
||||
toModel(): {
|
||||
resId: string;
|
||||
type: string;
|
||||
identifier: string;
|
||||
};
|
||||
|
7
doric-js/lib/src/native/imageDecoder.d.ts
vendored
7
doric-js/lib/src/native/imageDecoder.d.ts
vendored
@ -1,6 +1,9 @@
|
||||
import { Resource } from "../util/resource";
|
||||
import { BridgeContext } from "../runtime/global";
|
||||
export declare function imageDecoder(context: BridgeContext): {
|
||||
getBitmapInfo: (resource: Resource) => Promise<ArrayBuffer>;
|
||||
decodeToPixels: (resource: Resource) => Promise<ArrayBuffer>;
|
||||
decode: (resource: Resource) => Promise<{
|
||||
width: number;
|
||||
height: number;
|
||||
format: string;
|
||||
}>;
|
||||
};
|
||||
|
@ -13,13 +13,23 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
export function imageDecoder(context) {
|
||||
return {
|
||||
getBitmapInfo: (resource) => {
|
||||
return context.callNative('imageDecoder', 'getBitmapInfo', resource);
|
||||
},
|
||||
decodeToPixels: (resource) => {
|
||||
return context.callNative('imageDecoder', 'decode', resource);
|
||||
},
|
||||
decode: (resource) => __awaiter(this, void 0, void 0, function* () {
|
||||
yield context.callNative('imageDecoder', 'loadResource', resource);
|
||||
const imageInfo = yield context.callNative('imageDecoder', 'getImageInfo', resource.resId);
|
||||
const pixels = yield context.callNative('imageDecoder', 'decodeToPixels', resource.resId);
|
||||
yield context.callNative('imageDecoder', 'releaseResource', resource.resId);
|
||||
return Object.assign(Object.assign({}, imageInfo), { pixels });
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
2
doric-js/lib/src/util/resource.d.ts
vendored
2
doric-js/lib/src/util/resource.d.ts
vendored
@ -2,8 +2,10 @@ import { Modeling } from "./types";
|
||||
export declare abstract class Resource implements Modeling {
|
||||
type: string;
|
||||
identifier: string;
|
||||
resId: string;
|
||||
constructor(type: string, identifier: string);
|
||||
toModel(): {
|
||||
resId: string;
|
||||
type: string;
|
||||
identifier: string;
|
||||
};
|
||||
|
@ -1,10 +1,13 @@
|
||||
import { uniqueId } from "./uniqueId";
|
||||
export class Resource {
|
||||
constructor(type, identifier) {
|
||||
this.resId = uniqueId("resource");
|
||||
this.type = type;
|
||||
this.identifier = identifier;
|
||||
}
|
||||
toModel() {
|
||||
return {
|
||||
resId: this.resId,
|
||||
type: this.type,
|
||||
identifier: this.identifier,
|
||||
};
|
||||
|
@ -19,11 +19,26 @@ import { BridgeContext } from "../runtime/global"
|
||||
|
||||
export function imageDecoder(context: BridgeContext) {
|
||||
return {
|
||||
getBitmapInfo: (resource: Resource) => {
|
||||
return context.callNative('imageDecoder', 'getBitmapInfo', resource) as Promise<ArrayBuffer>
|
||||
},
|
||||
decodeToPixels: (resource: Resource) => {
|
||||
return context.callNative('imageDecoder', 'decode', resource) as Promise<ArrayBuffer>
|
||||
decode: async (resource: Resource) => {
|
||||
await context.callNative('imageDecoder', 'loadResource', resource);
|
||||
const imageInfo = await context.callNative(
|
||||
'imageDecoder',
|
||||
'getImageInfo',
|
||||
resource.resId) as Promise<
|
||||
{
|
||||
width: number,
|
||||
height: number,
|
||||
format: string,
|
||||
}>;
|
||||
const pixels = await context.callNative(
|
||||
'imageDecoder',
|
||||
'decodeToPixels',
|
||||
resource.resId) as Promise<ArrayBuffer>;
|
||||
await context.callNative('imageDecoder', 'releaseResource', resource.resId);
|
||||
return {
|
||||
...imageInfo,
|
||||
pixels,
|
||||
};
|
||||
},
|
||||
}
|
||||
}
|
@ -1,14 +1,17 @@
|
||||
import { Modeling } from "./types";
|
||||
import { uniqueId } from "./uniqueId";
|
||||
|
||||
export abstract class Resource implements Modeling {
|
||||
type: string;
|
||||
identifier: string;
|
||||
resId = uniqueId("resource");
|
||||
constructor(type: string, identifier: string) {
|
||||
this.type = type;
|
||||
this.identifier = identifier;
|
||||
}
|
||||
toModel() {
|
||||
return {
|
||||
resId: this.resId,
|
||||
type: this.type,
|
||||
identifier: this.identifier,
|
||||
}
|
||||
|
2
doric-web/dist/index.js
vendored
2
doric-web/dist/index.js
vendored
@ -3212,11 +3212,13 @@ function text(config) {
|
||||
|
||||
class Resource {
|
||||
constructor(type, identifier) {
|
||||
this.resId = uniqueId("resource");
|
||||
this.type = type;
|
||||
this.identifier = identifier;
|
||||
}
|
||||
toModel() {
|
||||
return {
|
||||
resId: this.resId,
|
||||
type: this.type,
|
||||
identifier: this.identifier,
|
||||
};
|
||||
|
9
doric-web/dist/index.js.map
vendored
9
doric-web/dist/index.js.map
vendored
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user