couch/core/Scripting/Guile.cpp

104 lines
2.8 KiB
C++
Raw Normal View History

2021-05-06 16:24:51 -05:00
#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