Begin experimental guile support
This commit is contained in:
103
core/Scripting/Guile.cpp
Normal file
103
core/Scripting/Guile.cpp
Normal file
@@ -0,0 +1,103 @@
|
||||
#include "Guile.h"
|
||||
|
||||
#include "../Util.h"
|
||||
|
||||
void Guile::Initialize() {
|
||||
#ifdef GUILE_SCRIPTING
|
||||
language = this;
|
||||
// Initialize Guile
|
||||
scm_with_guile(Guile::inner_init, NULL);
|
||||
|
||||
// Bind input functions
|
||||
Input *input = Input::GetInstance();
|
||||
if (HasHook("onkey")) {
|
||||
input->keyHandlers.push_back(GuileKeyHandler);
|
||||
}
|
||||
if (HasHook("onmousemotion")) {
|
||||
input->mousePositionHandlers.push_back(GuileMousePositionHandler);
|
||||
}
|
||||
#else // GUILE_SCRIPTING
|
||||
Util::Die("Guile is selected as the scripting language, but this binary was built without Guile support.");
|
||||
#endif // GUILE_SCRIPTING
|
||||
}
|
||||
|
||||
void Guile::Update(double delta) {
|
||||
#ifdef GUILE_SCRIPTING
|
||||
if (HasHook("update")) {
|
||||
scm_with_guile(Guile::inner_update, &delta);
|
||||
}
|
||||
#endif // GUILE_SCRIPTING
|
||||
}
|
||||
|
||||
void Guile::Close() {
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
bool Guile::HasHook(const char *name) {
|
||||
bool exists = false;
|
||||
#ifdef GUILE_SCRIPTING
|
||||
exists = scm_with_guile(Guile::inner_has_hook, (void *) name);
|
||||
#endif // GUILE_SCRIPTING
|
||||
return exists;
|
||||
}
|
||||
|
||||
#ifdef GUILE_SCRIPTING
|
||||
|
||||
void Guile::GuileKeyHandler(int key, int code, int action, int mods) {
|
||||
Guile::key_event ev {key, code, action, mods};
|
||||
scm_with_guile(Guile::inner_key_handler, &ev);
|
||||
}
|
||||
|
||||
void Guile::GuileMousePositionHandler(double xpos, double ypos, double relx, double rely) {
|
||||
Guile::mouse_position_event ev {xpos, ypos, relx, rely};
|
||||
scm_with_guile(Guile::inner_mouse_position_handler, &ev);
|
||||
}
|
||||
|
||||
void *Guile::inner_init(void* empty) {
|
||||
// Init swig
|
||||
SWIG_init();
|
||||
// Load main file
|
||||
scm_c_primitive_load("main.scm");
|
||||
// Execute the init function if it exists
|
||||
if (ScriptingLanguage::language->HasHook("init")) {
|
||||
scm_call_0(scm_c_eval_string("init"));
|
||||
}
|
||||
}
|
||||
|
||||
void *Guile::inner_update(void *data) {
|
||||
double delta = *(double*) data;
|
||||
if (ScriptingLanguage::language->HasHook("update")) {
|
||||
scm_call_1(scm_c_eval_string("update"), scm_from_double(delta));
|
||||
}
|
||||
}
|
||||
|
||||
void *Guile::inner_has_hook(void *data) {
|
||||
const char *name = (const char *) data;
|
||||
return (void *) scm_to_bool(scm_defined_p(scm_from_locale_symbol(name), SCM_UNDEFINED));
|
||||
}
|
||||
|
||||
void *Guile::inner_key_handler(void *data) {
|
||||
Guile::key_event *ev = (Guile::key_event*) data;
|
||||
if (ScriptingLanguage::language->HasHook("onkey")) {
|
||||
scm_call_4(scm_c_eval_string("onkey"),
|
||||
scm_from_int(ev->key),
|
||||
scm_from_int(ev->code),
|
||||
scm_from_int(ev->action),
|
||||
scm_from_int(ev->mods));
|
||||
}
|
||||
}
|
||||
|
||||
void *Guile::inner_mouse_position_handler(void *data) {
|
||||
Guile::mouse_position_event *ev = (Guile::mouse_position_event *) data;
|
||||
if (ScriptingLanguage::language->HasHook("onmousemotion")) {
|
||||
scm_call_4(scm_c_eval_string("onmousemotion"),
|
||||
scm_from_double(ev->xpos),
|
||||
scm_from_double(ev->ypos),
|
||||
scm_from_double(ev->relx),
|
||||
scm_from_double(ev->rely));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif // GUILE_SCRIPTING
|
||||
|
||||
46
core/Scripting/Guile.h
Normal file
46
core/Scripting/Guile.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#ifndef GUILE_H
|
||||
#define GUILE_H
|
||||
|
||||
#include "../Input.h"
|
||||
|
||||
#ifdef GUILE_SCRIPTING
|
||||
#include <libguile.h>
|
||||
|
||||
|
||||
extern "C" void SWIG_init();
|
||||
#endif // GUILE_SCRIPTING
|
||||
|
||||
#include "ScriptingLanguage.h"
|
||||
|
||||
class Guile : public ScriptingLanguage {
|
||||
public:
|
||||
void Initialize();
|
||||
void Update(double delta);
|
||||
void Close();
|
||||
bool HasHook(const char *name);
|
||||
private:
|
||||
#ifdef GUILE_SCRIPTING
|
||||
struct key_event {
|
||||
int key;
|
||||
int code;
|
||||
int action;
|
||||
int mods;
|
||||
};
|
||||
struct mouse_position_event {
|
||||
double xpos;
|
||||
double ypos;
|
||||
double relx;
|
||||
double rely;
|
||||
};
|
||||
static void *inner_init(void *empty);
|
||||
static void *inner_update(void *delta);
|
||||
static void *inner_has_hook(void *name);
|
||||
static void *inner_key_handler(void *ev);
|
||||
static void *inner_mouse_position_handler(void *ev);
|
||||
static void GuileKeyHandler(int key, int code, int action, int mods);
|
||||
static void GuileMousePositionHandler(double xpos, double ypos, double relx, double rely);
|
||||
#endif // GUILE_SCRIPTING
|
||||
};
|
||||
|
||||
|
||||
#endif /* GUILE_H */
|
||||
Reference in New Issue
Block a user