add support for external modules
This commit is contained in:
parent
b6c60365ab
commit
fe58e511e6
|
@ -1,5 +1,6 @@
|
||||||
add_subdirectory(engine)
|
add_subdirectory(engine)
|
||||||
add_subdirectory(logic)
|
add_subdirectory(logic)
|
||||||
|
add_subdirectory(scripts)
|
||||||
|
|
||||||
add_executable(sc-eng main.cpp)
|
add_executable(sc-eng main.cpp)
|
||||||
target_link_libraries(sc-eng engine logic)
|
target_link_libraries(sc-eng engine logic)
|
||||||
|
|
|
@ -4,30 +4,73 @@
|
||||||
#include "wren/vm/wren_vm.h"
|
#include "wren/vm/wren_vm.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <cstdio>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
void writeOutput(WrenVM *vm, const char *text) {
|
void writeOutput(WrenVM *vm, const char *text) {
|
||||||
std::cout << "wren output:" << text << "\n";
|
std::cout << text;
|
||||||
}
|
}
|
||||||
|
|
||||||
void errorOutput(WrenVM *vm, WrenErrorType type, const char *module, int line, const char *message) {
|
void errorOutput(WrenVM *vm, WrenErrorType type, const char *module, int line, const char *message) {
|
||||||
std::cerr << "wren error [module \"" << module << "\", line " << line << "]: " << message << "\n";
|
if (module != nullptr) {
|
||||||
|
std::cerr << "wren error [module \"" << module << "\", line " << line << "]: " << message << "\n";
|
||||||
|
} else {
|
||||||
|
std::cerr << "wren error: " << message << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char *fileContent(const char *path) {
|
||||||
|
FILE *f = fopen(path, "rb");
|
||||||
|
if (f == NULL) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the file length.
|
||||||
|
fseek(f, 0, SEEK_END);
|
||||||
|
size_t fileLength = ftell(f);
|
||||||
|
rewind(f);
|
||||||
|
|
||||||
|
// Read the file.
|
||||||
|
char *fileContent = (char *)malloc(fileLength + 1);
|
||||||
|
size_t bytesRead = fread(fileContent, sizeof(char), fileLength, f);
|
||||||
|
fclose(f);
|
||||||
|
if (fileLength != bytesRead) {
|
||||||
|
free(fileContent);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
fileContent[fileLength] = '\0';
|
||||||
|
|
||||||
|
return fileContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getPath(const char *name) {
|
||||||
|
std::string root("/Users/ffreling/Code/scripted-engine/src/scripts/");
|
||||||
|
return root + name + ".wren";
|
||||||
|
}
|
||||||
|
|
||||||
|
char *loadModule(WrenVM *vm, const char *name) {
|
||||||
|
std::string path = getPath(name);
|
||||||
|
|
||||||
|
return fileContent(path.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
Logic::Logic(Engine *engine) {
|
Logic::Logic(Engine *engine) {
|
||||||
WrenConfiguration wrenConfig;
|
WrenConfiguration wrenConfig;
|
||||||
wrenInitConfiguration(&wrenConfig);
|
wrenInitConfiguration(&wrenConfig);
|
||||||
|
|
||||||
// Setup user-defined data such as pointer to "global" objects.
|
|
||||||
_bundleData.engine = engine;
|
|
||||||
wrenConfig.userData = &_bundleData;
|
|
||||||
|
|
||||||
wrenConfig.bindForeignMethodFn = &Logic::bindForeignMethod;
|
wrenConfig.bindForeignMethodFn = &Logic::bindForeignMethod;
|
||||||
wrenConfig.writeFn = &writeOutput;
|
wrenConfig.writeFn = &writeOutput;
|
||||||
wrenConfig.errorFn = &errorOutput;
|
wrenConfig.errorFn = &errorOutput;
|
||||||
|
wrenConfig.loadModuleFn = &loadModule;
|
||||||
|
|
||||||
_wrenVm = wrenNewVM(&wrenConfig);
|
_wrenVm = wrenNewVM(&wrenConfig);
|
||||||
|
|
||||||
|
// Setup user-defined data such as pointer to "global" objects.
|
||||||
|
_bundleData.engine = engine;
|
||||||
|
wrenSetUserData(_wrenVm, &_bundleData);
|
||||||
|
|
||||||
WrenInterpretResult result = wrenInterpret(_wrenVm, "scripted-engine", "System.print(\"I am running in a VM!\")");
|
WrenInterpretResult result = wrenInterpret(_wrenVm, "scripted-engine", "System.print(\"I am running in a VM!\")");
|
||||||
assert(result == WREN_RESULT_SUCCESS);
|
assert(result == WREN_RESULT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
@ -38,7 +81,7 @@ Logic::~Logic() {
|
||||||
|
|
||||||
void get_info(WrenVM *vm) {
|
void get_info(WrenVM *vm) {
|
||||||
// Retrieve "global" objects defined in userData
|
// Retrieve "global" objects defined in userData
|
||||||
BundleData *bundleData = reinterpret_cast<BundleData *>(vm->config.userData);
|
BundleData *bundleData = reinterpret_cast<BundleData *>(wrenGetUserData(vm));
|
||||||
Engine *engine = bundleData->engine;
|
Engine *engine = bundleData->engine;
|
||||||
assert(engine);
|
assert(engine);
|
||||||
|
|
||||||
|
@ -48,25 +91,24 @@ void get_info(WrenVM *vm) {
|
||||||
|
|
||||||
WrenForeignMethodFn
|
WrenForeignMethodFn
|
||||||
Logic::bindForeignMethod(WrenVM *vm, const char *module, const char *className, bool isStatic, const char *signature) {
|
Logic::bindForeignMethod(WrenVM *vm, const char *module, const char *className, bool isStatic, const char *signature) {
|
||||||
if (strcmp(module, "scripted-engine") == 0) {
|
if (strcmp(module, "engine") == 0) {
|
||||||
if (strcmp(className, "Engine") == 0) {
|
if (strcmp(className, "Engine") == 0) {
|
||||||
if (isStatic && strcmp(signature, "get_info()") == 0) {
|
if (isStatic && strcmp(signature, "getInfo()") == 0) {
|
||||||
return get_info;
|
return get_info;
|
||||||
}
|
}
|
||||||
// Other foreign methods on Math...
|
// Other foreign methods on Engine...
|
||||||
}
|
}
|
||||||
// Other classes in main...
|
// Other classes in engine...
|
||||||
}
|
}
|
||||||
// Other modules...
|
// Other modules...
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Logic::interpret() {
|
void Logic::interpret(const char *name) {
|
||||||
assert(_wrenVm);
|
assert(_wrenVm);
|
||||||
WrenInterpretResult result = wrenInterpret(_wrenVm, "scripted-engine", "class Engine {\
|
std::string path = getPath(name);
|
||||||
foreign static get_info())\
|
char *script = fileContent(path.c_str());
|
||||||
}\
|
WrenInterpretResult result = wrenInterpret(_wrenVm, name, script);
|
||||||
Engine.get_info()");
|
|
||||||
assert(result == WREN_RESULT_SUCCESS);
|
assert(result == WREN_RESULT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ public:
|
||||||
|
|
||||||
static WrenForeignMethodFn
|
static WrenForeignMethodFn
|
||||||
bindForeignMethod(WrenVM *vm, const char *module, const char *className, bool isStatic, const char *signature);
|
bindForeignMethod(WrenVM *vm, const char *module, const char *className, bool isStatic, const char *signature);
|
||||||
void interpret();
|
void interpret(const char *name);
|
||||||
|
|
||||||
void add_item();
|
void add_item();
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ int main() {
|
||||||
Engine e;
|
Engine e;
|
||||||
Logic l(&e);
|
Logic l(&e);
|
||||||
|
|
||||||
l.interpret();
|
l.interpret("logic");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
4
src/scripts/CMakeLists.txt
Normal file
4
src/scripts/CMakeLists.txt
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
set(MODULE scripts)
|
||||||
|
|
||||||
|
file(GLOB_RECURSE script_list "*.wren")
|
||||||
|
add_custom_target(${MODULE} SOURCES ${script_list})
|
3
src/scripts/engine.wren
Normal file
3
src/scripts/engine.wren
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
class Engine {
|
||||||
|
foreign static getInfo()
|
||||||
|
}
|
4
src/scripts/logic.wren
Normal file
4
src/scripts/logic.wren
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
import "engine" for Engine
|
||||||
|
|
||||||
|
System.print("This is logic.wren")
|
||||||
|
System.print(Engine.getInfo())
|
Loading…
Reference in a new issue