script engine work
This commit is contained in:
parent
df4fe45dd5
commit
e5a187ce19
5
.gitignore
vendored
5
.gitignore
vendored
@ -44,4 +44,7 @@
|
||||
/docs/DoxygenWarningLog.txt
|
||||
|
||||
#imgui local layout
|
||||
/imgui.ini
|
||||
/imgui.ini
|
||||
|
||||
#script engine related
|
||||
/assets/Scripts/compiler/typescript.js
|
||||
|
||||
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@ -4,5 +4,7 @@
|
||||
"**/.git/objects/**": true,
|
||||
"**/node_modules/**": true
|
||||
},
|
||||
"java.jdt.ls.vmargs": "-XX:+UseParallelGC -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -Dsun.zip.disableMemoryMapping=true -Xmx2G -Xms100m -Xlog:disable"
|
||||
"java.jdt.ls.vmargs": "-XX:+UseParallelGC -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -Dsun.zip.disableMemoryMapping=true -Xmx2G -Xms100m -Xlog:disable",
|
||||
"javascript.preferences.importModuleSpecifier": "non-relative",
|
||||
"typescript.preferences.importModuleSpecifier": "non-relative"
|
||||
}
|
||||
113
assets/Scripts/compiler/compiler.js
Normal file
113
assets/Scripts/compiler/compiler.js
Normal file
@ -0,0 +1,113 @@
|
||||
|
||||
/**
|
||||
* The map of all source files to their content and compiled value
|
||||
*/
|
||||
let COMPILER_fileMap = { }
|
||||
|
||||
/**
|
||||
* The compiled program
|
||||
*/
|
||||
let COMPILER_emitted_value = ''
|
||||
|
||||
|
||||
/**
|
||||
* Registers a file with the compiler
|
||||
* @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 callback invoked when the compiler host tries to read a file
|
||||
* @param {*} fileName The name of the file
|
||||
* @param {*} languageVersion The language version
|
||||
* @returns The file if it exists, null otherwise
|
||||
*/
|
||||
const COMPILER_getSourceFile = (fileName, languageVersion) => {
|
||||
if(!!COMPILER_fileMap[fileName]){
|
||||
return COMPILER_fileMap[fileName].compiled
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs the compiler host
|
||||
* https://www.typescriptlang.org/tsconfig/#compilerOptions
|
||||
*/
|
||||
const COMPILER_customCompilerHost = {
|
||||
getSourceFile: COMPILER_getSourceFile,
|
||||
writeFile: (fileName, data) => {
|
||||
let normalizedFilePath = FILE_RESOLUTION_getFilePath(fileName)
|
||||
loggerScripts.INFO("EMIT FILE " + normalizedFilePath)
|
||||
let finalData =
|
||||
"let exports = { }\n" +
|
||||
data + "\n" +
|
||||
"return exports"
|
||||
// COMPILER_emitted_value = data
|
||||
COMPILER_fileMap[normalizedFilePath] = {
|
||||
content: data, //to be eval'd from top level
|
||||
moduleContent: finalData, //to be eval'd from require()
|
||||
}
|
||||
},
|
||||
getDefaultLibFileName: () => "lib.d.ts",
|
||||
useCaseSensitiveFileNames: () => false,
|
||||
getCanonicalFileName: filename => filename,
|
||||
getCurrentDirectory: () => "",
|
||||
getNewLine: () => "\n",
|
||||
getDirectories: () => [],
|
||||
fileExists: () => true,
|
||||
readFile: () => ""
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
loggerScripts.WARNING('FAILED TO RESOLVE FILE ' + normalizedFilePath)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
loggerScripts.WARNING('FAILED TO RESOLVE FILE ' + normalizedFilePath)
|
||||
}
|
||||
}
|
||||
23
assets/Scripts/compiler/file_resolution.js
Normal file
23
assets/Scripts/compiler/file_resolution.js
Normal file
@ -0,0 +1,23 @@
|
||||
|
||||
/**
|
||||
* Normalizes a file path
|
||||
* @param {*} rawFilePath The raw file path
|
||||
* @returns The normalized file path
|
||||
*/
|
||||
const FILE_RESOLUTION_getFilePath = (rawFilePath, isJavascript = true) => {
|
||||
let fileName = rawFilePath
|
||||
if(isJavascript && fileName.includes('.ts')){
|
||||
fileName = fileName.replace('.ts','.js')
|
||||
}
|
||||
if(fileName.startsWith('/Scripts')){
|
||||
fileName = fileName.replace('/Scripts','')
|
||||
}
|
||||
if(fileName.startsWith('Scripts/')){
|
||||
fileName = fileName.replace('Scripts/','/')
|
||||
}
|
||||
if(isJavascript && !fileName.endsWith(".js")){
|
||||
fileName = fileName + ".js"
|
||||
}
|
||||
return fileName
|
||||
}
|
||||
|
||||
1
assets/Scripts/compiler/get_typescript.sh
Normal file
1
assets/Scripts/compiler/get_typescript.sh
Normal file
@ -0,0 +1 @@
|
||||
wget -O typescript.js https://unpkg.com/typescript@latest/lib/typescript.js
|
||||
9
assets/Scripts/compiler/host_access.js
Normal file
9
assets/Scripts/compiler/host_access.js
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
/**
|
||||
* The host context that contains the core engine functions
|
||||
*/
|
||||
export let HOST = {
|
||||
classes: { }, //the classes available to the script engine
|
||||
singletons: { }, //the singletons available to the script engine
|
||||
}
|
||||
|
||||
36
assets/Scripts/compiler/require_polyfill.js
Normal file
36
assets/Scripts/compiler/require_polyfill.js
Normal file
@ -0,0 +1,36 @@
|
||||
|
||||
|
||||
/**
|
||||
* Caches loaded modules
|
||||
*/
|
||||
let REQUIRE_CACHE = { }
|
||||
|
||||
/**
|
||||
* Used if the module is directly executed instead of being require'd for some reason
|
||||
*/
|
||||
let exports = { }
|
||||
|
||||
/**
|
||||
* Imports a module
|
||||
* @param {*} path The path of the module
|
||||
* @param {*} cwd The current working directory
|
||||
*/
|
||||
const require = (path) => {
|
||||
let normalizedFilePath = FILE_RESOLUTION_getFilePath(path)
|
||||
if(REQUIRE_CACHE[path]){
|
||||
return REQUIRE_CACHE[normalizedFilePath].exports
|
||||
} else if(!!COMPILER_fileMap[normalizedFilePath]?.content) {
|
||||
const code = COMPILER_fileMap[normalizedFilePath].moduleContent
|
||||
let exports = new Function(code)()
|
||||
//create module object
|
||||
const module = {
|
||||
exports: exports,
|
||||
exportedValues: Object.keys(exports),
|
||||
}
|
||||
REQUIRE_CACHE[normalizedFilePath] = module
|
||||
loggerScripts.INFO("[require] CREATE MODULE " + normalizedFilePath)
|
||||
return module.exports
|
||||
} else {
|
||||
loggerScripts.WARNING("FAILED TO REQUIRE FILE " + normalizedFilePath)
|
||||
}
|
||||
}
|
||||
7
assets/Scripts/engine/engine-init.ts
Normal file
7
assets/Scripts/engine/engine-init.ts
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
/**
|
||||
* Called when the script engine first initializes
|
||||
*/
|
||||
export const ENGINE_onInit = () => {
|
||||
console.log('Script Engine Init')
|
||||
}
|
||||
9
assets/Scripts/engine/engine-interface.ts
Normal file
9
assets/Scripts/engine/engine-interface.ts
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
|
||||
/**
|
||||
* The host context that contains all core engine functions
|
||||
*/
|
||||
export interface Host {
|
||||
classes: any, //the host's view of the scripting engine
|
||||
singletons: any, //the singletons available to the script engine
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
console.log("test")
|
||||
@ -4,4 +4,5 @@
|
||||
- @subpage biomeideas
|
||||
- @subpage largelocationideas
|
||||
- @subpage macrolocationideas
|
||||
- @subpage smalllocations
|
||||
- @subpage smalllocations
|
||||
- @subpage minidungeons
|
||||
4
docs/src/highlevel-design/locations/minidungeons.md
Normal file
4
docs/src/highlevel-design/locations/minidungeons.md
Normal file
@ -0,0 +1,4 @@
|
||||
@page minidungeons Mini Dungeons
|
||||
|
||||
In certain levels, you can find premade characters that can join your party.
|
||||
|
||||
@ -21,7 +21,6 @@ Redo hitboxes to have capsules and also chaining between frames (but not between
|
||||
- Introduce block hitbox (blockbox) type
|
||||
- Sour spot, sweet spot for damage hitboxes and hurtboxes
|
||||
Enemy AI
|
||||
better scaffolding for scriptig engine with hooks for equipping items, spawning entities, pausing/resuming play, etc
|
||||
Ability for private realms to have time start/stop based on the player's feedback <-- sync this up to tutorial ui via script
|
||||
Scene Message Service
|
||||
- Can send arbitrary events and messages
|
||||
|
||||
@ -406,6 +406,8 @@ Audio
|
||||
- Sword Hit Metal
|
||||
- Sword Hit Flesh
|
||||
|
||||
(06/02/2024)
|
||||
better scaffolding for scripting engine with hooks for equipping items, spawning entities, pausing/resuming play, etc
|
||||
|
||||
# TODO
|
||||
|
||||
@ -413,7 +415,7 @@ Audio
|
||||
BIG BIG BIG BIG IMMEDIATE TO DO:
|
||||
always enforce opengl interface across all opengl calls jesus christ the bone uniform bug was impossible
|
||||
|
||||
|
||||
Fix not all grass tiles update when updating a nearby voxel (ie it doesn't go into negative coordinates to scan for foliage updates)
|
||||
|
||||
|
||||
|
||||
|
||||
@ -444,7 +444,6 @@ public class Globals {
|
||||
elementManager = new ElementManager();
|
||||
//script engine
|
||||
scriptEngine = new ScriptEngine();
|
||||
scriptEngine.init();
|
||||
//ai manager
|
||||
aiManager = new AIManager();
|
||||
//realm & data cell manager
|
||||
|
||||
@ -76,6 +76,9 @@ public class Main {
|
||||
//init global variables
|
||||
Globals.initGlobals();
|
||||
|
||||
//init scripting engine
|
||||
Globals.scriptEngine.init();
|
||||
|
||||
//controls
|
||||
if(Globals.RUN_CLIENT){
|
||||
initControlHandler();
|
||||
|
||||
@ -56,10 +56,11 @@ public class SceneLoader {
|
||||
}
|
||||
}
|
||||
//load scripts
|
||||
for(String scriptPath : file.getScriptPaths()){
|
||||
Globals.scriptEngine.loadScript(scriptPath);
|
||||
}
|
||||
Globals.scriptEngine.runScript(file.getInitScriptPath());
|
||||
//TODO: integrate scripts for client side of scenes
|
||||
// for(String scriptPath : file.getScriptPaths()){
|
||||
// Globals.scriptEngine.loadScript(scriptPath);
|
||||
// }
|
||||
// Globals.scriptEngine.runScript(file.getInitScriptPath());
|
||||
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package electrosphere.logger;
|
||||
|
||||
import org.graalvm.polyglot.HostAccess.Export;
|
||||
|
||||
/**
|
||||
* A channel for logging messages
|
||||
*/
|
||||
@ -56,6 +58,7 @@ public class Logger {
|
||||
* This should be used for messages that would have interest to someone running a server (ie specific network messages, account creation, etc)
|
||||
* @param message The message to report
|
||||
*/
|
||||
@Export
|
||||
public void INFO(String message){
|
||||
if(level == LogLevel.LOOP_DEBUG || level == LogLevel.DEBUG || level == LogLevel.INFO){
|
||||
System.out.println(message);
|
||||
@ -68,6 +71,7 @@ public class Logger {
|
||||
* This should be used for reporting events that happen in the engine that are concerning but don't mean the engine has failed to execute (ie a texture failed to load)
|
||||
* @param message The message to report
|
||||
*/
|
||||
@Export
|
||||
public void WARNING(String message){
|
||||
if(level == LogLevel.LOOP_DEBUG || level == LogLevel.DEBUG || level == LogLevel.INFO || level == LogLevel.WARNING){
|
||||
System.out.println(message);
|
||||
|
||||
@ -20,6 +20,7 @@ public class LoggerInterface {
|
||||
public static Logger loggerDB;
|
||||
public static Logger loggerAudio;
|
||||
public static Logger loggerUI;
|
||||
public static Logger loggerScripts;
|
||||
|
||||
/**
|
||||
* Initializes all logic objects
|
||||
@ -35,6 +36,7 @@ public class LoggerInterface {
|
||||
loggerDB = new Logger(LogLevel.WARNING);
|
||||
loggerAudio = new Logger(LogLevel.WARNING);
|
||||
loggerUI = new Logger(LogLevel.WARNING);
|
||||
loggerScripts = new Logger(LogLevel.WARNING);
|
||||
loggerStartup.INFO("Initialized loggers");
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,11 +7,14 @@ import java.util.Map;
|
||||
|
||||
import org.graalvm.polyglot.Context;
|
||||
import org.graalvm.polyglot.Engine;
|
||||
import org.graalvm.polyglot.PolyglotException;
|
||||
import org.graalvm.polyglot.Source;
|
||||
import org.graalvm.polyglot.Value;
|
||||
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
import electrosphere.util.FileUtils;
|
||||
import electrosphere.util.MathUtils;
|
||||
|
||||
/**
|
||||
* Interface for executing scripts in the game engine
|
||||
@ -25,7 +28,37 @@ public class ScriptEngine {
|
||||
Map<String,Source> sourceMap;
|
||||
|
||||
//the javascript object that stores values
|
||||
Value jsBindingsObject;
|
||||
Value topLevelValue;
|
||||
|
||||
//the object that contains all host values accessible to javascript land
|
||||
Value hostObject;
|
||||
|
||||
//The files that are loaded on init to bootstrap the script engine
|
||||
static final String[] filesToLoadOnInit = new String[]{
|
||||
//polyfills
|
||||
"Scripts/compiler/require_polyfill.js",
|
||||
|
||||
//main typescript engine
|
||||
"Scripts/compiler/typescript.js",
|
||||
|
||||
//compiler and utilities
|
||||
"Scripts/compiler/file_resolution.js",
|
||||
"Scripts/compiler/compiler.js",
|
||||
"Scripts/compiler/host_access.js",
|
||||
};
|
||||
|
||||
//The classes that will be provided to the scripting engine
|
||||
//https://stackoverflow.com/a/65942034
|
||||
static final Object[][] staticClasses = new Object[][]{
|
||||
{"mathUtils",MathUtils.class},
|
||||
};
|
||||
|
||||
//singletons from the host that are provided to the javascript context
|
||||
static final Object[][] hostSingletops = new Object[][]{
|
||||
{"timekeeper",Globals.timekeeper},
|
||||
{"currentPlayer",Globals.clientPlayer},
|
||||
{"loggerScripts",LoggerInterface.loggerScripts},
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes the engine
|
||||
@ -36,11 +69,42 @@ public class ScriptEngine {
|
||||
//create engine with flag to disable warning
|
||||
Engine engine = Engine.newBuilder().option("engine.WarnInterpreterOnly", "false").build();
|
||||
//create context
|
||||
context = Context.newBuilder("js").engine(engine).build();
|
||||
//read scripts into source map
|
||||
readScriptsDirectory("/src/main/sql", FileUtils.getAssetFile("/src/main/sql"));
|
||||
context = Context.newBuilder("js")
|
||||
.allowNativeAccess(false)
|
||||
.engine(engine)
|
||||
.build();
|
||||
//save the js bindings object
|
||||
jsBindingsObject = context.getBindings("js");
|
||||
topLevelValue = context.getBindings("js");
|
||||
|
||||
//put host members into environment
|
||||
putTopLevelValue("loggerScripts",LoggerInterface.loggerScripts);
|
||||
|
||||
//load all files required to start the engine
|
||||
for(String fileToLoad : filesToLoadOnInit){
|
||||
loadDependency(fileToLoad);
|
||||
}
|
||||
|
||||
//define host members
|
||||
defineHostMembers();
|
||||
|
||||
//register engine files
|
||||
registerScriptDirectory("Scripts/engine",FileUtils.getAssetFile("Scripts/engine"));
|
||||
|
||||
//compile
|
||||
compile();
|
||||
|
||||
//run script for engine init
|
||||
requireModule("/Scripts/engine/engine-init.ts");
|
||||
invokeModuleFunction("/Scripts/engine/engine-init.ts","ENGINE_onInit");
|
||||
|
||||
|
||||
//call the engine initialization function
|
||||
// invokeFunction("ENGINE_onInit");
|
||||
|
||||
System.exit(0);
|
||||
|
||||
//read scripts into source map
|
||||
// readScriptsDirectory("/src/main/sql", FileUtils.getAssetFile("/src/main/sql"));
|
||||
//create bindings
|
||||
// try {
|
||||
// String content = FileUtils.getAssetFileAsString("/Scripts/test.js");
|
||||
@ -59,7 +123,7 @@ public class ScriptEngine {
|
||||
* @param value The value that is stored at that variable
|
||||
*/
|
||||
public void putTopLevelValue(String valueName, Object value){
|
||||
jsBindingsObject.putMember(valueName, value);
|
||||
topLevelValue.putMember(valueName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -68,7 +132,16 @@ public class ScriptEngine {
|
||||
* @return The value of the variable
|
||||
*/
|
||||
public Value getTopLevelValue(String valueName){
|
||||
return jsBindingsObject.getMember(valueName);
|
||||
return topLevelValue.getMember(valueName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a top level member from the javascript context
|
||||
* @param valueName The name of the top level member
|
||||
* @return true if successfully removed, false otherwise
|
||||
*/
|
||||
public boolean removeTopLevelValue(String valueName){
|
||||
return topLevelValue.removeMember(valueName);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -76,17 +149,18 @@ public class ScriptEngine {
|
||||
* @param path The
|
||||
* @param directory
|
||||
*/
|
||||
void readScriptsDirectory(String path, File directory){
|
||||
void registerScriptDirectory(String path, File directory){
|
||||
if(directory.exists() && directory.isDirectory()){
|
||||
File[] children = directory.listFiles();
|
||||
for(File childFile : children){
|
||||
String qualifiedName = path + "/" + childFile.getName();
|
||||
if(childFile.isDirectory()){
|
||||
readScriptsDirectory(qualifiedName,childFile);
|
||||
registerScriptDirectory(qualifiedName,childFile);
|
||||
} else {
|
||||
//add to source map
|
||||
String content = FileUtils.readFileToString(childFile);
|
||||
sourceMap.put(qualifiedName,Source.create("js",content));
|
||||
registerFile(qualifiedName);
|
||||
// String content = FileUtils.readFileToString(childFile);
|
||||
// sourceMap.put(qualifiedName,Source.create("js",content));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -96,15 +170,17 @@ public class ScriptEngine {
|
||||
* Loads a script from disk
|
||||
* @param path The path to the script file
|
||||
*/
|
||||
public void loadScript(String path){
|
||||
public void loadDependency(String path){
|
||||
String content;
|
||||
try {
|
||||
content = FileUtils.getAssetFileAsString(path);
|
||||
sourceMap.put(path,Source.create("js",content));
|
||||
context.eval(sourceMap.get(path));
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
LoggerInterface.loggerScripts.ERROR("FAILED TO LOAD SCRIPT", e);
|
||||
} catch (PolyglotException e){
|
||||
LoggerInterface.loggerScripts.ERROR("Script error", e);
|
||||
e.printStackTrace();
|
||||
LoggerInterface.loggerGameLogic.ERROR("FAILED TO LOAD SCRIPT", e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,12 +189,96 @@ public class ScriptEngine {
|
||||
* @param path The filepath of the script
|
||||
*/
|
||||
public void runScript(String path){
|
||||
Source source = sourceMap.get(path);
|
||||
if(source != null){
|
||||
context.eval(source);
|
||||
invokeFunction("COMPILER_runFile", path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the content of a file
|
||||
* @param path The filepath of the script
|
||||
*/
|
||||
public void printScriptSource(String path){
|
||||
invokeFunction("COMPILER_printSource", path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a file with the scripting engine to be compiled into the full binary
|
||||
* @param path The path to the script file
|
||||
*/
|
||||
private void registerFile(String path){
|
||||
String content;
|
||||
try {
|
||||
content = FileUtils.getAssetFileAsString(path);
|
||||
sourceMap.put(path,Source.create("js",content));
|
||||
invokeFunction("COMPILER_registerFile",path,content);
|
||||
} catch (IOException e) {
|
||||
LoggerInterface.loggerScripts.ERROR("FAILED TO LOAD SCRIPT", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the project
|
||||
*/
|
||||
private void compile(){
|
||||
invokeFunction("COMPILER_run");
|
||||
Value compiledCode = topLevelValue.getMember("COMPILER_emitted_value");
|
||||
context.eval("js",compiledCode.asString());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calls a function defined in the global scope with the arguments provided
|
||||
* @param functionName The function name
|
||||
* @param args The arguments
|
||||
*/
|
||||
public Value invokeFunction(String functionName, Object... args){
|
||||
Value function = topLevelValue.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
|
||||
* @param filePath The file the function is defined in
|
||||
* @param functionName The function's name
|
||||
* @param args The args to pass into the function
|
||||
*/
|
||||
public void invokeModuleFunction(String filePath, String functionName, Object ... args){
|
||||
Value filePathRaw = invokeFunction("FILE_RESOLUTION_getFilePath",filePath);
|
||||
Value requireCache = topLevelValue.getMember("REQUIRE_CACHE");
|
||||
Value module = requireCache.getMember(filePathRaw.asString());
|
||||
Value exports = module.getMember("exports");
|
||||
Value function = exports.getMember(functionName);
|
||||
if(function != null && function.canExecute()){
|
||||
function.execute(args);
|
||||
} else {
|
||||
LoggerInterface.loggerScripts.WARNING("Failed to invoke function " + functionName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Requires a module into the global space
|
||||
* @param filePath The filepath of the module
|
||||
*/
|
||||
public void requireModule(String filePath){
|
||||
invokeFunction("require", filePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines host members within javascript context
|
||||
*/
|
||||
private void defineHostMembers(){
|
||||
//remove top level members required for bootstrapping the engine
|
||||
removeTopLevelValue("loggerScripts");
|
||||
//give guest access to static classes
|
||||
Value classes = hostObject.getMember("classes");
|
||||
for(Object[] currentClass : staticClasses){
|
||||
classes.putMember((String)currentClass[0], currentClass[1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
9
tsconfig.json
Normal file
9
tsconfig.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"paths" : {
|
||||
"/*" : [
|
||||
"./assets/Scripts/*"
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user