From 936bd602939810c6d95beafbdce49bbc80596f3a Mon Sep 17 00:00:00 2001 From: "pengfei.zhou" Date: Thu, 4 Mar 2021 14:35:34 +0800 Subject: [PATCH] feat:fix dirty props cannot be rendered in promise --- .../Devkit/Classes/DoricRemoteJSExecutor.m | 6 ++-- doric-js/bundle/doric-sandbox.es5.js | 4 +++ doric-js/bundle/doric-sandbox.js | 4 +++ doric-js/bundle/doric-vm.js | 35 +++++++++++++++++++ doric-js/index.debug.ts | 34 ++++++++++++++++++ doric-js/lib/index.debug.js | 32 +++++++++++++++++ doric-js/lib/src/runtime/sandbox.d.ts | 1 + doric-js/lib/src/runtime/sandbox.js | 3 ++ doric-js/src/runtime/sandbox.es5.ts | 3 ++ doric-js/src/runtime/sandbox.ts | 3 ++ 10 files changed, 123 insertions(+), 2 deletions(-) diff --git a/doric-iOS/Devkit/Classes/DoricRemoteJSExecutor.m b/doric-iOS/Devkit/Classes/DoricRemoteJSExecutor.m index cfe78e02..3b4d2e42 100644 --- a/doric-iOS/Devkit/Classes/DoricRemoteJSExecutor.m +++ b/doric-iOS/Devkit/Classes/DoricRemoteJSExecutor.m @@ -198,8 +198,10 @@ - (BOOL)interceptType:(NSString *)type command:(NSString *)cmd payload:(NSDictio } @finally { DoricLog(@"Unlock:%@", payload); dispatch_semaphore_t semaphore = self.semaphores[callId]; - [self.semaphores removeObjectForKey:callId]; - DC_UNLOCK(semaphore); + if (semaphore) { + [self.semaphores removeObjectForKey:callId]; + DC_UNLOCK(semaphore); + } } } } diff --git a/doric-js/bundle/doric-sandbox.es5.js b/doric-js/bundle/doric-sandbox.es5.js index 99341040..bbdbbd01 100644 --- a/doric-js/bundle/doric-sandbox.es5.js +++ b/doric-js/bundle/doric-sandbox.es5.js @@ -1324,6 +1324,9 @@ var doric = (function (exports) { }()); var gContexts = new Map; var gModules = new Map; + function allContexts() { + return gContexts.values(); + } function jsObtainContext(id) { if (gContexts.has(id)) { var context_1 = gContexts.get(id); @@ -13763,6 +13766,7 @@ var doric = (function (exports) { exports.Context = Context; exports.__moduleExports = coreJs; exports.__require__ = __require__; + exports.allContexts = allContexts; exports.jsCallEntityMethod = jsCallEntityMethod; exports.jsCallReject = jsCallReject; exports.jsCallResolve = jsCallResolve; diff --git a/doric-js/bundle/doric-sandbox.js b/doric-js/bundle/doric-sandbox.js index 1e7fcd85..c57fef85 100644 --- a/doric-js/bundle/doric-sandbox.js +++ b/doric-js/bundle/doric-sandbox.js @@ -1325,6 +1325,9 @@ var doric = (function (exports) { } const gContexts = new Map; const gModules = new Map; + function allContexts() { + return gContexts.values(); + } function jsObtainContext(id) { if (gContexts.has(id)) { const context = gContexts.get(id); @@ -1526,6 +1529,7 @@ var doric = (function (exports) { exports.Context = Context; exports.__require__ = __require__; + exports.allContexts = allContexts; exports.jsCallEntityMethod = jsCallEntityMethod; exports.jsCallReject = jsCallReject; exports.jsCallResolve = jsCallResolve; diff --git a/doric-js/bundle/doric-vm.js b/doric-js/bundle/doric-vm.js index 0ab17aae..8bbb41c0 100644 --- a/doric-js/bundle/doric-vm.js +++ b/doric-js/bundle/doric-vm.js @@ -1354,6 +1354,9 @@ class Context { } const gContexts = new Map; const gModules = new Map; +function allContexts() { + return gContexts.values(); +} function jsObtainContext(id) { if (gContexts.has(id)) { const context = gContexts.get(id); @@ -1558,6 +1561,7 @@ var doric = /*#__PURE__*/Object.freeze({ jsCallResolve: jsCallResolve, jsCallReject: jsCallReject, Context: Context, + allContexts: allContexts, jsObtainContext: jsObtainContext, jsReleaseContext: jsReleaseContext, __require__: __require__, @@ -4235,6 +4239,7 @@ var __awaiter = (undefined && undefined.__awaiter) || function (thisArg, _argume }; let contextId = undefined; let global$1 = new Function('return this')(); +const originSetTimeout = global$1.setTimeout; global$1.setTimeout = global$1.doricSetTimeout; global$1.setInterval = global$1.doricSetInterval; global$1.clearTimeout = global$1.doricClearTimeout; @@ -4287,10 +4292,16 @@ function initNativeEnvironment(source) { else if (type === 5) { arg = JSON.parse(value); } + if (payload.name === "Environment") { + arg.debugging = true; + } Reflect.set(global$1, payload.name, arg); break; case "injectGlobalJSFunction": console.log("injectGlobalJSFunction", payload); + if (payload.name === "nativeEmpty") { + break; + } Reflect.set(global$1, payload.name, function () { let args = [].slice.call(arguments); console.log(args); @@ -4433,6 +4444,30 @@ global$1.Envrionment = new Proxy({}, { return Reflect.set(target, p, v, receiver); } }); +global$1.nativeEmpty = () => { + originSetTimeout(() => { + for (let context of allContexts()) { + const entity = context.entity; + if (entity instanceof Panel) { + const panel = entity; + if (panel.getRootView().isDirty()) { + const model = panel.getRootView().toModel(); + context.callNative("shader", "render", model); + panel.getRootView().clean(); + } + for (let map of panel.allHeadViews()) { + for (let v of map.values()) { + if (v.isDirty()) { + const model = v.toModel(); + context.callNative("shader", "render", model); + v.clean(); + } + } + } + } + } + }, 0); +}; exports.AnimationSet = AnimationSet; exports.BOTTOM = BOTTOM; diff --git a/doric-js/index.debug.ts b/doric-js/index.debug.ts index 75705611..33bbe36a 100644 --- a/doric-js/index.debug.ts +++ b/doric-js/index.debug.ts @@ -16,6 +16,7 @@ import * as doric from './src/runtime/sandbox' import WebSocket from "ws" import path from 'path' +import { Panel } from './src/ui/panel'; type MSG = { type: "D2C" | "C2D" | "C2S" | "D2S" | "S2C" | "S2D", @@ -26,6 +27,7 @@ type MSG = { let contextId: string | undefined = undefined; let global = new Function('return this')() +const originSetTimeout = global.setTimeout global.setTimeout = global.doricSetTimeout global.setInterval = global.doricSetInterval global.clearTimeout = global.doricClearTimeout @@ -73,10 +75,16 @@ async function initNativeEnvironment(source: string) { } else if (type === 5) { arg = JSON.parse(value) } + if (payload.name === "Environment") { + (arg as any).debugging = true + } Reflect.set(global, payload.name as string, arg) break case "injectGlobalJSFunction": console.log("injectGlobalJSFunction", payload); + if (payload.name === "nativeEmpty") { + break + } Reflect.set(global, payload.name as string, function () { let args = [].slice.call(arguments) console.log(args) @@ -222,4 +230,30 @@ global.Envrionment = new Proxy({}, { } }) +global.nativeEmpty = () => { + originSetTimeout(() => { + for (let context of doric.allContexts()) { + const entity = context.entity + if (entity instanceof Panel) { + const panel = entity as Panel + if (panel.getRootView().isDirty()) { + const model = panel.getRootView().toModel() + context.callNative("shader", "render", model) + panel.getRootView().clean() + } + for (let map of panel.allHeadViews()) { + for (let v of map.values()) { + if (v.isDirty()) { + const model = v.toModel() + context.callNative("shader", "render", model) + v.clean() + } + } + } + } + } + + }, 0) +} + export * from './index' \ No newline at end of file diff --git a/doric-js/lib/index.debug.js b/doric-js/lib/index.debug.js index aed844c3..d054dd81 100644 --- a/doric-js/lib/index.debug.js +++ b/doric-js/lib/index.debug.js @@ -25,8 +25,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge import * as doric from './src/runtime/sandbox'; import WebSocket from "ws"; import path from 'path'; +import { Panel } from './src/ui/panel'; let contextId = undefined; let global = new Function('return this')(); +const originSetTimeout = global.setTimeout; global.setTimeout = global.doricSetTimeout; global.setInterval = global.doricSetInterval; global.clearTimeout = global.doricClearTimeout; @@ -79,10 +81,16 @@ function initNativeEnvironment(source) { else if (type === 5) { arg = JSON.parse(value); } + if (payload.name === "Environment") { + arg.debugging = true; + } Reflect.set(global, payload.name, arg); break; case "injectGlobalJSFunction": console.log("injectGlobalJSFunction", payload); + if (payload.name === "nativeEmpty") { + break; + } Reflect.set(global, payload.name, function () { let args = [].slice.call(arguments); console.log(args); @@ -225,4 +233,28 @@ global.Envrionment = new Proxy({}, { return Reflect.set(target, p, v, receiver); } }); +global.nativeEmpty = () => { + originSetTimeout(() => { + for (let context of doric.allContexts()) { + const entity = context.entity; + if (entity instanceof Panel) { + const panel = entity; + if (panel.getRootView().isDirty()) { + const model = panel.getRootView().toModel(); + context.callNative("shader", "render", model); + panel.getRootView().clean(); + } + for (let map of panel.allHeadViews()) { + for (let v of map.values()) { + if (v.isDirty()) { + const model = v.toModel(); + context.callNative("shader", "render", model); + v.clean(); + } + } + } + } + } + }, 0); +}; export * from './index'; diff --git a/doric-js/lib/src/runtime/sandbox.d.ts b/doric-js/lib/src/runtime/sandbox.d.ts index 694dae80..0f3005e4 100644 --- a/doric-js/lib/src/runtime/sandbox.d.ts +++ b/doric-js/lib/src/runtime/sandbox.d.ts @@ -17,6 +17,7 @@ export declare class Context { function2Id(func: Function): string; removeFuncById(funcId: string): void; } +export declare function allContexts(): IterableIterator; export declare function jsObtainContext(id: string): Context | undefined; export declare function jsReleaseContext(id: string): void; export declare function __require__(name: string): any; diff --git a/doric-js/lib/src/runtime/sandbox.js b/doric-js/lib/src/runtime/sandbox.js index b22c70dc..a409c728 100644 --- a/doric-js/lib/src/runtime/sandbox.js +++ b/doric-js/lib/src/runtime/sandbox.js @@ -143,6 +143,9 @@ export class Context { } const gContexts = new Map; const gModules = new Map; +export function allContexts() { + return gContexts.values(); +} export function jsObtainContext(id) { if (gContexts.has(id)) { const context = gContexts.get(id); diff --git a/doric-js/src/runtime/sandbox.es5.ts b/doric-js/src/runtime/sandbox.es5.ts index 35ba1347..5745807f 100644 --- a/doric-js/src/runtime/sandbox.es5.ts +++ b/doric-js/src/runtime/sandbox.es5.ts @@ -165,6 +165,9 @@ export class Context { const gContexts: Map = new Map const gModules: Map = new Map +export function allContexts() { + return gContexts.values() +} export function jsObtainContext(id: string) { if (gContexts.has(id)) { const context = gContexts.get(id) diff --git a/doric-js/src/runtime/sandbox.ts b/doric-js/src/runtime/sandbox.ts index 74e5b22b..d9ba45dc 100644 --- a/doric-js/src/runtime/sandbox.ts +++ b/doric-js/src/runtime/sandbox.ts @@ -203,6 +203,9 @@ export class Context { const gContexts: Map = new Map const gModules: Map = new Map +export function allContexts() { + return gContexts.values() +} export function jsObtainContext(id: string) { if (gContexts.has(id)) { const context = gContexts.get(id)