diff --git a/src/core/job/init/InitScriptAPIJob.re b/src/core/job/init/InitScriptAPIJob.re index 6321e04c4..8ece2c3c9 100644 --- a/src/core/job/init/InitScriptAPIJob.re +++ b/src/core/job/init/InitScriptAPIJob.re @@ -1,3 +1,188 @@ +module AssetBundle = { + open Js.Promise; + + module Path = { + let getAssetBundlePath = (.) => ""; + }; + + module Load = { + let _buildFakeFetchArrayBufferResponse = + arrayBuffer: Js.Promise.t(Fetch.Response.t) => + { + "ok": true, + "status": "", + "statusText": "_buildFakeFetchArrayBufferResponse error", + "arrayBuffer": () => arrayBuffer |> resolve, + } + |> resolve + |> Obj.magic; + + let rec _findAssetBundbleNodeData = + (nodeNameHierachy, folderNode, editorState) + : NodeAssetType.assetBundleNodeData => { + WonderLog.Contract.requireCheck( + () => + WonderLog.( + Contract.( + Operators.( + test( + Log.buildAssertMessage( + ~expect={j|nodeNameHierachy.length > 0|j}, + ~actual={j|not|j}, + ), + () => + nodeNameHierachy |> Js.Array.length > 0 + ) + ) + ) + ), + StateEditorService.getStateIsDebug(), + ); + + nodeNameHierachy |> Js.Array.length > 1 ? + { + let nextFolderNodeName = + ArrayService.unsafeGetFirst(nodeNameHierachy); + + let nextFolderNode = + FolderNodeAssetService.getChildrenNodes(folderNode) + |> Js.Array.find(childNode => + FolderNodeAssetService.isFolderNode(childNode) + && FolderNodeAssetService.getNodeName( + FolderNodeAssetService.getNodeData(childNode), + ) + === nextFolderNodeName + ) + |> OptionService.unsafeGet; + + _findAssetBundbleNodeData( + nodeNameHierachy |> Js.Array.sliceFrom(1), + nextFolderNode, + editorState, + ); + } : + { + let assetBundleNodeName = + ArrayService.unsafeGetFirst(nodeNameHierachy) + |> FileNameService.getBaseName; + + FolderNodeAssetService.getChildrenNodes(folderNode) + |> Js.Array.find(childNode => + AssetBundleNodeAssetService.isAssetBundleNode(childNode) + && AssetBundleNodeAssetService.getNodeName( + AssetBundleNodeAssetService.getNodeData(childNode), + ) + === assetBundleNodeName + ) + |> OptionService.unsafeGet + |> AssetBundleNodeAssetService.getNodeData; + }; + }; + + let _buildFakeFetchAssetBundle = + (. abRelativePath) => { + let editorState = StateEditorService.getState(); + + let nodeNameHierachy = abRelativePath |> Js.String.split("/"); + + _findAssetBundbleNodeData( + nodeNameHierachy, + RootTreeAssetEditorService.getRootNode(editorState), + editorState, + ). + assetBundle + |> _buildFakeFetchArrayBufferResponse; + }; + + let loadSABAndSetToState = + ( + sabRelativePath, + wholeManifest, + ( + getAssetBundlePathFunc, + initAssetBundleArrayBufferCacheFunc, + isAssetBundleArrayBufferCachedFunc, + getAssetBundleArrayBufferCacheFunc, + cacheAssetBundleArrayBufferFunc, + ), + ) => + Wonderjs.ImportABSystem.SAB.loadSABAndSetToState( + sabRelativePath, + wholeManifest, + ( + getAssetBundlePathFunc, + initAssetBundleArrayBufferCacheFunc, + isAssetBundleArrayBufferCachedFunc, + getAssetBundleArrayBufferCacheFunc, + cacheAssetBundleArrayBufferFunc, + _buildFakeFetchAssetBundle, + ), + ); + + let loadAllDependencyRABAndSetToState = + (. + abRelativePath, + wholeManifest, + ( + getAssetBundlePathFunc, + initAssetBundleArrayBufferCacheFunc, + isAssetBundleArrayBufferCachedFunc, + getAssetBundleArrayBufferCacheFunc, + cacheAssetBundleArrayBufferFunc, + ), + ) => + Wonderjs.ImportABSystem.RAB.loadAllDependencyRABAndSetToState( + abRelativePath, + wholeManifest, + ( + getAssetBundlePathFunc, + initAssetBundleArrayBufferCacheFunc, + isAssetBundleArrayBufferCachedFunc, + getAssetBundleArrayBufferCacheFunc, + cacheAssetBundleArrayBufferFunc, + _buildFakeFetchAssetBundle, + ), + ); + + let loadWABAndSetToState = + (. wabRelativePath, getAssetBundlePathFunc) => + Wonderjs.ImportABSystem.WAB.loadWABAndSetToState( + wabRelativePath, + (getAssetBundlePathFunc, _buildFakeFetchAssetBundle), + ); + + let loadAssetBundle = + (. abPath) => + Wonderjs.LoadABSystem.load(abPath, _buildFakeFetchAssetBundle); + }; + module Cache = { + open WonderBsMost; + + open Js.Typed_array; + + let initAssetBundleArrayBufferCache = (.) => Most.empty(); + + let isAssetBundleArrayBufferCached = + (. abRelativePath: string, hashId: string) => Most.just(false); + + let getAssetBundleArrayBufferCache = + (. abRelativePath: string) => + WonderLog.Log.fatal( + WonderLog.Log.buildFatalMessage( + ~title="getAssetBundleArrayBufferCache", + ~description={j|need rewrite|j}, + ~reason="", + ~solution={j||j}, + ~params={j||j}, + ), + ); + + let cacheAssetBundleArrayBuffer = + (. abRelativePath: string, ab: ArrayBuffer.t, hashId: string) => + Most.empty(); + }; +}; + let _buildDisposeGameObjectFunc = scriptAPIJsObj => (. gameObject, engineState) => { let disposeGameObject = scriptAPIJsObj##disposeGameObject; @@ -21,20 +206,36 @@ let _buildDisposeGameObjectFunc = scriptAPIJsObj => StateEngineService.unsafeGetState(); }; -let _createScriptAPIJsObj = scriptAPIJsObj => { - "unsafeGetScriptAttribute": scriptAPIJsObj##unsafeGetScriptAttribute, - "unsafeGetScriptAttributeFieldValue": - scriptAPIJsObj##unsafeGetScriptAttributeFieldValue, - "setScriptAttributeFieldValue": scriptAPIJsObj##setScriptAttributeFieldValue, - "unsafeGetScriptGameObject": scriptAPIJsObj##unsafeGetScriptGameObject, - "getTransformLocalPosition": scriptAPIJsObj##getTransformLocalPosition, - /* TODO should only set MainEditorTransform->local position values */ - "setTransformLocalPosition": scriptAPIJsObj##setTransformLocalPosition, - "unsafeGetGameObjectTransformComponent": - scriptAPIJsObj##unsafeGetGameObjectTransformComponent, - "disposeGameObject": _buildDisposeGameObjectFunc(scriptAPIJsObj), - "findGameObjectsByName": scriptAPIJsObj##findGameObjectsByName, -}; +let _extend = [%raw + (destination, source) => {| + for (let property in source) { + destination[property] = source[property]; + } + + return destination; + |} +]; + +let _rewriteScriptAPIJsObj = scriptAPIJsObj => + { + /* TODO improve: should only set MainEditorTransform->local position values + "setTransformLocalPosition": scriptAPIJsObj##setTransformLocalPosition, */ + "disposeGameObject": _buildDisposeGameObjectFunc(scriptAPIJsObj), + "getAssetBundlePath": AssetBundle.Path.getAssetBundlePath, + "loadSABAndSetToState": AssetBundle.Load.loadSABAndSetToState, + "loadAllDependencyRABAndSetToState": AssetBundle.Load.loadAllDependencyRABAndSetToState, + "loadWABAndSetToState": AssetBundle.Load.loadWABAndSetToState, + "loadAssetBundle": AssetBundle.Load.loadAssetBundle, + "initAssetBundleArrayBufferCache": AssetBundle.Cache.initAssetBundleArrayBufferCache, + "isAssetBundleArrayBufferCached": AssetBundle.Cache.isAssetBundleArrayBufferCached, + "getAssetBundleArrayBufferCache": AssetBundle.Cache.getAssetBundleArrayBufferCache, + "cacheAssetBundleArrayBuffer": AssetBundle.Cache.cacheAssetBundleArrayBuffer, + } + |> _extend( + scriptAPIJsObj + |> Obj.magic + |> WonderCommonlib.MutableHashMapService.copy, + ); let initJob = (_, ({apiRecord}: Wonderjs.StateDataMainType.state) as engineState) => { @@ -42,7 +243,6 @@ let initJob = apiRecord: { ...apiRecord, scriptAPIJsObj: - _createScriptAPIJsObj(apiRecord.scriptAPIJsObj |> Obj.magic) - |> Obj.magic, + _rewriteScriptAPIJsObj(apiRecord.scriptAPIJsObj |> Obj.magic), }, }; \ No newline at end of file diff --git a/test/integration/job/initScriptAPIJob_test.re b/test/integration/job/initScriptAPIJob_test.re index 5d3fe828f..306acb2e6 100644 --- a/test/integration/job/initScriptAPIJob_test.re +++ b/test/integration/job/initScriptAPIJob_test.re @@ -6,6 +6,10 @@ open Expect.Operators; open Sinon; +open Js.Promise; + +open WonderBsMost; + let _ = describe("init script api job", () => { let sandbox = getSandboxDefaultVal(); @@ -16,17 +20,22 @@ let _ = }); afterEach(() => restoreSandbox(refJsObjToSandbox(sandbox^))); - describe("test api", () => + describe("test api", () => { + describe("not rewrited api should exist", () => + test("test", () => + InitScriptJobTool.createRewritedScriptAPIJsObj()##setTransformLocalPosition + |> Js.Nullable.toOption + |> Js.Option.isSome + |> expect == true + ) + ); + describe("disposeGameObject", () => { describe("handle engine state", () => test("dispose gameObject", () => { let disposeGameObjectFunc = - InitScriptAPIJob._buildDisposeGameObjectFunc( - InitScriptJobTool.createScriptAPIJsObj(), - ); - + InitScriptJobTool.createRewritedScriptAPIJsObj()##disposeGameObject; let engineState = StateEngineService.unsafeGetState(); - let (engineState, gameObject, _) = GameObjectToolEngine.createGameObject(engineState); @@ -41,9 +50,7 @@ let _ = describe("handle editor state", () => test("clear current data", () => { let disposeGameObjectFunc = - InitScriptAPIJob._buildDisposeGameObjectFunc( - InitScriptJobTool.createScriptAPIJsObj(), - ); + InitScriptJobTool.createRewritedScriptAPIJsObj()##disposeGameObject; let engineState = StateEngineService.unsafeGetState(); let (engineState, gameObject, _) = GameObjectToolEngine.createGameObject(engineState); @@ -53,13 +60,164 @@ let _ = let engineState = StateEngineService.unsafeGetState(); let engineState = disposeGameObjectFunc(. gameObject, engineState); - engineState |> StateEngineService.setState |> ignore; + engineState |> StateEngineService.setState |> ignore; GameObjectTool.getCurrentSceneTreeNode() |> Js.Option.isNone |> expect == true; }) ); - }) - ); + }); + + describe("test asset bundle api", () => { + beforeEach(() => { + MainEditorSceneTool.prepareScene(sandbox); + MainEditorAssetTool.buildFakeFileReader(); + }); + + describe("getAssetBundlePath", () => + test("return empty str", () => { + let getAssetBundlePath = + InitScriptJobTool.createRewritedScriptAPIJsObj()##getAssetBundlePath; + + getAssetBundlePath(.) |> expect == ""; + }) + ); + + describe("test load api", () => { + let _isArrayBufferEqual = (a1, a2) => + Js.Typed_array.( + JudgeTool.isEqual( + a1 |> ArrayBuffer.byteLength, + a2 |> ArrayBuffer.byteLength, + ) + ); + + describe("loadAssetBundle", () => + describe("get asset bundle from asset tree->asset bundle node", () => { + let _judge = + ( + abRelativePath, + uploadedAssetBundleNodeId, + loadAssetBundleFunc, + ) => { + let loadedAssetBundle = ref(Obj.magic(-1)); + + loadAssetBundleFunc(. abRelativePath) + |> Most.forEach(assetBundle => + loadedAssetBundle := assetBundle + ) + |> then_(() => + _isArrayBufferEqual( + loadedAssetBundle^, + MainEditorAssetAssetBundleNodeTool.getAssetBundle( + uploadedAssetBundleNodeId, + ) + |> StateLogicService.getEditorState, + ) + |> expect == true + |> resolve + ); + }; + + testPromise("test load one asset bundle asset", () => + MainEditorAssetUploadTool.loadOneAssetBundle( + ~fileName="A.rab", + (), + ) + |> then_(uploadedAssetBundleNodeId => { + let loadAssetBundle = + InitScriptJobTool.createRewritedScriptAPIJsObj()##loadAssetBundle; + + _judge( + "A.rab", + uploadedAssetBundleNodeId, + loadAssetBundle, + ); + }) + ); + testPromise( + "test load one asset bundle asset in added folder", () => { + let addedFolderNodeId1 = MainEditorAssetIdTool.getNewAssetId(); + MainEditorAssetHeaderOperateNodeTool.addFolder(); + + MainEditorAssetTreeTool.Select.selectFolderNode( + ~nodeId=addedFolderNodeId1, + (), + ); + + MainEditorAssetUploadTool.loadOneAssetBundle( + ~fileName="A.rab", + (), + ) + |> then_(uploadedAssetBundleNodeId => { + let loadAssetBundle = + InitScriptJobTool.createRewritedScriptAPIJsObj()##loadAssetBundle; + let editorState = StateEditorService.getState(); + + _judge( + MainEditorAssetFolderNodeTool.getFolderName( + addedFolderNodeId1, + editorState, + ) + ++ "/" + ++ "A.rab", + uploadedAssetBundleNodeId, + loadAssetBundle, + ); + }); + }); + testPromise( + "test load one asset bundle asset in added-two-layer folder", + () => { + let addedFolderNodeId1 = MainEditorAssetIdTool.getNewAssetId(); + MainEditorAssetHeaderOperateNodeTool.addFolder(); + + let addedFolderNodeId2 = MainEditorAssetIdTool.getNewAssetId(); + MainEditorAssetHeaderOperateNodeTool.addFolder(); + + MainEditorAssetTreeTool.Select.selectFolderNode( + ~nodeId=addedFolderNodeId2, + (), + ); + + let addedFolderNodeId3 = MainEditorAssetIdTool.getNewAssetId(); + MainEditorAssetHeaderOperateNodeTool.addFolder(); + + MainEditorAssetTreeTool.Select.selectFolderNode( + ~nodeId=addedFolderNodeId3, + (), + ); + + MainEditorAssetUploadTool.loadOneAssetBundle( + ~fileName="A.rab", + (), + ) + |> then_(uploadedAssetBundleNodeId => { + let loadAssetBundle = + InitScriptJobTool.createRewritedScriptAPIJsObj()##loadAssetBundle; + let editorState = StateEditorService.getState(); + + _judge( + MainEditorAssetFolderNodeTool.getFolderName( + addedFolderNodeId2, + editorState, + ) + ++ "/" + ++ MainEditorAssetFolderNodeTool.getFolderName( + addedFolderNodeId3, + editorState, + ) + ++ "/" + ++ "A.rab", + uploadedAssetBundleNodeId, + loadAssetBundle, + ); + }); + }); + }) + ); + }); + }); + }); }); \ No newline at end of file diff --git a/test/integration/job/tool/EventTool.re b/test/integration/job/tool/EventTool.re index 0af768e9d..ad132f845 100755 --- a/test/integration/job/tool/EventTool.re +++ b/test/integration/job/tool/EventTool.re @@ -10,8 +10,6 @@ let _isHostMethod = [%raw let _extend = [%raw (destination, source) => {| - var property = ""; - var target = null; Object.defineProperty(destination, "target", { configurable: true, @@ -24,7 +22,7 @@ let _extend = [%raw } }) - for (property in source) { + for (let property in source) { destination[property] = source[property]; } return destination; diff --git a/test/integration/job/tool/InitScriptJobTool.re b/test/integration/job/tool/InitScriptJobTool.re index 9630552a9..23309e27e 100644 --- a/test/integration/job/tool/InitScriptJobTool.re +++ b/test/integration/job/tool/InitScriptJobTool.re @@ -1 +1,4 @@ -let createScriptAPIJsObj = () => Wonderjs.RecordScriptAPIMainService.create(); \ No newline at end of file +let createScriptAPIJsObj = () => Wonderjs.RecordScriptAPIMainService.create(); + +let createRewritedScriptAPIJsObj = () => + InitScriptAPIJob._rewriteScriptAPIJsObj(createScriptAPIJsObj()); \ No newline at end of file