Add module for Scheduler.

Also reorganizes some code to make it easier to add more modules.
This commit is contained in:
Bob Nystrom
2015-09-13 11:32:39 -07:00
parent f36a795534
commit ea5c3b01eb
18 changed files with 291 additions and 110 deletions
+3 -3
View File
@@ -3,8 +3,7 @@
#include <string.h>
#include "io.h"
#include "timer.h"
#include "modules.h"
char const* rootDirectory = NULL;
@@ -73,7 +72,8 @@ char* wrenFilePath(const char* name)
char* readModule(WrenVM* vm, const char* module)
{
if (strcmp(module, "timer") == 0) return timerGetSource();
char* source = readBuiltInModule(module);
if (source != NULL) return source;
// First try to load the module with a ".wren" extension.
char* modulePath = wrenFilePath(module);
+83
View File
@@ -0,0 +1,83 @@
#include <stdlib.h>
#include <string.h>
#include "modules.h"
#include "scheduler.wren.inc"
#include "timer.wren.inc"
#include "scheduler.h"
#include "timer.h"
typedef struct
{
// The name of the module.
const char* name;
// Pointer to the string containing the source code of the module. We use a
// pointer here because the string variable itself is not a constant
// expression so can't be used in the initializer below.
const char **source;
// The function that binds foreign methods in this module.
WrenForeignMethodFn (*bindMethodFn)(WrenVM* vm, const char* className,
bool isStatic, const char* signature);
// The function that binds foreign classes in this module.
WrenForeignClassMethods (*bindClassFn)(WrenVM* vm, const char* className);
} BuiltInModule;
// The array of built-in modules.
static BuiltInModule modules[] =
{
{"scheduler", &schedulerModuleSource, schedulerBindForeign, NULL},
{"timer", &timerModuleSource, timerBindForeign, NULL},
// Sentinel marking the end of the list.
{NULL, NULL, NULL, NULL}
};
// Looks for a built-in module with [name].
//
// Returns the BuildInModule for it or NULL if not found.
static BuiltInModule* findModule(const char* name)
{
for (int i = 0; modules[i].name != NULL; i++)
{
if (strcmp(name, modules[i].name) == 0) return &modules[i];
}
return NULL;
}
char* readBuiltInModule(const char* name)
{
BuiltInModule* module = findModule(name);
if (module == NULL) return NULL;
size_t length = strlen(*module->source);
char* copy = (char*)malloc(length + 1);
strncpy(copy, *module->source, length + 1);
return copy;
}
WrenForeignMethodFn bindBuiltInForeignMethod(
WrenVM* vm, const char* moduleName, const char* className, bool isStatic,
const char* signature)
{
BuiltInModule* module = findModule(moduleName);
if (module == NULL) return NULL;
return module->bindMethodFn(vm, className, isStatic, signature);
}
WrenForeignClassMethods bindBuiltInForeignClass(
WrenVM* vm, const char* moduleName, const char* className)
{
WrenForeignClassMethods methods = { NULL, NULL };
BuiltInModule* module = findModule(moduleName);
if (module == NULL) return methods;
return module->bindClassFn(vm, className);
}
+19
View File
@@ -0,0 +1,19 @@
#ifndef modules_h
#define modules_h
#include "wren.h"
char* readBuiltInModule(const char* module);
// Looks up a foreign method in a built-in module.
//
// Returns `NULL` if [moduleName] is not a built-in module.
WrenForeignMethodFn bindBuiltInForeignMethod(
WrenVM* vm, const char* moduleName, const char* className, bool isStatic,
const char* signature);
// Binds foreign classes declared in a built-in modules.
WrenForeignClassMethods bindBuiltInForeignClass(
WrenVM* vm, const char* moduleName, const char* className);
#endif
+14 -14
View File
@@ -2,8 +2,9 @@
#include <string.h>
#include "io.h"
#include "modules.h"
#include "vm.h"
#include "timer.h"
#include "scheduler.h"
#define MAX_LINE_LENGTH 1024 // TODO: Something less arbitrary.
@@ -15,16 +16,15 @@ static WrenBindForeignClassFn bindClassFn = NULL;
uv_loop_t* loop;
/// Binds foreign methods declared in either built in modules, or the injected
/// API test modules.
// Binds foreign methods declared in either built in modules, or the injected
// API test modules.
static WrenForeignMethodFn bindForeignMethod(WrenVM* vm, const char* module,
const char* className, bool isStatic, const char* signature)
{
if (strcmp(module, "timer") == 0)
{
return timerBindForeign(vm, className, isStatic, signature);
}
WrenForeignMethodFn method = bindBuiltInForeignMethod(vm, module, className,
isStatic, signature);
if (method != NULL) return method;
if (bindMethodFn != NULL)
{
return bindMethodFn(vm, module, className, isStatic, signature);
@@ -33,14 +33,14 @@ static WrenForeignMethodFn bindForeignMethod(WrenVM* vm, const char* module,
return NULL;
}
/// Binds foreign classes declared in either built in modules, or the injected
/// API test modules.
// Binds foreign classes declared in either built in modules, or the injected
// API test modules.
static WrenForeignClassMethods bindForeignClass(
WrenVM* vm, const char* module, const char* className)
{
WrenForeignClassMethods methods = { NULL, NULL };
// TODO: Bind classes for built-in modules here.
WrenForeignClassMethods methods = bindBuiltInForeignClass(vm, module,
className);
if (methods.allocate != NULL) return methods;
if (bindClassFn != NULL)
{
@@ -70,7 +70,7 @@ static void initVM()
static void freeVM()
{
timerReleaseMethods();
schedulerReleaseMethods();
uv_loop_close(loop);
free(loop);