Compare commits
	
		
			No commits in common. "f2877edf376354ab7bb9adc498b9abb59730724d" and "14f4607c47b4504efcd7bd5e82bb392f7ca4fa84" have entirely different histories.
		
	
	
		
			f2877edf37
			...
			14f4607c47
		
	
		
| @ -1,10 +0,0 @@ | |||||||
| { |  | ||||||
|     "entities" : [], |  | ||||||
|     "scriptPaths" : [], |  | ||||||
|     "initScriptPath" : "/Scenes/defaultLevel_2/scene.ts", |  | ||||||
|     "realmDescriptor" : { |  | ||||||
|         "type" : "gridded", |  | ||||||
|         "griddedRealmSize" : 2 |  | ||||||
|     }, |  | ||||||
|     "createSaveInstance" : true |  | ||||||
| } |  | ||||||
| @ -1,18 +0,0 @@ | |||||||
| import { TrackedScene } from "/Scripts/engine/scene/scene-loader"; |  | ||||||
| import { Scene } from "/Scripts/types/scene"; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * The main scene interface |  | ||||||
|  */ |  | ||||||
| const TestScene1: Scene = { |  | ||||||
|      |  | ||||||
|     onCreate: (instanceId: number) => { |  | ||||||
|         console.log('Hello from the scene! My ID is ' + instanceId) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * The scene to export |  | ||||||
|  */ |  | ||||||
| export default TestScene1 |  | ||||||
| @ -1,479 +1,119 @@ | |||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * @description The compiler object |  * The map of all source files to their content and compiled value | ||||||
|  */ |  */ | ||||||
| let COMPILER = { | let COMPILER_fileMap = { } | ||||||
| 
 | 
 | ||||||
|     //
 | /** | ||||||
|     //
 |  * The compiled program | ||||||
|     //    VIRTUAL FILE SYSTEM
 |  */ | ||||||
|     //
 | let COMPILER_emitted_value = '' | ||||||
|     //
 |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * The map of all source files to their content and compiled value |  | ||||||
|      */ |  | ||||||
|     fileMap: { }, |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * The list of all source files to compile |  | ||||||
|      */ |  | ||||||
|     sourceFiles: [ ], |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * The top level directory, "/" |  | ||||||
|      */ |  | ||||||
|     topLevelDirectory: { |  | ||||||
|         //as required by our framework
 |  | ||||||
|         Scripts: { |  | ||||||
|             compiler: { |  | ||||||
|                 "host_access.js": { |  | ||||||
|                     content: "", |  | ||||||
|                     version: 0, |  | ||||||
|                 }, |  | ||||||
|                 version: 0, |  | ||||||
|                 isDir: true, |  | ||||||
|             }, |  | ||||||
|             version: 0, |  | ||||||
|             isDir: true, |  | ||||||
|         }, |  | ||||||
|         //as required by language service
 |  | ||||||
|         node_modules: { |  | ||||||
|             "@types": { |  | ||||||
|                 "lib.d.ts": { |  | ||||||
|                     content: "", |  | ||||||
|                     version: 0, |  | ||||||
|                     isDir: false, |  | ||||||
|                 }, |  | ||||||
|                 version: 0, |  | ||||||
|                 isDir: true, |  | ||||||
|             }, |  | ||||||
|             version: 0, |  | ||||||
|             isDir: true, |  | ||||||
|         }, |  | ||||||
|         version: 0, |  | ||||||
|         isDir: true, |  | ||||||
|     }, |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * The current directory, "/" |  | ||||||
|      */ |  | ||||||
|     currentDirectory : { }, |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Registers a file with the compiler |  | ||||||
|      * @param {string} fileName The file's name |  | ||||||
|      * @param {string} content The content of the file |  | ||||||
|      * @returns {string[]} The list of all files that still need to be registered by the host |  | ||||||
|      */ |  | ||||||
|     registerFile: (fileName, content) => { |  | ||||||
| 
 |  | ||||||
|         //the list of files that are imported by this file
 |  | ||||||
|         let dependentFiles = [] |  | ||||||
|      |  | ||||||
|         loggerScripts.INFO('REGISTER FILE ' + fileName) |  | ||||||
|         if(!COMPILER.fileMap[fileName]){ |  | ||||||
|             //create the virtual file
 |  | ||||||
|             COMPILER.fileMap[fileName] = COMPILER.createFile(fileName,content) |  | ||||||
|             //register the file itself
 |  | ||||||
|             COMPILER.fileMap[fileName].tsSourceFile = ts.createSourceFile( |  | ||||||
|                 fileName, |  | ||||||
|                 content, |  | ||||||
|                 ts.ScriptTarget.Latest, |  | ||||||
|             ) |  | ||||||
|             COMPILER.sourceFiles.push(fileName) |  | ||||||
|             /** |  | ||||||
|              * The preprocessed info about the file |  | ||||||
|              * { |  | ||||||
|              *   referencedFiles: ?, |  | ||||||
|              *   typeReferenceDirectives: ?, |  | ||||||
|              *   libReferenceDirectives: ?, |  | ||||||
|              *   importedFiles: Array<{ |  | ||||||
|              *     fileName: string, //the path (without file ending) of the file that is imported by this file
 |  | ||||||
|              *     pos: ?, |  | ||||||
|              *     end: ?, |  | ||||||
|              *   }>, |  | ||||||
|              *   isLibFile: boolean, |  | ||||||
|              *   ambientExternalModules: ?, |  | ||||||
|              * } |  | ||||||
|              */ |  | ||||||
|             const fileInfo = ts.preProcessFile(content) |  | ||||||
|             loggerScripts.INFO('==========================') |  | ||||||
|             loggerScripts.INFO(fileName) |  | ||||||
|             loggerScripts.INFO('Registered file depends on:') |  | ||||||
|             fileInfo.importedFiles.forEach(module => { |  | ||||||
|                 let extension = ".ts" |  | ||||||
|                 /** |  | ||||||
|                  * { |  | ||||||
|                  *   resolvedModule: ?, |  | ||||||
|                  *   failedLookupLocations: Array<string>, |  | ||||||
|                  *   affectingLocations: ?, |  | ||||||
|                  *   resolutionDiagnostics: ?, |  | ||||||
|                  *   alternateResult: ?, |  | ||||||
|                  * } |  | ||||||
|                  */ |  | ||||||
|                 const resolvedImport = ts.resolveModuleName(module.fileName,fileName,COMPILER.compilerOptions,COMPILER.customCompilerHost) |  | ||||||
|                 if(resolvedImport?.resolvedModule){ |  | ||||||
|                     /** |  | ||||||
|                      * undefined |  | ||||||
|                      * OR |  | ||||||
|                      * { |  | ||||||
|                      *   resolvedFileName: ?, |  | ||||||
|                      *   originalPath: ?, |  | ||||||
|                      *   extension: string, (ie ".js", ".ts", etc) |  | ||||||
|                      *   isExternalLibraryImport: boolean, |  | ||||||
|                      *   packageId: ?, |  | ||||||
|                      *   resolvedUsingTsExtension: boolean, |  | ||||||
|                      * } |  | ||||||
|                      */ |  | ||||||
|                     const module = resolvedImport.resolvedModule |  | ||||||
|                     extension = module.extension |  | ||||||
|                 } |  | ||||||
|                 //am assuming we're always importing typescript for the time being
 |  | ||||||
|                 const dependentFile = module.fileName + extension |  | ||||||
|                 const normalizedDependentFilePath = FILE_RESOLUTION_getFilePath(dependentFile,false) |  | ||||||
|                 if(!COMPILER.fileMap[normalizedDependentFilePath]){ |  | ||||||
|                     dependentFiles.push(normalizedDependentFilePath) |  | ||||||
|                     loggerScripts.INFO(" - " + normalizedDependentFilePath) |  | ||||||
|                 } |  | ||||||
|             }) |  | ||||||
|      |  | ||||||
|             //If the compiler has already run once, run the language service against only this file
 |  | ||||||
|             if(!!COMPILER.compilerHasRun){ |  | ||||||
|                 COMPILER.emitFile(fileName) |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         return dependentFiles; |  | ||||||
|     }, |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Creates a file object for a given path |  | ||||||
|      * @param string} fileName The name of the file |  | ||||||
|      * @param {string} content The content of the file |  | ||||||
|      * @returns The file object |  | ||||||
|      */ |  | ||||||
|     createFile: (fileName, content) => { |  | ||||||
|         //get the file path array
 |  | ||||||
|         const filePathArray = COMPILER.getPath(fileName) |  | ||||||
|         let mutableArray = filePathArray |  | ||||||
|      |  | ||||||
|         //the current folder as we recursively create folders to populate this file
 |  | ||||||
|         let currentFolder = COMPILER.topLevelDirectory |  | ||||||
|      |  | ||||||
|         //recursively create directories until our file is written
 |  | ||||||
|         while(mutableArray.length > 1){ |  | ||||||
|             let nextDirName = mutableArray.shift() |  | ||||||
|             if(!currentFolder?.[nextDirName]){ |  | ||||||
|                 //create directory
 |  | ||||||
|                 currentFolder[nextDirName] = { |  | ||||||
|                     isDir: true, |  | ||||||
|                     "..": currentFolder, |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             currentFolder = currentFolder?.[nextDirName] |  | ||||||
|         } |  | ||||||
|      |  | ||||||
|         //create the actual file
 |  | ||||||
|         currentFolder[mutableArray[0]] = { |  | ||||||
|             isDir: false, |  | ||||||
|             dir: currentFolder, |  | ||||||
|             content: content, |  | ||||||
|             version: 0, |  | ||||||
|         } |  | ||||||
|      |  | ||||||
|         //return the file
 |  | ||||||
|         return currentFolder[mutableArray[0]] |  | ||||||
|     }, |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Gets the path for the file |  | ||||||
|      * @param {string} fullyQualifiedFilePath The fully qualified file path |  | ||||||
|      * @returns {string[]} The array of directories ending with the name of the file |  | ||||||
|      */ |  | ||||||
|     getPath: (fullyQualifiedFilePath) => { |  | ||||||
|         let modifiedFileName = fullyQualifiedFilePath |  | ||||||
|         //remove leading "/"
 |  | ||||||
|         if(modifiedFileName.startsWith("/")){ |  | ||||||
|             modifiedFileName = modifiedFileName.substring(1) |  | ||||||
|         } |  | ||||||
|         //split
 |  | ||||||
|         return modifiedFileName.split("/") |  | ||||||
|     }, |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Gets the path for the file |  | ||||||
|      * @param {stringp[]} filePathArray The fully qualified file path |  | ||||||
|      * @returns The array of directories ending with the name of the file |  | ||||||
|      */ |  | ||||||
|     getFileByPath: (filePathArray) => { |  | ||||||
|         let currentFolder = COMPILER.topLevelDirectory |  | ||||||
|         let mutableArray = filePathArray |  | ||||||
|      |  | ||||||
|         //illegal state
 |  | ||||||
|         if(mutableArray?.length < 1){ |  | ||||||
|             throw new Error("Trying to get a file with a path array of length 0!") |  | ||||||
|         } |  | ||||||
|      |  | ||||||
|         while(mutableArray?.length > 1){ |  | ||||||
|             let nextDirName = mutableArray.shift() |  | ||||||
|             currentFolder = currentFolder?.[nextDirName] |  | ||||||
|             if(!currentFolder){ |  | ||||||
|                 let errorMessage = "Trying to get file in directory that doesn't exist! \n" + |  | ||||||
|                 nextDirName |  | ||||||
|                 throw new Error(errorMessage) |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         return currentFolder[mutableArray?.[0]] |  | ||||||
|     }, |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Checks if a file exists |  | ||||||
|      * @param {string[]} filePathArray The file path array |  | ||||||
|      * @returns true if it exists, false otherwise |  | ||||||
|      */ |  | ||||||
|     fileExists: (filePathArray) => { |  | ||||||
|         let currentFolder = COMPILER.topLevelDirectory |  | ||||||
|         let mutableArray = filePathArray |  | ||||||
|      |  | ||||||
|         //illegal state
 |  | ||||||
|         if(mutableArray?.length < 1){ |  | ||||||
|             throw new Error("Trying to get a file with a path array of length 0!") |  | ||||||
|         } |  | ||||||
|      |  | ||||||
|         while(mutableArray.length > 1){ |  | ||||||
|             let nextDirName = mutableArray.shift() |  | ||||||
|             currentFolder = currentFolder?.[nextDirName] |  | ||||||
|             if(!currentFolder){ |  | ||||||
|                 return false |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         return !!currentFolder?.[mutableArray[0]] |  | ||||||
|     }, |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * The callback invoked when the compiler host tries to read a file |  | ||||||
|      * @param {string} fileName The name of the file |  | ||||||
|      * @param {*} languageVersion The language version |  | ||||||
|      * @returns The file if it exists, null otherwise |  | ||||||
|      */ |  | ||||||
|     getSourceFile: (fileName, languageVersion) => { |  | ||||||
|         if(!!COMPILER.fileMap[fileName]){ |  | ||||||
|             return COMPILER.fileMap[fileName].tsSourceFile |  | ||||||
|         } else { |  | ||||||
|             return null |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|     //
 | /** | ||||||
|     //
 |  * Registers a file with the compiler | ||||||
|     //   COMPILATION
 |  * @param {*} fileName The file's name | ||||||
|     //
 |  * @param {*} content The content of the file | ||||||
|     //
 |  */ | ||||||
|  | const COMPILER_registerFile = (fileName, content) => { | ||||||
|  |     let normalizedFilePath = FILE_RESOLUTION_getFilePath(fileName,false) | ||||||
|  |     loggerScripts.INFO('REGISTER FILE ' + normalizedFilePath) | ||||||
|  |     COMPILER_fileMap[normalizedFilePath] = { | ||||||
|  |         content: content, | ||||||
|  |         compiled: ts.createSourceFile( | ||||||
|  |             normalizedFilePath, content, ts.ScriptTarget.Latest | ||||||
|  |         ) | ||||||
|  |     } | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
|     /** |  | ||||||
|      * The compiler options |  | ||||||
|      */ |  | ||||||
|     compilerOptions: { }, |  | ||||||
| 
 | 
 | ||||||
|     /** | /** | ||||||
|      * Tracks whether the compiler has run or not |  * The callback invoked when the compiler host tries to read a file | ||||||
|      */ |  * @param {*} fileName The name of the file | ||||||
|     compilerHasRun: false, |  * @param {*} languageVersion The language version | ||||||
| 
 |  * @returns The file if it exists, null otherwise | ||||||
|     /** |  */ | ||||||
|      * The typescript compiler host definition | const COMPILER_getSourceFile = (fileName, languageVersion) => { | ||||||
|      */ |     if(!!COMPILER_fileMap[fileName]){ | ||||||
|     customCompilerHost: null, |         return COMPILER_fileMap[fileName].compiled | ||||||
| 
 |     } else { | ||||||
|     /** |         return null | ||||||
|      * The typescript program |     } | ||||||
|      */ |  | ||||||
|     program: null, |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Emits a file |  | ||||||
|      * @param {string} fileName The name of the file |  | ||||||
|      * @returns {void} |  | ||||||
|      */ |  | ||||||
|     emitFile: (fileName) => { |  | ||||||
|         loggerScripts.DEBUG('Compiler evaluating source path ' + fileName) |  | ||||||
|         /** |  | ||||||
|          * { |  | ||||||
|          *   outputFiles: [ ], |  | ||||||
|          *   emitSkipped: boolean, |  | ||||||
|          *   diagnostics: { }, |  | ||||||
|          * } |  | ||||||
|          */ |  | ||||||
|         const output = COMPILER.program.getEmitOutput(fileName) |  | ||||||
|         if (!output.emitSkipped) { |  | ||||||
|             output.outputFiles.forEach(outputFile => { |  | ||||||
|                 loggerScripts.DEBUG(`[ts] Emitting ${outputFile}`); |  | ||||||
|                 COMPILER.customCompilerHost.writeFile(outputFile.name, outputFile.text) |  | ||||||
|             }) |  | ||||||
|         } else { |  | ||||||
|             loggerScripts.DEBUG(`[ts] Emitting ${fileName} failed`); |  | ||||||
|             COMPILER.logEmitError(fileName); |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Logs errors raised during emission of files |  | ||||||
|      * @param {string} fileName The name of the file to log errors about |  | ||||||
|      * @returns {void} |  | ||||||
|      */ |  | ||||||
|     logEmitError: (fileName) => { |  | ||||||
|         loggerScripts.DEBUG('[ts] logErrors ' + fileName) |  | ||||||
|         let allDiagnostics = services |  | ||||||
|             .getCompilerOptionsDiagnostics() |  | ||||||
|             .concat(services.getSyntacticDiagnostics(fileName)) |  | ||||||
|             .concat(services.getSemanticDiagnostics(fileName)); |  | ||||||
|      |  | ||||||
|         allDiagnostics.forEach(diagnostic => { |  | ||||||
|             let message = ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n"); |  | ||||||
|             if (diagnostic.file) { |  | ||||||
|                 let { line, character } = diagnostic.file.getLineAndCharacterOfPosition( |  | ||||||
|                     diagnostic.start |  | ||||||
|                 ); |  | ||||||
|                 loggerScripts.DEBUG(`[ts]  Error ${diagnostic.file.fileName} (${line + 1},${character +1}): ${message}`); |  | ||||||
|             } else { |  | ||||||
|                 loggerScripts.DEBUG(`[ts]  Error: ${message}`); |  | ||||||
|             } |  | ||||||
|         }); |  | ||||||
|     }, |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Instructs Typescript to emit the final compiled value |  | ||||||
|      */ |  | ||||||
|     run: () => { |  | ||||||
|         loggerScripts.INFO('COMPILE ALL REGISTERED FILES') |  | ||||||
|      |  | ||||||
|         if(!COMPILER.program){ |  | ||||||
|             COMPILER.program = ts.createLanguageService(COMPILER.customCompilerHost, ts.createDocumentRegistry()); |  | ||||||
|         } |  | ||||||
|      |  | ||||||
|         //Emit all currently known files
 |  | ||||||
|         COMPILER.sourceFiles.forEach(sourcePath => { |  | ||||||
|             COMPILER.emitFile(sourcePath) |  | ||||||
|         }) |  | ||||||
|      |  | ||||||
|         //flag that the compiler has run (ie only incrementally compile when new files are added, now)
 |  | ||||||
|         COMPILER.compilerHasRun = true |  | ||||||
|     }, |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Loads a file |  | ||||||
|      * @param {*} fileName The name of the file to load (preferably already has .ts at the end) |  | ||||||
|      */ |  | ||||||
|     runFile: (fileName) => { |  | ||||||
|         let normalizedFilePath = FILE_RESOLUTION_getFilePath(fileName) |  | ||||||
|         if(!!COMPILER.fileMap[normalizedFilePath]){ |  | ||||||
|             loggerScripts.INFO('RUN FILE ' + normalizedFilePath) |  | ||||||
|             eval(COMPILER.fileMap[normalizedFilePath].content) |  | ||||||
|         } else { |  | ||||||
|             const message = 'FAILED TO RESOLVE FILE ' + normalizedFilePath |  | ||||||
|             loggerScripts.WARNING(message) |  | ||||||
|             throw new Error(message) |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Loads a file |  | ||||||
|      * @param {*} fileName The name of the file to load (preferably already has .ts at the end) |  | ||||||
|      */ |  | ||||||
|     printSource: (fileName) => { |  | ||||||
|         let normalizedFilePath = FILE_RESOLUTION_getFilePath(fileName) |  | ||||||
|         if(!!COMPILER.fileMap[normalizedFilePath]){ |  | ||||||
|             loggerScripts.INFO('FILE CONTENT ' + normalizedFilePath) |  | ||||||
|         } else { |  | ||||||
|             const message = 'FAILED TO RESOLVE FILE ' + normalizedFilePath |  | ||||||
|             loggerScripts.WARNING(message) |  | ||||||
|             loggerScripts.WARNING('file map content:') |  | ||||||
|             loggerScripts.WARNING(OBject.keys(COMPILER.fileMap) + "") |  | ||||||
|             throw new Error(message) |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Constructs the compiler host |  * Constructs the compiler host | ||||||
|  * https://www.typescriptlang.org/tsconfig/#compilerOptions
 |  * https://www.typescriptlang.org/tsconfig/#compilerOptions
 | ||||||
|  *  |  | ||||||
|  * Examples: |  | ||||||
|  * https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API
 |  | ||||||
|  *  |  | ||||||
|  */ |  */ | ||||||
| COMPILER.customCompilerHost = { | const COMPILER_customCompilerHost = { | ||||||
|     getSourceFile: COMPILER.getSourceFile, |     getSourceFile: COMPILER_getSourceFile, | ||||||
|     writeFile: (fileName, data) => { |     writeFile: (fileName, data) => { | ||||||
|         loggerScripts.INFO("EMIT FILE " + fileName) |         let normalizedFilePath = FILE_RESOLUTION_getFilePath(fileName) | ||||||
|         //wrap in require logic
 |         loggerScripts.INFO("EMIT FILE " + normalizedFilePath) | ||||||
|         let finalData =  |         let finalData =  | ||||||
|         "let exports = { }\n" + |         "let exports = { }\n" + | ||||||
|         data + "\n" + |         data + "\n" + | ||||||
|         "return exports" |         "return exports" | ||||||
| 
 |         // COMPILER_emitted_value = data
 | ||||||
|         //create file
 |         COMPILER_fileMap[normalizedFilePath] = { | ||||||
|         COMPILER.createFile(fileName,finalData) |  | ||||||
|          |  | ||||||
|         //register in file map
 |  | ||||||
|         COMPILER.fileMap[fileName] = { |  | ||||||
|             content: data, //to be eval'd from top level
 |             content: data, //to be eval'd from top level
 | ||||||
|             moduleContent: finalData, //to be eval'd from require()
 |             moduleContent: finalData, //to be eval'd from require()
 | ||||||
|         } |         } | ||||||
|     }, |     }, | ||||||
|     getDefaultLibFileName: ts.getDefaultLibFileName, |     getDefaultLibFileName: () => "lib.d.ts", | ||||||
|     useCaseSensitiveFileNames: () => false, |     useCaseSensitiveFileNames: () => false, | ||||||
|     getCanonicalFileName: filename => filename, |     getCanonicalFileName: filename => filename, | ||||||
|     getCurrentDirectory: () => "/", |     getCurrentDirectory: () => "", | ||||||
|     getNewLine: () => "\n", |     getNewLine: () => "\n", | ||||||
|     getDirectories: (path) => { |     getDirectories: () => [], | ||||||
|         loggerScripts.DEBUG('[ts] getDirectories ' + path) |     fileExists: () => true, | ||||||
|         const dirs = Object.keys(COMPILER.getFileByPath(COMPILER.getPath(path))) |     readFile: () => "" | ||||||
|         loggerScripts.DEBUG('[ts] dirs: ' + dirs) |  | ||||||
|         return dirs |  | ||||||
|     }, |  | ||||||
|     directoryExists: (path) => { |  | ||||||
|         let exists = COMPILER.fileExists(COMPILER.getPath(path)) |  | ||||||
|         if(exists){ |  | ||||||
|             exists = COMPILER.getFileByPath(COMPILER.getPath(path))?.isDir |  | ||||||
|         } |  | ||||||
|         loggerScripts.DEBUG('[ts] directoryExists ' + path + " - " + exists) |  | ||||||
|         return false |  | ||||||
|     }, |  | ||||||
|     fileExists: (path) => { |  | ||||||
|         const exists = COMPILER.fileExists(COMPILER.getPath(path)) |  | ||||||
|         loggerScripts.DEBUG('[ts] fileExists ' + path + " - " + exists) |  | ||||||
|         return exists |  | ||||||
|     }, |  | ||||||
|     readFile: (path) => { |  | ||||||
|         loggerScripts.DEBUG('[ts] readFile ' + path) |  | ||||||
|         const file = COMPILER.getFileByPath(COMPILER.getPath(path)) |  | ||||||
|         loggerScripts.DEBUG('[ts] readFile (content): ' + file.content) |  | ||||||
|         return file.content |  | ||||||
|     }, |  | ||||||
|     getScriptFileNames: () => { |  | ||||||
|         loggerScripts.DEBUG('[ts] getScriptFileNames') |  | ||||||
|         return COMPILER.sourceFiles |  | ||||||
|     }, |  | ||||||
|     getScriptVersion: (fileName) => { |  | ||||||
|         loggerScripts.DEBUG('[ts] getScriptVersion: ' + fileName) |  | ||||||
|         const file = COMPILER.getFileByPath(COMPILER.getPath(fileName)) |  | ||||||
|         return file?.version |  | ||||||
|     }, |  | ||||||
|     //https://github.com/microsoft/TypeScript/wiki/Using-the-Language-Service-API#scriptsnapshot
 |  | ||||||
|     getScriptSnapshot: (fileName) => { |  | ||||||
|         loggerScripts.DEBUG('[ts] getScriptSnapshot: ' + fileName) |  | ||||||
|         const file = COMPILER.getFileByPath(COMPILER.getPath(fileName)) |  | ||||||
|         if(file){ |  | ||||||
|             return ts.ScriptSnapshot.fromString(file.content) |  | ||||||
|         } else { |  | ||||||
|             return undefined |  | ||||||
|         } |  | ||||||
|     }, |  | ||||||
|     getCompilationSettings: () => COMPILER.compilerOptions, |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| //initialized CWD
 | /** | ||||||
| COMPILER.currentDirectory = COMPILER.topLevelDirectory |  * Instructs Typescript to emit the final compiled value | ||||||
|  |  */ | ||||||
|  | const COMPILER_run = () => { | ||||||
|  |     loggerScripts.INFO('COMPILE ALL REGISTERED FILES') | ||||||
|  | 
 | ||||||
|  |     const compilerOptions = { } | ||||||
|  | 
 | ||||||
|  |     const COMPILER_program = ts.createProgram( | ||||||
|  |         Object.keys(COMPILER_fileMap), compilerOptions, COMPILER_customCompilerHost | ||||||
|  |     ) | ||||||
|  |     COMPILER_program.emit() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Loads a file | ||||||
|  |  * @param {*} fileName The name of the file to load (preferably already has .ts at the end) | ||||||
|  |  */ | ||||||
|  | const COMPILER_runFile = (fileName) => { | ||||||
|  |     let normalizedFilePath = FILE_RESOLUTION_getFilePath(fileName) | ||||||
|  |     if(!!COMPILER_fileMap[normalizedFilePath]){ | ||||||
|  |         loggerScripts.INFO('RUN FILE ' + normalizedFilePath) | ||||||
|  |         eval(COMPILER_fileMap[normalizedFilePath].content) | ||||||
|  |     } else { | ||||||
|  |         const message = 'FAILED TO RESOLVE FILE ' + normalizedFilePath | ||||||
|  |         loggerScripts.WARNING(message) | ||||||
|  |         throw new Error(message) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Loads a file | ||||||
|  |  * @param {*} fileName The name of the file to load (preferably already has .ts at the end) | ||||||
|  |  */ | ||||||
|  | const COMPILER_printSource = (fileName) => { | ||||||
|  |     let normalizedFilePath = FILE_RESOLUTION_getFilePath(fileName) | ||||||
|  |     if(!!COMPILER_fileMap[normalizedFilePath]){ | ||||||
|  |         loggerScripts.INFO('FILE CONTENT ' + normalizedFilePath) | ||||||
|  |     } else { | ||||||
|  |         const message = 'FAILED TO RESOLVE FILE ' + normalizedFilePath | ||||||
|  |         loggerScripts.WARNING(message) | ||||||
|  |         loggerScripts.WARNING('file map content:') | ||||||
|  |         loggerScripts.WARNING(OBject.keys(COMPILER_fileMap) + "") | ||||||
|  |         throw new Error(message) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | |||||||
| @ -10,10 +10,10 @@ const FILE_RESOLUTION_getFilePath = (rawFilePath, isJavascript = true) => { | |||||||
|         fileName = fileName.replace('.ts','.js') |         fileName = fileName.replace('.ts','.js') | ||||||
|     } |     } | ||||||
|     if(fileName.startsWith('/Scripts')){ |     if(fileName.startsWith('/Scripts')){ | ||||||
|         // fileName = fileName.replace('/Scripts','')
 |         fileName = fileName.replace('/Scripts','') | ||||||
|     } |     } | ||||||
|     if(fileName.startsWith('Scripts')){ |     if(fileName.startsWith('Scripts/')){ | ||||||
|         fileName = fileName.replace('Scripts','/Scripts') |         fileName = fileName.replace('Scripts/','/') | ||||||
|     } |     } | ||||||
|     if(isJavascript && !fileName.endsWith(".js")){ |     if(isJavascript && !fileName.endsWith(".js")){ | ||||||
|         fileName = fileName + ".js" |         fileName = fileName + ".js" | ||||||
|  | |||||||
| @ -8,14 +8,14 @@ let HOST_ACCESS = { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| //fake require
 | //fake require
 | ||||||
| REQUIRE_CACHE["/Scripts/compiler/host_access.js"] = { | REQUIRE_CACHE["/compiler/host_access.js"] = { | ||||||
|     exports: { |     exports: { | ||||||
|         'HOST_ACCESS': HOST_ACCESS, |         'HOST_ACCESS': HOST_ACCESS, | ||||||
|         'loggerScripts': loggerScripts, |         'loggerScripts': loggerScripts, | ||||||
|     }, |     }, | ||||||
|     exportedValues: [ |     exportedValues: [ | ||||||
|         'HOST_ACCESS', |         'HOST_ACCESS', | ||||||
|         'loggerScripts', |         'loggerScripts' | ||||||
|     ], |     ], | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -16,24 +16,13 @@ let exports = { } | |||||||
|  * @param {*} cwd The current working directory |  * @param {*} cwd The current working directory | ||||||
|  */ |  */ | ||||||
| const require = (path) => { | const require = (path) => { | ||||||
|     //get the path
 |  | ||||||
|     loggerScripts.DEBUG('Require path ' + path) |     loggerScripts.DEBUG('Require path ' + path) | ||||||
|     let normalizedFilePath = FILE_RESOLUTION_getFilePath(path) |     let normalizedFilePath = FILE_RESOLUTION_getFilePath(path) | ||||||
| 
 |  | ||||||
|     //actually require
 |  | ||||||
|     if(!!REQUIRE_CACHE[normalizedFilePath]){ |     if(!!REQUIRE_CACHE[normalizedFilePath]){ | ||||||
|         //return if has already been required
 |  | ||||||
|         return REQUIRE_CACHE[normalizedFilePath].exports |         return REQUIRE_CACHE[normalizedFilePath].exports | ||||||
|     } else if(!!COMPILER.fileMap[normalizedFilePath]?.content) { |     } else if(!!COMPILER_fileMap[normalizedFilePath]?.content) { | ||||||
|         //require if it is already registered
 |         const code = COMPILER_fileMap[normalizedFilePath].moduleContent | ||||||
|         const code = COMPILER.fileMap[normalizedFilePath].moduleContent |  | ||||||
|         loggerScripts.DEBUG('Module code ' + JSON.stringify(code)) |         loggerScripts.DEBUG('Module code ' + JSON.stringify(code)) | ||||||
|         //create dummy prior to fully evaluating code so that we don't recurse infinitely
 |  | ||||||
|         REQUIRE_CACHE[normalizedFilePath] = { |  | ||||||
|             exports: {}, |  | ||||||
|             exportedValues: [], |  | ||||||
|         } |  | ||||||
|         //evaluate script for exports
 |  | ||||||
|         let exports = new Function(code)() |         let exports = new Function(code)() | ||||||
|         //create module object
 |         //create module object
 | ||||||
|         const module = { |         const module = { | ||||||
| @ -44,7 +33,6 @@ const require = (path) => { | |||||||
|         loggerScripts.INFO("[require] CREATE MODULE " + normalizedFilePath) |         loggerScripts.INFO("[require] CREATE MODULE " + normalizedFilePath) | ||||||
|         return module.exports |         return module.exports | ||||||
|     } else { |     } else { | ||||||
|         //fail if it doesn't exist from host's view
 |  | ||||||
|         const errorMsg = "FAILED TO REQUIRE FILE " + normalizedFilePath |         const errorMsg = "FAILED TO REQUIRE FILE " + normalizedFilePath | ||||||
|         loggerScripts.WARNING(errorMsg) |         loggerScripts.WARNING(errorMsg) | ||||||
|         loggerScripts.WARNING('Module value:') |         loggerScripts.WARNING('Module value:') | ||||||
| @ -53,19 +41,7 @@ const require = (path) => { | |||||||
|         loggerScripts.WARNING('Require cache contents:') |         loggerScripts.WARNING('Require cache contents:') | ||||||
|         loggerScripts.WARNING(Object.keys(REQUIRE_CACHE) + '') |         loggerScripts.WARNING(Object.keys(REQUIRE_CACHE) + '') | ||||||
|         loggerScripts.WARNING('File cache contents:') |         loggerScripts.WARNING('File cache contents:') | ||||||
|         loggerScripts.WARNING(Object.keys(COMPILER.fileMap) + '') |         loggerScripts.WARNING(Object.keys(COMPILER_fileMap) + '') | ||||||
|         throw new Error(errorMsg) |         throw new Error(errorMsg) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 |  | ||||||
| //Add require to its own cache
 |  | ||||||
| REQUIRE_CACHE["/Scripts/compiler/require_polyfill.js"] = { |  | ||||||
|     exports: { |  | ||||||
|         'require': require, |  | ||||||
|         'exports': exports, |  | ||||||
|     }, |  | ||||||
|     exportedValues: [ |  | ||||||
|         'require', |  | ||||||
|         'exports', |  | ||||||
|     ], |  | ||||||
| } |  | ||||||
|  | |||||||
| @ -1,8 +1,7 @@ | |||||||
| import { Engine } from '/Scripts/engine/engine-interface' | import { Engine } from '/Scripts/engine/engine-interface' | ||||||
| import { loggerScripts } from '/Scripts/compiler/host_access' | import { loggerScripts } from '/Scripts/compiler/host_access' | ||||||
| import { Client, NamespaceClient } from '/Scripts/client/client' | import { Client, NamespaceClient } from '/Scripts/client/client' | ||||||
| import { HookManager } from '/Scripts/engine/hooks/hook-manager' | import { HookManager } from '/Scripts/engine/hook-manager' | ||||||
| import { SceneLoader } from '/Scripts/engine/scene/scene-loader' |  | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * The core engine values |  * The core engine values | ||||||
| @ -11,7 +10,6 @@ export const engine: Engine = { | |||||||
|     classes: [], |     classes: [], | ||||||
|     singletons: [], |     singletons: [], | ||||||
|     hookManager: new HookManager(), |     hookManager: new HookManager(), | ||||||
|     sceneLoader: new SceneLoader(), |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
| @ -22,7 +20,6 @@ export const ENGINE_onInit = () => { | |||||||
| 
 | 
 | ||||||
|     //load namespaces
 |     //load namespaces
 | ||||||
|     let client: NamespaceClient = Client |     let client: NamespaceClient = Client | ||||||
|     engine.sceneLoader.hookManager = engine.hookManager |  | ||||||
| 
 | 
 | ||||||
|     loggerScripts.INFO('Script Engine Initialized') |     loggerScripts.INFO('Script Engine Initialized') | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,5 +1,4 @@ | |||||||
| import { HookManager } from "/Scripts/engine/hooks/hook-manager"; | import { HookManager } from "/Scripts/engine/hook-manager"; | ||||||
| import { SceneLoader } from "/Scripts/engine/scene/scene-loader"; |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
| @ -22,9 +21,4 @@ export interface Engine { | |||||||
|      */ |      */ | ||||||
|     hookManager: HookManager, |     hookManager: HookManager, | ||||||
|      |      | ||||||
|     /** |  | ||||||
|      * Tracks and loads scenes |  | ||||||
|      */ |  | ||||||
|     sceneLoader: SceneLoader, |  | ||||||
| 
 |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,4 +1,3 @@ | |||||||
| import { TrackedScene } from "/Scripts/engine/scene/scene-loader" |  | ||||||
| import { Hook } from "/Scripts/types/hook" | import { Hook } from "/Scripts/types/hook" | ||||||
| import { Scene } from "/Scripts/types/scene" | import { Scene } from "/Scripts/types/scene" | ||||||
| 
 | 
 | ||||||
| @ -16,7 +15,7 @@ export enum HookScope { | |||||||
| /** | /** | ||||||
|  * A hook that is tracked by the manager |  * A hook that is tracked by the manager | ||||||
|  */ |  */ | ||||||
| export interface TrackedHook extends Hook { | interface TrackedHook extends Hook { | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * The scope that this hook was defined at |      * The scope that this hook was defined at | ||||||
| @ -30,6 +29,23 @@ export interface TrackedHook extends Hook { | |||||||
| 
 | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /** | ||||||
|  |  * A scene being tracked by the manager | ||||||
|  |  */ | ||||||
|  | interface TrackedScene { | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * The id assigned to the scene | ||||||
|  |      */ | ||||||
|  |     sceneId: number, | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * The scene itself | ||||||
|  |      */ | ||||||
|  |     scene: Scene, | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /** | /** | ||||||
|  * Manages hooks for the engine |  * Manages hooks for the engine | ||||||
|  */ |  */ | ||||||
| @ -40,6 +56,11 @@ export class HookManager { | |||||||
|      */ |      */ | ||||||
|     hooks: Array<TrackedHook> = [] |     hooks: Array<TrackedHook> = [] | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * A map of a scene to all hooks related to the scene | ||||||
|  |      */ | ||||||
|  |     sceneHookMap: Record<number,Array<TrackedHook>> = { } | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * A map of engine signal to the list of hooks that should be called when that signal fires |      * A map of engine signal to the list of hooks that should be called when that signal fires | ||||||
|      */ |      */ | ||||||
| @ -48,7 +69,57 @@ export class HookManager { | |||||||
|     /** |     /** | ||||||
|      * The list of all scenes tracked by the manager |      * The list of all scenes tracked by the manager | ||||||
|      */ |      */ | ||||||
|     trackedScenes: Array<TrackedScene> = [] |     trackedScenes: Array<{ sceneId: number, scene: Scene }> = [] | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * A scene  | ||||||
|  |      */ | ||||||
|  |     sceneIdIncrementer: number = 0 | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Registers all hooks in a scene to the hook manager | ||||||
|  |      * @param scene The scene | ||||||
|  |      */ | ||||||
|  |     registerScene(scene: Scene, isServerScene: boolean){ | ||||||
|  |         const shouldRegister: boolean = !this.containsScene(scene) | ||||||
|  |         if(shouldRegister){ | ||||||
|  | 
 | ||||||
|  |             //add to the list of tracked scenes
 | ||||||
|  |             const trackedScene: TrackedScene = { | ||||||
|  |                 sceneId: this.sceneIdIncrementer++, | ||||||
|  |                 scene: scene, | ||||||
|  |             } | ||||||
|  |             this.trackedScenes.push(trackedScene) | ||||||
|  | 
 | ||||||
|  |             //load all hooks from the scene
 | ||||||
|  |             scene.hooks.forEach((hook: Hook) => { | ||||||
|  |                 this.registerHook(trackedScene,hook,isServerScene) | ||||||
|  |             }) | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Deregisters all hooks in a scene from the hook manager | ||||||
|  |      * @param scene The scene | ||||||
|  |      */ | ||||||
|  |     deregisterScene(scene: Scene){ | ||||||
|  |         throw new Error("Unsupported Operation!") | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Checks if the manager is tracking a given scene | ||||||
|  |      * @param scene The scene | ||||||
|  |      * @returns true if it is being tracked already, false otherwise | ||||||
|  |      */ | ||||||
|  |     containsScene(scene: Scene): boolean { | ||||||
|  |         this.trackedScenes.forEach(trackedScene => { | ||||||
|  |             if(trackedScene.scene === scene){ | ||||||
|  |                 return true | ||||||
|  |             } | ||||||
|  |         }) | ||||||
|  |         return false | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Registers a hook |      * Registers a hook | ||||||
| @ -68,19 +139,10 @@ export class HookManager { | |||||||
|         const signalArray: Array<TrackedHook> = this.signalHookMap?.[hookSignal] ? this.signalHookMap?.[hookSignal] : [] |         const signalArray: Array<TrackedHook> = this.signalHookMap?.[hookSignal] ? this.signalHookMap?.[hookSignal] : [] | ||||||
|         signalArray.push(trackedHook) |         signalArray.push(trackedHook) | ||||||
|         this.signalHookMap[hookSignal] = signalArray |         this.signalHookMap[hookSignal] = signalArray | ||||||
|         //
 |         //add to scene array
 | ||||||
|         //Scene related structures
 |         const sceneArray: Array<TrackedHook> = this.sceneHookMap?.[scene.sceneId] ? this.sceneHookMap?.[scene.sceneId] : [] | ||||||
|         //
 |         sceneArray.push(trackedHook) | ||||||
|         //track scene if it isn't already being tracked
 |         this.sceneHookMap[scene.sceneId] = sceneArray | ||||||
|         let filteredArr = this.trackedScenes.filter(trackedScene => trackedScene.instanceId === scene.instanceId) |  | ||||||
|         if(filteredArr.length < 1){ |  | ||||||
|             this.trackedScenes.push(scene) |  | ||||||
|         } |  | ||||||
|         //add to scene tracking structures
 |  | ||||||
|         scene.sceneHooks.push(trackedHook) |  | ||||||
|         const sceneSignalArray: Array<TrackedHook> = scene.signalHookMap?.[hookSignal] ? scene.signalHookMap?.[hookSignal] : [] |  | ||||||
|         sceneSignalArray.push(trackedHook) |  | ||||||
|         scene.signalHookMap[hookSignal] = sceneSignalArray |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
| @ -97,7 +159,7 @@ export class HookManager { | |||||||
|      * @param signal The signal |      * @param signal The signal | ||||||
|      * @param value The value associated with the signal |      * @param value The value associated with the signal | ||||||
|      */ |      */ | ||||||
|     fireSignal(instanceId: number, signal: string, value: any){ |     fireSignal(signal: string, value: any){ | ||||||
|         const hooks: Array<TrackedHook> = this.signalHookMap[signal] |         const hooks: Array<TrackedHook> = this.signalHookMap[signal] | ||||||
|         hooks.forEach(trackedHook => { |         hooks.forEach(trackedHook => { | ||||||
|             trackedHook.callback(value) |             trackedHook.callback(value) | ||||||
| @ -1,137 +0,0 @@ | |||||||
| import { engine } from "/Scripts/engine/engine-init"; |  | ||||||
| import { HookManager, TrackedHook } from "/Scripts/engine/hooks/hook-manager"; |  | ||||||
| import { Hook } from "/Scripts/types/hook"; |  | ||||||
| import { Scene } from "/Scripts/types/scene"; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * A scene being tracked by the manager |  | ||||||
|  */ |  | ||||||
| export interface TrackedScene { |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * The id assigned to the scene |  | ||||||
|      */ |  | ||||||
|     instanceId: number, |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * The scene itself |  | ||||||
|      */ |  | ||||||
|     scene: Scene, |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * A map of a scene to all hooks related to the scene |  | ||||||
|      */ |  | ||||||
|     sceneHooks: Array<TrackedHook> |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * A map of engine signal to the list of hooks that should be called when that signal fires |  | ||||||
|      */ |  | ||||||
|     signalHookMap: Record<string,Array<TrackedHook>> |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Loads scenes |  | ||||||
|  */ |  | ||||||
| export class SceneLoader { |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|      |  | ||||||
|     /** |  | ||||||
|      * The hook manager |  | ||||||
|      */ |  | ||||||
|     hookManager: HookManager |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * The list of loaded scenes |  | ||||||
|      */ |  | ||||||
|     loadedScenes: TrackedScene[] = [ ] |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * A record of tracked scene id to tracked scene object |  | ||||||
|      */ |  | ||||||
|     sceneIdMap: Record<number,TrackedScene> = { } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * A scene  |  | ||||||
|      */ |  | ||||||
|     sceneIdIncrementer: number = 0 |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Loads a scene |  | ||||||
|      * @param sceneName The scene to load |  | ||||||
|      * @returns The id assigned to the instance of the scene |  | ||||||
|      */ |  | ||||||
|     loadScene(sceneName: string): number { |  | ||||||
|         //@ts-ignore
 |  | ||||||
|         const scene: Scene = require(sceneName).default |  | ||||||
| 
 |  | ||||||
|         //creates an instance of the scene
 |  | ||||||
|         let sceneInstanceId: number = this.createInstance(scene,true) |  | ||||||
| 
 |  | ||||||
|         //call on init for scene
 |  | ||||||
|         if(scene.onCreate){ |  | ||||||
|             scene.onCreate(sceneInstanceId) |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return sceneInstanceId |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Registers all hooks in a scene to the hook manager |  | ||||||
|      * @param scene The scene |  | ||||||
|      * @returns The id assigned to the instance of the scene |  | ||||||
|      */ |  | ||||||
|     createInstance(scene: Scene, isServerScene: boolean): number{ |  | ||||||
|         //add to the list of tracked scenes
 |  | ||||||
|         const trackedScene: TrackedScene = { |  | ||||||
|             instanceId: this.sceneIdIncrementer++, |  | ||||||
|             scene: scene, |  | ||||||
|             sceneHooks: [], |  | ||||||
|             signalHookMap: { }, |  | ||||||
|         } |  | ||||||
|         this.loadedScenes.push(trackedScene) |  | ||||||
|         this.sceneIdMap[trackedScene.instanceId] = trackedScene |  | ||||||
| 
 |  | ||||||
|         //load all hooks from the scene
 |  | ||||||
|         scene?.hooks?.forEach((hook: Hook) => { |  | ||||||
|             engine.hookManager.registerHook(trackedScene,hook,isServerScene) |  | ||||||
|         }) |  | ||||||
| 
 |  | ||||||
|         return trackedScene.instanceId |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Deregisters all hooks in a scene from the hook manager |  | ||||||
|      * @param scene The scene |  | ||||||
|      */ |  | ||||||
|     deregisterScene(scene: Scene){ |  | ||||||
|         throw new Error("Unsupported Operation!") |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Checks if the manager is tracking a given scene |  | ||||||
|      * @param scene The scene |  | ||||||
|      * @returns true if it is being tracked already, false otherwise |  | ||||||
|      */ |  | ||||||
|     containsScene(scene: Scene): boolean { |  | ||||||
|         this.loadedScenes.forEach(trackedScene => { |  | ||||||
|             if(trackedScene.scene === scene){ |  | ||||||
|                 return true |  | ||||||
|             } |  | ||||||
|         }) |  | ||||||
|         return false |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Gets a tracked scene by its id |  | ||||||
|      * @param sceneId The tracked scene |  | ||||||
|      * @returns The tracked scene if it exists, null otherwise |  | ||||||
|      */ |  | ||||||
|     getScene(sceneId: number){ |  | ||||||
|         return this.sceneIdMap[sceneId] |  | ||||||
|     } |  | ||||||
|      |  | ||||||
| } |  | ||||||
| @ -1,4 +1,3 @@ | |||||||
| import { TrackedScene } from "/Scripts/engine/scene/scene-loader"; |  | ||||||
| import { Hook } from "/Scripts/types/hook"; | import { Hook } from "/Scripts/types/hook"; | ||||||
| import { Namespace } from "/Scripts/types/namespace"; | import { Namespace } from "/Scripts/types/namespace"; | ||||||
| 
 | 
 | ||||||
| @ -27,9 +26,4 @@ export interface Scene extends Namespace { | |||||||
|      */ |      */ | ||||||
|     hooks?: Array<Hook> |     hooks?: Array<Hook> | ||||||
| 
 | 
 | ||||||
|     /** |  | ||||||
|      * Invoked when the scene is created |  | ||||||
|      */ |  | ||||||
|     onCreate?: (instanceId: number) => void |  | ||||||
| 
 |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,8 +1,5 @@ | |||||||
| @page dungeonsindex Dungeons | @page dungeonsindex Dungeons | ||||||
| 
 | 
 | ||||||
| [TOC] |  | ||||||
| - @subpage dungeonslayout |  | ||||||
| 
 |  | ||||||
| Enforce slower walking speed in dungeons (to give movement a more deliberate and weighty feel) | Enforce slower walking speed in dungeons (to give movement a more deliberate and weighty feel) | ||||||
|  - Slower movement will also help with weapons feel more impactful |  - Slower movement will also help with weapons feel more impactful | ||||||
| Have the engine generate different types of shortcuts to allow you to quickly navigate up/down to the uncleared floors | Have the engine generate different types of shortcuts to allow you to quickly navigate up/down to the uncleared floors | ||||||
|  | |||||||
| @ -1,11 +0,0 @@ | |||||||
| @page dungeonslayout Dungeon Layout |  | ||||||
| 
 |  | ||||||
| Procedural generation works better the more levers you have to tweak the generation with. |  | ||||||
| Ideas for levers with respect to layout of dungeon templates: |  | ||||||
|  - "Themes" of floors. IE having a spider themed floor, a magma/fire themed floor, etc |  | ||||||
|  - "Navigation Lines". Having specific templates that are used to make easily identifiable highways through the dungeon that guide the player between highest level points of interest |  | ||||||
|  - Color coordinating within floors |  | ||||||
|  - Puzzle subsections of floors |  | ||||||
|   - Working off of puzzles, have a central mechanism with explicit rooms around the mechanism (think a pillar that raises/lowers, a water level, etc) |  | ||||||
|   - Generate rooms connecting all of these explicit rooms |  | ||||||
|   - Don't necessarily want to connect them optimally. Players enjoy having to remember the location of other rooms earlier in the dungeon metroidvania style. |  | ||||||
| @ -33,7 +33,7 @@ public class DebugSPWorldLoading { | |||||||
|             SaveUtils.createOrOverwriteSave(saveName, SceneGenerator.createProceduralSceneFile(saveName)); |             SaveUtils.createOrOverwriteSave(saveName, SceneGenerator.createProceduralSceneFile(saveName)); | ||||||
|         } |         } | ||||||
|         //load just-created save |         //load just-created save | ||||||
|         SaveUtils.loadSave(saveName, false); |         SaveUtils.loadSave(saveName); | ||||||
|         //initialize the "virtual" objects simulation |         //initialize the "virtual" objects simulation | ||||||
|         LoadingUtils.initMacroSimulation(); |         LoadingUtils.initMacroSimulation(); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -53,7 +53,7 @@ public class LevelEditorLoading { | |||||||
|             SaveUtils.createOrOverwriteSave(saveName,sceneFile); |             SaveUtils.createOrOverwriteSave(saveName,sceneFile); | ||||||
|         } |         } | ||||||
|         //load just-created save |         //load just-created save | ||||||
|         SaveUtils.loadSave(saveName, true); |         SaveUtils.loadSave(saveName); | ||||||
| 
 | 
 | ||||||
|         LoggerInterface.loggerEngine.INFO("run server: " + Globals.RUN_SERVER + " run client: " + Globals.RUN_CLIENT); |         LoggerInterface.loggerEngine.INFO("run server: " + Globals.RUN_SERVER + " run client: " + Globals.RUN_CLIENT); | ||||||
|         //init authentication |         //init authentication | ||||||
|  | |||||||
| @ -34,7 +34,7 @@ public class LevelLoading { | |||||||
|         loadingWindow.setVisible(true); |         loadingWindow.setVisible(true); | ||||||
| 
 | 
 | ||||||
|         //load save |         //load save | ||||||
|         SaveUtils.loadSave(saveName, false); |         SaveUtils.loadSave(saveName); | ||||||
| 
 | 
 | ||||||
|         LoggerInterface.loggerEngine.INFO("run server: " + Globals.RUN_SERVER + " run client: " + Globals.RUN_CLIENT); |         LoggerInterface.loggerEngine.INFO("run server: " + Globals.RUN_SERVER + " run client: " + Globals.RUN_CLIENT); | ||||||
|         //init authentication |         //init authentication | ||||||
|  | |||||||
| @ -95,12 +95,4 @@ public class SceneFile { | |||||||
|         return createSaveInstance; |         return createSaveInstance; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |  | ||||||
|      * Sets whether the save utils will store a copy of the scene file in the save or not |  | ||||||
|      * @param createSaveInstancetrue if should create instance of scene file in save, false otherwise |  | ||||||
|      */ |  | ||||||
|     public void setCreateSaveInstance(boolean createSaveInstance){ |  | ||||||
|         this.createSaveInstance = createSaveInstance; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -23,23 +23,23 @@ public class SceneLoader { | |||||||
|      * Loads a scene file on the server |      * Loads a scene file on the server | ||||||
|      * @param path The name of the save to look for a scene file within |      * @param path The name of the save to look for a scene file within | ||||||
|      */ |      */ | ||||||
|     public static void serverInstantiateSaveSceneFile(String saveName, ServerWorldData serverWorldData, boolean isLevelEditor){ |     public static void serverInstantiateSaveSceneFile(String saveName, ServerWorldData serverWorldData){ | ||||||
|         //load scene file |         //load scene file | ||||||
|         SceneFile file = FileUtils.loadObjectFromSavePath(saveName, "/scene.json", SceneFile.class); |         SceneFile file = FileUtils.loadObjectFromSavePath(saveName, "/scene.json", SceneFile.class); | ||||||
|         //instantiate scene data |         //instantiate scene data | ||||||
|         serverInstantiateSceneFile(file,serverWorldData,isLevelEditor); |         serverInstantiateSceneFile(file,serverWorldData); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Loads a scene file on the server |      * Loads a scene file on the server | ||||||
|      * @param path The name of the scene in the assets/scenes folder |      * @param path The name of the scene in the assets/scenes folder | ||||||
|      */ |      */ | ||||||
|     public static void serverInstantiateAssetSceneFile(String sceneName, ServerWorldData serverWorldData, boolean isLevelEditor){ |     public static void serverInstantiateAssetSceneFile(String sceneName, ServerWorldData serverWorldData){ | ||||||
|         //load scene file |         //load scene file | ||||||
|         String sanitizedPath = FileUtils.sanitizeFilePath("/Scenes/" + sceneName + "/scene.json"); |         String sanitizedPath = FileUtils.sanitizeFilePath("/Scenes/" + sceneName + "/scene.json"); | ||||||
|         SceneFile file = FileUtils.loadObjectFromAssetPath(sanitizedPath, SceneFile.class); |         SceneFile file = FileUtils.loadObjectFromAssetPath(sanitizedPath, SceneFile.class); | ||||||
|         //instantiate scene data |         //instantiate scene data | ||||||
|         serverInstantiateSceneFile(file,serverWorldData,isLevelEditor); |         serverInstantiateSceneFile(file,serverWorldData); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
| @ -47,7 +47,7 @@ public class SceneLoader { | |||||||
|      * @param path The path in the assets directory to a scene file |      * @param path The path in the assets directory to a scene file | ||||||
|      * @param isSave if true, will try to load scene from save file instead of asset file |      * @param isSave if true, will try to load scene from save file instead of asset file | ||||||
|      */ |      */ | ||||||
|     private static void serverInstantiateSceneFile(SceneFile file, ServerWorldData serverWorldData, boolean isLevelEditor){ |     private static void serverInstantiateSceneFile(SceneFile file, ServerWorldData serverWorldData){ | ||||||
| 
 | 
 | ||||||
|         // |         // | ||||||
|         //Content manager |         //Content manager | ||||||
| @ -103,9 +103,6 @@ public class SceneLoader { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         //load scripts |         //load scripts | ||||||
|         if(!isLevelEditor && file.getInitScriptPath() != null){ |  | ||||||
|             Globals.scriptEngine.initScene(file.getInitScriptPath()); |  | ||||||
|         } |  | ||||||
|         //TODO: integrate scripts for client side of scenes |         //TODO: integrate scripts for client side of scenes | ||||||
|         // for(String scriptPath : file.getScriptPaths()){ |         // for(String scriptPath : file.getScriptPaths()){ | ||||||
|         //     Globals.scriptEngine.loadScript(scriptPath); |         //     Globals.scriptEngine.loadScript(scriptPath); | ||||||
|  | |||||||
| @ -59,7 +59,7 @@ public class MenuGenerators { | |||||||
|                         serverThread.start(); |                         serverThread.start(); | ||||||
|                         clientThread.start(); |                         clientThread.start(); | ||||||
|                     } else { |                     } else { | ||||||
|                         SaveUtils.loadSave(saveName.toLowerCase(), false); |                         SaveUtils.loadSave(saveName.toLowerCase()); | ||||||
|                         WindowUtils.replaceMainMenuContents(MenuGenerators.createSaveCreationMenu()); |                         WindowUtils.replaceMainMenuContents(MenuGenerators.createSaveCreationMenu()); | ||||||
|                     } |                     } | ||||||
|                     return false; |                     return false; | ||||||
|  | |||||||
| @ -179,11 +179,6 @@ public class MenuGeneratorsLevelEditor { | |||||||
|                 }, DEFAULT_GRID_SIZE / (float)GriddedDataCellManager.MAX_GRID_SIZE) |                 }, DEFAULT_GRID_SIZE / (float)GriddedDataCellManager.MAX_GRID_SIZE) | ||||||
|             ); |             ); | ||||||
|             sceneFile.getRealmDescriptor().setGriddedRealmSize(DEFAULT_GRID_SIZE); |             sceneFile.getRealmDescriptor().setGriddedRealmSize(DEFAULT_GRID_SIZE); | ||||||
| 
 |  | ||||||
|             griddedRealmControls.addChild(InputMacros.createToggle("Create Scene File", false, (ValueChangeEvent event) -> { |  | ||||||
|                 sceneFile.setCreateSaveInstance(event.getAsBoolean()); |  | ||||||
|                 System.out.println(sceneFile.getCreateSaveInstance()); |  | ||||||
|             })); |  | ||||||
|         } |         } | ||||||
|         rVal.addChild(griddedRealmControls); |         rVal.addChild(griddedRealmControls); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -191,7 +191,7 @@ public class ToggleInput extends StandardDrawableElement implements ClickableEle | |||||||
|             } else { |             } else { | ||||||
|                 Globals.elementManager.focusElement(this); |                 Globals.elementManager.focusElement(this); | ||||||
|                 this.value = !this.value; |                 this.value = !this.value; | ||||||
|                 Globals.elementManager.fireEventNoPosition(new ValueChangeEvent(this.value), this); |                 Globals.elementManager.fireEventNoPosition(new ValueChangeEvent(absoluteX), this); | ||||||
|                 propagate = false; |                 propagate = false; | ||||||
|             } |             } | ||||||
|         } else if(event instanceof ValueChangeEvent){ |         } else if(event instanceof ValueChangeEvent){ | ||||||
|  | |||||||
| @ -119,9 +119,6 @@ public class InputMacros { | |||||||
|         //the actual input |         //the actual input | ||||||
|         ToggleInput toggleInput = ToggleInput.createToggleInput(); |         ToggleInput toggleInput = ToggleInput.createToggleInput(); | ||||||
|         toggleInput.setValue(defaultValue); |         toggleInput.setValue(defaultValue); | ||||||
|         toggleInput.setOnValueChangeCallback(new ValueChangeEventCallback() {public void execute(ValueChangeEvent event) { |  | ||||||
|             onChange.accept(event); |  | ||||||
|         }}); |  | ||||||
|         rVal.addChild(toggleInput); |         rVal.addChild(toggleInput); | ||||||
| 
 | 
 | ||||||
|         return rVal; |         return rVal; | ||||||
|  | |||||||
| @ -42,9 +42,6 @@ public class ScriptEngine { | |||||||
|     //the object that contains all host values accessible to javascript land |     //the object that contains all host values accessible to javascript land | ||||||
|     Value hostObject; |     Value hostObject; | ||||||
| 
 | 
 | ||||||
|     //the engine object |  | ||||||
|     Value engineObject; |  | ||||||
| 
 |  | ||||||
|     //The files that are loaded on init to bootstrap the script engine |     //The files that are loaded on init to bootstrap the script engine | ||||||
|     static final String[] filesToLoadOnInit = new String[]{ |     static final String[] filesToLoadOnInit = new String[]{ | ||||||
|         //polyfills |         //polyfills | ||||||
| @ -59,6 +56,12 @@ public class ScriptEngine { | |||||||
|         "Scripts/compiler/host_access.js", |         "Scripts/compiler/host_access.js", | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  |     //folders that should be loaded once we have bootstrapped the compiler | ||||||
|  |     static final String[] foldersToLoadOnInit = new String[]{ | ||||||
|  |         "Scripts/engine", | ||||||
|  |         "Scripts/client", | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|     //The classes that will be provided to the scripting engine |     //The classes that will be provided to the scripting engine | ||||||
|     //https://stackoverflow.com/a/65942034 |     //https://stackoverflow.com/a/65942034 | ||||||
|     static final Object[][] staticClasses = new Object[][]{ |     static final Object[][] staticClasses = new Object[][]{ | ||||||
| @ -100,15 +103,15 @@ public class ScriptEngine { | |||||||
|         defineHostMembers(); |         defineHostMembers(); | ||||||
| 
 | 
 | ||||||
|         //register engine files |         //register engine files | ||||||
|         registerFile("/Scripts/engine/engine-init.ts"); |         for(String folderToRegister : foldersToLoadOnInit){ | ||||||
|  |             registerScriptDirectory(folderToRegister,FileUtils.getAssetFile(folderToRegister)); | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         //compile |         //compile | ||||||
|         compile(); |         compile(); | ||||||
| 
 | 
 | ||||||
|         //run script for engine init |         //run script for engine init | ||||||
|         requireModule("/Scripts/engine/engine-init.ts"); |         requireModule("/Scripts/engine/engine-init.ts"); | ||||||
|         //get the engine object |  | ||||||
|         engineObject = topLevelValue.getMember("REQUIRE_CACHE").getMember("/Scripts/engine/engine-init.js").getMember("exports").getMember("engine"); |  | ||||||
|         invokeModuleFunction("/Scripts/engine/engine-init.ts","ENGINE_onInit"); |         invokeModuleFunction("/Scripts/engine/engine-init.ts","ENGINE_onInit"); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -157,7 +160,6 @@ public class ScriptEngine { | |||||||
|         return topLevelValue.removeMember(valueName); |         return topLevelValue.removeMember(valueName); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Deprecated |  | ||||||
|     /** |     /** | ||||||
|      * Reads the scripts directory |      * Reads the scripts directory | ||||||
|      * @param path The  |      * @param path The  | ||||||
| @ -184,7 +186,7 @@ public class ScriptEngine { | |||||||
|      * Loads a script from disk |      * Loads a script from disk | ||||||
|      * @param path The path to the script file |      * @param path The path to the script file | ||||||
|      */ |      */ | ||||||
|     void loadDependency(String path){ |     public void loadDependency(String path){ | ||||||
|         String content; |         String content; | ||||||
|         Source source = null; |         Source source = null; | ||||||
|         try { |         try { | ||||||
| @ -203,59 +205,44 @@ public class ScriptEngine { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Runs a script | ||||||
|  |      * @param path The filepath of the script | ||||||
|  |      */ | ||||||
|  |     public void runScript(String path){ | ||||||
|  |         invokeFunction("COMPILER_runFile", path); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * Prints the content of a file |      * Prints the content of a file | ||||||
|      * @param path The filepath of the script |      * @param path The filepath of the script | ||||||
|      */ |      */ | ||||||
|     public void printScriptSource(String path){ |     public void printScriptSource(String path){ | ||||||
|         invokeMemberFunction("COMPILER", "printSource", path); |         invokeFunction("COMPILER_printSource", path); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Registers a file with the scripting engine to be compiled into the full binary |      * Registers a file with the scripting engine to be compiled into the full binary | ||||||
|      * @param path The path to the script file |      * @param path The path to the script file | ||||||
|      */ |      */ | ||||||
|     private boolean registerFile(String path){ |     private void registerFile(String path){ | ||||||
|         String content; |         String content; | ||||||
|         try { |         try { | ||||||
|             content = FileUtils.getAssetFileAsString(path); |             content = FileUtils.getAssetFileAsString(path); | ||||||
|             sourceMap.put(path,Source.create("js",content)); |             sourceMap.put(path,Source.create("js",content)); | ||||||
|             Value dependentFilesValue = invokeMemberFunction("COMPILER", "registerFile",path,content); |             invokeFunction("COMPILER_registerFile",path,content); | ||||||
|             // |  | ||||||
|             //register dependent files if necessary |  | ||||||
|             long dependentFilesCount = dependentFilesValue.getArraySize(); |  | ||||||
|             if(dependentFilesCount > 0){ |  | ||||||
|                 for(int i = 0; i < dependentFilesCount; i++){ |  | ||||||
|                     String dependentFilePath = dependentFilesValue.getArrayElement(i).asString(); |  | ||||||
|                     LoggerInterface.loggerScripts.INFO("[HOST - Script Engine] Should register file " + dependentFilePath); |  | ||||||
|                     registerFile(dependentFilePath); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } catch (IOException e) { |         } catch (IOException e) { | ||||||
|             LoggerInterface.loggerScripts.ERROR("FAILED TO LOAD SCRIPT", e); |             LoggerInterface.loggerScripts.ERROR("FAILED TO LOAD SCRIPT", e); | ||||||
|             return false; |  | ||||||
|         } |         } | ||||||
|         return true; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * Compiles the project |      * Compiles the project | ||||||
|      */ |      */ | ||||||
|     private void compile(){ |     private void compile(){ | ||||||
|         invokeMemberFunction("COMPILER", "run"); |         invokeFunction("COMPILER_run"); | ||||||
|     } |         Value compiledCode = topLevelValue.getMember("COMPILER_emitted_value"); | ||||||
| 
 |         context.eval("js",compiledCode.asString()); | ||||||
|     /** |  | ||||||
|      * Initializes a scene script |  | ||||||
|      * @param scenePath The scene's init script path |  | ||||||
|      */ |  | ||||||
|     public void initScene(String scenePath){ |  | ||||||
|         //add files to virtual filesystem in script engine |  | ||||||
|         registerFile(scenePath); |  | ||||||
|         //load scene from javascript side |  | ||||||
|         Value sceneLoader = this.engineObject.getMember("sceneLoader"); |  | ||||||
|         Value loadFunc = sceneLoader.getMember("loadScene"); |  | ||||||
|         loadFunc.execute(scenePath); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -265,7 +252,6 @@ public class ScriptEngine { | |||||||
|      * @param args The arguments |      * @param args The arguments | ||||||
|      */ |      */ | ||||||
|     public Value invokeFunction(String functionName, Object... args){ |     public Value invokeFunction(String functionName, Object... args){ | ||||||
|         LoggerInterface.loggerScripts.DEBUG("Host execute: " + functionName); |  | ||||||
|         Value function = topLevelValue.getMember(functionName); |         Value function = topLevelValue.getMember(functionName); | ||||||
|         if(function != null){ |         if(function != null){ | ||||||
|             return function.execute(args); |             return function.execute(args); | ||||||
| @ -275,25 +261,6 @@ public class ScriptEngine { | |||||||
|         return null; |         return null; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |  | ||||||
|      * Calls a function on a child of the top level member |  | ||||||
|      * @param memberName The name of the child |  | ||||||
|      * @param functionName The name of the function |  | ||||||
|      * @param args The arguments for the function |  | ||||||
|      * @return The value from the function call |  | ||||||
|      */ |  | ||||||
|     public Value invokeMemberFunction(String memberName, String functionName, Object ... args){ |  | ||||||
|         LoggerInterface.loggerScripts.DEBUG("Host execute: " + functionName); |  | ||||||
|         Value childMember = topLevelValue.getMember(memberName); |  | ||||||
|         Value function = childMember.getMember(functionName); |  | ||||||
|         if(function != null){ |  | ||||||
|             return function.execute(args); |  | ||||||
|         } else { |  | ||||||
|             LoggerInterface.loggerScripts.WARNING("Failed to invoke function " + functionName); |  | ||||||
|         } |  | ||||||
|         return null; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |     /** | ||||||
|      * Invokes a function defined in a file |      * Invokes a function defined in a file | ||||||
|      * @param filePath The file the function is defined in |      * @param filePath The file the function is defined in | ||||||
| @ -331,8 +298,6 @@ public class ScriptEngine { | |||||||
|         for(Object[] currentClass : staticClasses){ |         for(Object[] currentClass : staticClasses){ | ||||||
|             classes.putMember((String)currentClass[0], currentClass[1]); |             classes.putMember((String)currentClass[0], currentClass[1]); | ||||||
|         } |         } | ||||||
|         //give access to script engine instance |  | ||||||
|         hostObject.putMember("scriptEngine", this); |  | ||||||
|     } |     } | ||||||
|      |      | ||||||
|      |      | ||||||
|  | |||||||
| @ -174,7 +174,7 @@ public class SaveUtils { | |||||||
|      * @param saveName The name of the save |      * @param saveName The name of the save | ||||||
|      * @return true always |      * @return true always | ||||||
|      */ |      */ | ||||||
|     public static boolean loadSave(String saveName, boolean isLevelEditor){ |     public static boolean loadSave(String saveName){ | ||||||
|         String dirPath = deriveSaveDirectoryPath(saveName); |         String dirPath = deriveSaveDirectoryPath(saveName); | ||||||
| 
 | 
 | ||||||
|         //load save file |         //load save file | ||||||
| @ -200,11 +200,11 @@ public class SaveUtils { | |||||||
|         if(FileUtils.checkSavePathExists(saveName, "/scene.json")){ |         if(FileUtils.checkSavePathExists(saveName, "/scene.json")){ | ||||||
|             //load from save itself |             //load from save itself | ||||||
|             LoggerInterface.loggerEngine.INFO("Load scene data from save " + saveName); |             LoggerInterface.loggerEngine.INFO("Load scene data from save " + saveName); | ||||||
|             SceneLoader.serverInstantiateSaveSceneFile(saveName, serverWorldData, isLevelEditor); |             SceneLoader.serverInstantiateSaveSceneFile(saveName, serverWorldData); | ||||||
|         } else if(FileUtils.getAssetFile("/Scenes/" + saveName + "/scene.json").exists()){ |         } else if(FileUtils.checkFileExists("/Scenes/" + saveName)){ | ||||||
|             //load from defined scene |             //load from defined scene | ||||||
|             LoggerInterface.loggerEngine.INFO("Load scene data from scene " + saveName); |             LoggerInterface.loggerEngine.INFO("Load scene data from scene " + saveName); | ||||||
|             SceneLoader.serverInstantiateAssetSceneFile(saveName, serverWorldData, isLevelEditor); |             SceneLoader.serverInstantiateAssetSceneFile(saveName, serverWorldData); | ||||||
|         } else { |         } else { | ||||||
|             //The scene is neither defined in the save itself nor in the assets scene files |             //The scene is neither defined in the save itself nor in the assets scene files | ||||||
|             throw new IllegalStateException("Trying to load a save that does not contain a scene!"); |             throw new IllegalStateException("Trying to load a save that does not contain a scene!"); | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user