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.AnimatePlugin;
|
||||||
import pub.doric.plugin.CoordinatorPlugin;
|
import pub.doric.plugin.CoordinatorPlugin;
|
||||||
import pub.doric.plugin.DoricJavaPlugin;
|
import pub.doric.plugin.DoricJavaPlugin;
|
||||||
|
import pub.doric.plugin.ImageDecoderPlugin;
|
||||||
import pub.doric.plugin.KeyboardPlugin;
|
import pub.doric.plugin.KeyboardPlugin;
|
||||||
import pub.doric.plugin.ModalPlugin;
|
import pub.doric.plugin.ModalPlugin;
|
||||||
import pub.doric.plugin.NavBarPlugin;
|
import pub.doric.plugin.NavBarPlugin;
|
||||||
@ -114,6 +115,7 @@ public class DoricRegistry {
|
|||||||
this.registerNativePlugin(NotchPlugin.class);
|
this.registerNativePlugin(NotchPlugin.class);
|
||||||
this.registerNativePlugin(KeyboardPlugin.class);
|
this.registerNativePlugin(KeyboardPlugin.class);
|
||||||
this.registerNativePlugin(ResourceLoaderPlugin.class);
|
this.registerNativePlugin(ResourceLoaderPlugin.class);
|
||||||
|
this.registerNativePlugin(ImageDecoderPlugin.class);
|
||||||
|
|
||||||
this.registerViewNode(RootNode.class);
|
this.registerViewNode(RootNode.class);
|
||||||
this.registerViewNode(TextNode.class);
|
this.registerViewNode(TextNode.class);
|
||||||
|
@ -15,10 +15,12 @@
|
|||||||
*/
|
*/
|
||||||
package pub.doric.plugin;
|
package pub.doric.plugin;
|
||||||
|
|
||||||
import com.bumptech.glide.Glide;
|
|
||||||
import com.github.pengfeizhou.jscore.JSObject;
|
import com.github.pengfeizhou.jscore.JSObject;
|
||||||
import com.github.pengfeizhou.jscore.JavaValue;
|
import com.github.pengfeizhou.jscore.JavaValue;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import pub.doric.DoricContext;
|
import pub.doric.DoricContext;
|
||||||
import pub.doric.async.AsyncResult;
|
import pub.doric.async.AsyncResult;
|
||||||
import pub.doric.extension.bridge.DoricMethod;
|
import pub.doric.extension.bridge.DoricMethod;
|
||||||
@ -34,6 +36,7 @@ import pub.doric.utils.DoricLog;
|
|||||||
*/
|
*/
|
||||||
@DoricPlugin(name = "resourceLoader")
|
@DoricPlugin(name = "resourceLoader")
|
||||||
public class ResourceLoaderPlugin extends DoricJavaPlugin {
|
public class ResourceLoaderPlugin extends DoricJavaPlugin {
|
||||||
|
private Map<String, DoricResource> cachedResources = new HashMap<>();
|
||||||
|
|
||||||
public ResourceLoaderPlugin(DoricContext doricContext) {
|
public ResourceLoaderPlugin(DoricContext doricContext) {
|
||||||
super(doricContext);
|
super(doricContext);
|
||||||
@ -41,11 +44,16 @@ public class ResourceLoaderPlugin extends DoricJavaPlugin {
|
|||||||
|
|
||||||
@DoricMethod
|
@DoricMethod
|
||||||
public void load(JSObject resource, final DoricPromise promise) {
|
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 type = resource.getProperty("type").asString().value();
|
||||||
final String identifier = resource.getProperty("identifier").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) {
|
if (doricResource != null) {
|
||||||
doricResource.fetchRaw().setCallback(new AsyncResult.Callback<byte[]>() {
|
doricResource.fetch().setCallback(new AsyncResult.Callback<byte[]>() {
|
||||||
@Override
|
@Override
|
||||||
public void onResult(byte[] rawData) {
|
public void onResult(byte[] rawData) {
|
||||||
promise.resolve(new JavaValue(rawData));
|
promise.resolve(new JavaValue(rawData));
|
||||||
|
@ -26,6 +26,7 @@ import pub.doric.async.AsyncResult;
|
|||||||
public abstract class DoricResource {
|
public abstract class DoricResource {
|
||||||
protected final DoricContext doricContext;
|
protected final DoricContext doricContext;
|
||||||
protected final String identifier;
|
protected final String identifier;
|
||||||
|
private AsyncResult<byte[]> rawResult;
|
||||||
|
|
||||||
public DoricResource(DoricContext doricContext, String identifier) {
|
public DoricResource(DoricContext doricContext, String identifier) {
|
||||||
this.doricContext = doricContext;
|
this.doricContext = doricContext;
|
||||||
@ -33,4 +34,11 @@ public abstract class DoricResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public abstract AsyncResult<byte[]> fetchRaw();
|
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.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.WeakHashMap;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
@ -29,6 +30,7 @@ import pub.doric.DoricContext;
|
|||||||
*/
|
*/
|
||||||
public class DoricResourceManager {
|
public class DoricResourceManager {
|
||||||
private final Map<String, DoricResourceLoader> mResourceLoaders = new HashMap<>();
|
private final Map<String, DoricResourceLoader> mResourceLoaders = new HashMap<>();
|
||||||
|
private final Map<String, DoricResource> cachedResources = new WeakHashMap<>();
|
||||||
|
|
||||||
public void registerLoader(DoricResourceLoader loader) {
|
public void registerLoader(DoricResourceLoader loader) {
|
||||||
mResourceLoaders.put(loader.resourceType(), loader);
|
mResourceLoaders.put(loader.resourceType(), loader);
|
||||||
@ -39,11 +41,18 @@ public class DoricResourceManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public DoricResource load(@NonNull DoricContext doricContext, @NonNull String type, @NonNull String identifier) {
|
public DoricResource load(@NonNull DoricContext doricContext,
|
||||||
DoricResourceLoader loader = mResourceLoaders.get(type);
|
@NonNull String resId,
|
||||||
if (loader != null) {
|
@NonNull String type,
|
||||||
return loader.load(doricContext, identifier);
|
@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;
|
return;
|
||||||
}
|
}
|
||||||
JSObject resource = prop.asObject();
|
JSObject resource = prop.asObject();
|
||||||
|
final String resourceId = resource.getProperty("resId").asString().value();
|
||||||
final String type = resource.getProperty("type").asString().value();
|
final String type = resource.getProperty("type").asString().value();
|
||||||
final String identifier = resource.getProperty("identifier").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) {
|
if (doricResource != null) {
|
||||||
doricResource.fetchRaw().setCallback(new AsyncResult.Callback<byte[]>() {
|
doricResource.fetch().setCallback(new AsyncResult.Callback<byte[]>() {
|
||||||
@Override
|
@Override
|
||||||
public void onResult(byte[] imageData) {
|
public void onResult(byte[] imageData) {
|
||||||
loadIntoTarget(Glide.with(getContext()).load(imageData));
|
loadIntoTarget(Glide.with(getContext()).load(imageData));
|
||||||
|
@ -2145,11 +2145,13 @@ var __extends$f = (undefined && undefined.__extends) || (function () {
|
|||||||
})();
|
})();
|
||||||
var Resource = /** @class */ (function () {
|
var Resource = /** @class */ (function () {
|
||||||
function Resource(type, identifier) {
|
function Resource(type, identifier) {
|
||||||
|
this.resId = uniqueId("resource");
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.identifier = identifier;
|
this.identifier = identifier;
|
||||||
}
|
}
|
||||||
Resource.prototype.toModel = function () {
|
Resource.prototype.toModel = function () {
|
||||||
return {
|
return {
|
||||||
|
resId: this.resId,
|
||||||
type: this.type,
|
type: this.type,
|
||||||
identifier: this.identifier,
|
identifier: this.identifier,
|
||||||
};
|
};
|
||||||
|
@ -1610,11 +1610,13 @@ function text(config) {
|
|||||||
|
|
||||||
class Resource {
|
class Resource {
|
||||||
constructor(type, identifier) {
|
constructor(type, identifier) {
|
||||||
|
this.resId = uniqueId("resource");
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.identifier = identifier;
|
this.identifier = identifier;
|
||||||
}
|
}
|
||||||
toModel() {
|
toModel() {
|
||||||
return {
|
return {
|
||||||
|
resId: this.resId,
|
||||||
type: this.type,
|
type: this.type,
|
||||||
identifier: this.identifier,
|
identifier: this.identifier,
|
||||||
};
|
};
|
||||||
|
@ -3138,11 +3138,13 @@ function text(config) {
|
|||||||
|
|
||||||
class Resource {
|
class Resource {
|
||||||
constructor(type, identifier) {
|
constructor(type, identifier) {
|
||||||
|
this.resId = uniqueId("resource");
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.identifier = identifier;
|
this.identifier = identifier;
|
||||||
}
|
}
|
||||||
toModel() {
|
toModel() {
|
||||||
return {
|
return {
|
||||||
|
resId: this.resId,
|
||||||
type: this.type,
|
type: this.type,
|
||||||
identifier: this.identifier,
|
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 {
|
export abstract class Resource implements Modeling {
|
||||||
type: string;
|
type: string;
|
||||||
identifier: string;
|
identifier: string;
|
||||||
|
resId: string;
|
||||||
constructor(type: string, identifier: string);
|
constructor(type: string, identifier: string);
|
||||||
toModel(): {
|
toModel(): {
|
||||||
|
resId: string;
|
||||||
type: string;
|
type: string;
|
||||||
identifier: 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 { Resource } from "../util/resource";
|
||||||
import { BridgeContext } from "../runtime/global";
|
import { BridgeContext } from "../runtime/global";
|
||||||
export declare function imageDecoder(context: BridgeContext): {
|
export declare function imageDecoder(context: BridgeContext): {
|
||||||
getBitmapInfo: (resource: Resource) => Promise<ArrayBuffer>;
|
decode: (resource: Resource) => Promise<{
|
||||||
decodeToPixels: (resource: Resource) => Promise<ArrayBuffer>;
|
width: number;
|
||||||
|
height: number;
|
||||||
|
format: string;
|
||||||
|
}>;
|
||||||
};
|
};
|
||||||
|
@ -13,13 +13,23 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* 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) {
|
export function imageDecoder(context) {
|
||||||
return {
|
return {
|
||||||
getBitmapInfo: (resource) => {
|
decode: (resource) => __awaiter(this, void 0, void 0, function* () {
|
||||||
return context.callNative('imageDecoder', 'getBitmapInfo', resource);
|
yield context.callNative('imageDecoder', 'loadResource', resource);
|
||||||
},
|
const imageInfo = yield context.callNative('imageDecoder', 'getImageInfo', resource.resId);
|
||||||
decodeToPixels: (resource) => {
|
const pixels = yield context.callNative('imageDecoder', 'decodeToPixels', resource.resId);
|
||||||
return context.callNative('imageDecoder', 'decode', resource);
|
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 {
|
export declare abstract class Resource implements Modeling {
|
||||||
type: string;
|
type: string;
|
||||||
identifier: string;
|
identifier: string;
|
||||||
|
resId: string;
|
||||||
constructor(type: string, identifier: string);
|
constructor(type: string, identifier: string);
|
||||||
toModel(): {
|
toModel(): {
|
||||||
|
resId: string;
|
||||||
type: string;
|
type: string;
|
||||||
identifier: string;
|
identifier: string;
|
||||||
};
|
};
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
|
import { uniqueId } from "./uniqueId";
|
||||||
export class Resource {
|
export class Resource {
|
||||||
constructor(type, identifier) {
|
constructor(type, identifier) {
|
||||||
|
this.resId = uniqueId("resource");
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.identifier = identifier;
|
this.identifier = identifier;
|
||||||
}
|
}
|
||||||
toModel() {
|
toModel() {
|
||||||
return {
|
return {
|
||||||
|
resId: this.resId,
|
||||||
type: this.type,
|
type: this.type,
|
||||||
identifier: this.identifier,
|
identifier: this.identifier,
|
||||||
};
|
};
|
||||||
|
@ -19,11 +19,26 @@ import { BridgeContext } from "../runtime/global"
|
|||||||
|
|
||||||
export function imageDecoder(context: BridgeContext) {
|
export function imageDecoder(context: BridgeContext) {
|
||||||
return {
|
return {
|
||||||
getBitmapInfo: (resource: Resource) => {
|
decode: async (resource: Resource) => {
|
||||||
return context.callNative('imageDecoder', 'getBitmapInfo', resource) as Promise<ArrayBuffer>
|
await context.callNative('imageDecoder', 'loadResource', resource);
|
||||||
},
|
const imageInfo = await context.callNative(
|
||||||
decodeToPixels: (resource: Resource) => {
|
'imageDecoder',
|
||||||
return context.callNative('imageDecoder', 'decode', resource) as Promise<ArrayBuffer>
|
'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 { Modeling } from "./types";
|
||||||
|
import { uniqueId } from "./uniqueId";
|
||||||
|
|
||||||
export abstract class Resource implements Modeling {
|
export abstract class Resource implements Modeling {
|
||||||
type: string;
|
type: string;
|
||||||
identifier: string;
|
identifier: string;
|
||||||
|
resId = uniqueId("resource");
|
||||||
constructor(type: string, identifier: string) {
|
constructor(type: string, identifier: string) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.identifier = identifier;
|
this.identifier = identifier;
|
||||||
}
|
}
|
||||||
toModel() {
|
toModel() {
|
||||||
return {
|
return {
|
||||||
|
resId: this.resId,
|
||||||
type: this.type,
|
type: this.type,
|
||||||
identifier: this.identifier,
|
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 {
|
class Resource {
|
||||||
constructor(type, identifier) {
|
constructor(type, identifier) {
|
||||||
|
this.resId = uniqueId("resource");
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.identifier = identifier;
|
this.identifier = identifier;
|
||||||
}
|
}
|
||||||
toModel() {
|
toModel() {
|
||||||
return {
|
return {
|
||||||
|
resId: this.resId,
|
||||||
type: this.type,
|
type: this.type,
|
||||||
identifier: this.identifier,
|
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