This repository has been archived on 2020-04-11. You can view files and clone it, but cannot push or open issues or pull requests.
gnoemoe/gnoemoe/gm-scripts.c
Jesse van den Kieboom 49e8351958 * gnoemoe/gm-app.c: make sure the main view is destroyed (otherwise
the main view still holds references to the opened worlds which then
	don't get properly finalized). Therefore not properly saving 
	command input history etc. Added proper finalization on SIGINT
	* gnoemoe/gm-scripts.c: fixed indentation
	* gnoemoe/dialogs/gm-preferences-dialog.c: added color table
	saving when dialog gets destroyed
2006-09-29 12:26:16 +00:00

918 lines
21 KiB
C

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <glib.h>
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <gtk/gtk.h>
#include <ruby.h>
#include <libgnomevfs/gnome-vfs-mime-utils.h>
#include <libgnomevfs/gnome-vfs.h>
#include <sys/stat.h>
#include <sys/types.h>
#undef PACKAGE_BUGREPORT
#undef PACKAGE_NAME
#undef PACKAGE_STRING
#undef PACKAGE_TARNAME
#undef PACKAGE_VERSION
#include "gm-support.h"
#include "gm-debug.h"
#include "gm-world.h"
#include "gm-app.h"
#include "gm-scripts.h"
#include "gm-world.h"
#include "gm-string.h"
#define GM_SCRIPTS_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), \
GM_TYPE_SCRIPTS, GmScriptsPrivate))
#define RB_CALLBACK(x) (VALUE (*)())(x)
#define GM_SCRIPTS_GLOBAL PACKAGE_DATA_DIR "/" PACKAGE "/scripts"
static VALUE rb_world_class, rb_client_class, rb_scripts_class;
VALUE script_world_name(VALUE self);
VALUE gm_scripts_rb_world_new(GmWorld *world);
VALUE gm_scripts_rb_scripts_new(GmScripts *scripts);
void gm_scripts_rb_world_class_init();
void gm_scripts_rb_client_class_init();
void gm_scripts_rb_scripts_class_init();
void gm_scripts_unload(GmScripts *scripts);
void gm_scripts_rb_init();
struct _GmScriptsPrivate {
GList *files;
GmScript *loading;
GList *monitors;
};
/* Signals */
enum {
SCRIPT_ADDED,
SCRIPT_CHANGED,
SCRIPT_REMOVED,
RELOAD,
MESSAGE,
ERROR,
RUN,
NUM_SIGNALS
};
static guint gm_scripts_signals[NUM_SIGNALS] = {0};
G_DEFINE_TYPE(GmScripts, gm_scripts, G_TYPE_OBJECT)
static void
gm_scripts_finalize(GObject *object) {
GmScripts *scripts = GM_SCRIPTS(object);
GList *monitors;
gm_scripts_unload(scripts);
for (monitors = scripts->priv->monitors; monitors;
monitors = monitors->next) {
gnome_vfs_monitor_cancel((GnomeVFSMonitorHandle *)(monitors->data));
}
g_list_free(scripts->priv->monitors);
scripts->priv->monitors = NULL;
G_OBJECT_CLASS(gm_scripts_parent_class)->finalize(object);
}
static void
gm_scripts_class_init(GmScriptsClass *klass) {
GObjectClass *object_class = G_OBJECT_CLASS(klass);
object_class->finalize = gm_scripts_finalize;
gm_scripts_signals[SCRIPT_ADDED] =
g_signal_new("script_added",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(GmScriptsClass, script_added),
NULL, NULL,
g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE,
1,
G_TYPE_POINTER);
gm_scripts_signals[SCRIPT_CHANGED] =
g_signal_new("script_changed",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(GmScriptsClass, script_changed),
NULL, NULL,
g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE,
1,
G_TYPE_POINTER);
gm_scripts_signals[SCRIPT_REMOVED] =
g_signal_new("script_removed",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(GmScriptsClass, script_removed),
NULL, NULL,
g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE,
1,
G_TYPE_POINTER);
gm_scripts_signals[RELOAD] =
g_signal_new("reload",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(GmScriptsClass, reload),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
gm_scripts_signals[MESSAGE] =
g_signal_new("message",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(GmScriptsClass, message),
NULL, NULL,
g_cclosure_marshal_VOID__STRING,
G_TYPE_NONE,
1,
G_TYPE_STRING);
gm_scripts_signals[ERROR] =
g_signal_new("error",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(GmScriptsClass, error),
NULL, NULL,
g_cclosure_marshal_VOID__STRING,
G_TYPE_NONE,
1,
G_TYPE_STRING);
gm_scripts_signals[RUN] =
g_signal_new("run",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(GmScriptsClass, run),
NULL, NULL,
g_cclosure_marshal_VOID__STRING,
G_TYPE_NONE,
1,
G_TYPE_STRING);
g_type_class_add_private(object_class, sizeof(GmScriptsPrivate));
gm_scripts_rb_init();
}
void
gm_scripts_rb_init(GmScriptsClass *klass) {
ruby_init();
gm_scripts_rb_world_class_init();
gm_scripts_rb_client_class_init();
gm_scripts_rb_scripts_class_init();
}
static void
gm_scripts_init(GmScripts *scripts) {
scripts->priv = GM_SCRIPTS_GET_PRIVATE(scripts);
scripts->priv->monitors = NULL;
scripts->priv->files = NULL;
}
GmScripts *
gm_scripts_new() {
GmScripts *scripts = GM_SCRIPTS(g_object_new(GM_TYPE_SCRIPTS, NULL));
return scripts;
}
void gm_scripts_monitor_cb (GnomeVFSMonitorHandle *handle,
const gchar *monitor_uri, const gchar *info_uri,
GnomeVFSMonitorEventType event_type,
GmScripts *scripts) {
gchar *filename = gnome_vfs_get_local_path_from_uri(info_uri);
switch (event_type) {
case GNOME_VFS_MONITOR_EVENT_CHANGED:
gm_scripts_reload_file(scripts, filename);
break;
case GNOME_VFS_MONITOR_EVENT_DELETED:
gm_scripts_remove_file(scripts, filename);
break;
case GNOME_VFS_MONITOR_EVENT_CREATED:
gm_scripts_add_file(scripts, filename);
break;
default:
break;
}
g_free(filename);
}
void
gm_script_function_destroy(GmScriptFunction *fi) {
g_free(fi->name);
g_free(fi->fname);
g_free(fi->description);
g_free(fi);
}
void
gm_script_destroy_functions(GmScript *script) {
GList *functions;
for (functions = script->functions; functions;
functions = functions->next) {
gm_script_function_destroy((GmScriptFunction *)(functions->data));
}
g_list_free(script->functions);
script->functions = NULL;
}
void
gm_script_destroy(GmScript *script) {
gm_script_destroy_functions(script);
g_free(script->filename);
g_free(script);
}
void
gm_scripts_unload(GmScripts *scripts) {
GList *files;
for (files = scripts->priv->files; files; files = files->next) {
gm_script_destroy((GmScript *)(files->data));
}
g_list_free(scripts->priv->files);
scripts->priv->files = NULL;
}
GmScriptFunction *
gm_scripts_find(GmScripts *scripts, gchar *name) {
GList *files;
GList *functions;
GmScriptFunction *func;
GmScript *script;
for (files = scripts->priv->files; files; files = files->next) {
script = (GmScript *)(files->data);
for (functions = script->functions; functions;
functions = functions->next) {
func = (GmScriptFunction *)(functions->data);
if (strcasecmp(func->name, name) == 0) {
return func;
}
}
}
return NULL;
}
gboolean
gm_scripts_add(GmScripts *scripts, gchar *name, gchar *fname,
gchar *description) {
GmScriptFunction *func;
if (gm_scripts_find(scripts, name) == NULL) {
func = g_new(GmScriptFunction, 1);
func->script = scripts->priv->loading;
func->name = g_strdup(name);
func->fname = g_strdup(fname);;
func->description = g_strdup(description);
scripts->priv->loading->functions =
g_list_append(scripts->priv->loading->functions, func);
return TRUE;
} else {
return FALSE;
}
}
VALUE
gm_scripts_rb_register_functions_wrap(VALUE arg) {
return rb_eval_string("register_functions");
}
void
gm_scripts_rb_script_define_world(VALUE *world) {
rb_define_variable("$world", world);
}
void
gm_scripts_rb_error(GmScripts *scripts) {
int c;
VALUE lasterr;
char *err;
gchar *msg;
VALUE ary;
if(!NIL_P(ruby_errinfo)) {
lasterr = rb_gv_get("$!");
err = RSTRING(rb_obj_as_string(lasterr))->ptr;
gm_debug_msg(DEBUG_DEFAULT, "GmScripts.Error: Error while executing Ruby code: %s",
err);
msg = g_strdup_printf(_("Error in execution: %s"), err);
g_signal_emit(scripts, gm_scripts_signals[MESSAGE], 0, msg);
g_free(msg);
ary = rb_funcall(ruby_errinfo, rb_intern("backtrace"), 0);
gm_debug_msg(DEBUG_DEFAULT, "GmScripts.Error: Ruby backtrace:");
g_signal_emit(scripts, gm_scripts_signals[ERROR], 0,
_("Ruby backtrace:"));
for (c = 0; c < RARRAY(ary)->len; c++) {
gm_debug_msg(DEBUG_DEFAULT, "GmScripts.Error: \tfrom %s",
RSTRING(RARRAY(ary)->ptr[c])->ptr);
msg = g_strdup_printf(_("\tfrom %s"),
RSTRING(RARRAY(ary)->ptr[c])->ptr);
g_signal_emit(scripts, gm_scripts_signals[ERROR], 0, msg);
g_free(msg);
}
}
}
int
gm_scripts_rb_do(GmScripts *scripts, VALUE (*body)(), VALUE arg) {
int status;
rb_protect(body, arg, &status);
if (status != 0) {
gm_scripts_rb_error(scripts);
ruby_cleanup(status);
return 0;
}
return 1;
}
VALUE
gm_scripts_run_function(GmScriptInfo *arg) {
VALUE ret;
gchar *argstr;
gchar *func_all;
if (arg->argstr) {
argstr = gm_string_escape(arg->argstr);
func_all = g_strconcat(arg->name, "(\"", argstr, "\")", NULL);
g_free(argstr);
} else {
func_all = g_strconcat(arg->name, "()", NULL);
}
ret = rb_eval_string(func_all);
g_free(func_all);
return ret;
}
gboolean
gm_scripts_run(GmScripts *scripts, GmWorld *world, gchar *name, gchar *argstr) {
VALUE rbWorld, rbClient;
gchar *msg;
GmScriptInfo *info;
GmScriptFunction *f = gm_scripts_find(scripts, name);
if (!f) {
return FALSE;
}
info = g_new0(GmScriptInfo, 1);
info->name = g_strdup(f->fname);
if (argstr) {
info->argstr = g_strdup(argstr);
msg = g_strdup_printf(_("Run script '%s' from '%s' (%s)"), f->fname,
f->script->filename, argstr);
} else {
info->argstr = NULL;
msg = g_strdup_printf(_("Run script '%s' from '%s' ()"), f->fname,
f->script->filename);
}
g_signal_emit(scripts, gm_scripts_signals[RUN], 0, msg);
g_free(msg);
gm_scripts_rb_do(scripts, RB_CALLBACK(rb_load_file),
(VALUE)(f->script->filename));
ruby_exec();
rbWorld = gm_scripts_rb_world_new(world);
rb_define_variable("$world", &rbWorld);
rbClient = rb_class_new_instance(0, NULL, rb_client_class);
rb_define_variable("$client", &rbClient);
gm_scripts_rb_do(scripts, RB_CALLBACK(gm_scripts_run_function),
(VALUE)info);
g_free(info->name);
g_free(info->argstr);
g_free(info);
return TRUE;
}
VALUE
gm_scripts_rb_register_func_old(int argc, VALUE *argv) {
gm_debug_msg(DEBUG_DEFAULT, "GmScripts.RegisterFunc: This is the deprecated way to "
"register functions is does no longer work. Use $scripts.register "
"instead.");
return Qfalse;
}
void
gm_scripts_register_functions(GmScripts *scripts) {
gchar *msg;
VALUE rbScripts;
gm_debug_msg(DEBUG_DEFAULT, "GmScripts.RegisterFunctions: registering functions in %s",
scripts->priv->loading->filename);
msg = g_strdup_printf(_("Registering functions from '%s'"),
scripts->priv->loading->filename);
g_signal_emit(scripts, gm_scripts_signals[MESSAGE], 0, msg);
g_free(msg);
// Okay, I'm desperate... define an empty register_functions method so
// that the previous when gets cleared ... :(
rb_eval_string("def register_functions() end");
if (!gm_scripts_rb_do(scripts, RB_CALLBACK(rb_load_file),
(VALUE) scripts->priv->loading->filename)) {
return;
}
ruby_exec();
rbScripts = gm_scripts_rb_scripts_new(scripts);
rb_define_variable("$scripts", &rbScripts);
rb_define_global_function("register_func", &gm_scripts_rb_register_func_old,
-1);
gm_scripts_rb_do(scripts,
RB_CALLBACK(gm_scripts_rb_register_functions_wrap), 0);
}
void
gm_scripts_remove_file(GmScripts *scripts, const gchar *uri) {
GList *f, *l;
GmScript *script;
l = g_list_copy(scripts->priv->files);
for (f = l; f; f = f->next) {
script = (GmScript *)(f->data);
if (strcmp(script->filename, uri) == 0) {
scripts->priv->files = g_list_remove(scripts->priv->files, script);
gm_debug_msg(DEBUG_DEFAULT, "GmScripts.RemoveFile: Removing scripts from `%s'",
script->filename);
g_signal_emit(scripts, gm_scripts_signals[SCRIPT_REMOVED], 0,
script);
gm_script_destroy(script);
}
}
g_list_free(l);
}
gboolean
gm_scripts_add_file(GmScripts *scripts, const gchar *uri) {
GList *f;
GmScript *script;
gchar *msg;
gchar *ext;
// Only .rb files
ext = strrchr(uri, '.');
if (ext == NULL || strncmp(ext, ".rb", 2) != 0) {
msg = g_strdup_printf(_("File `%s' is not a valid ruby file"), uri);
gm_debug_msg(DEBUG_DEFAULT, "GmScripts.AddFile: %s", msg);
g_signal_emit(scripts, gm_scripts_signals[ERROR], 0, msg);
g_free(msg);
return FALSE;
}
for (f = scripts->priv->files; f; f = f->next) {
script = (GmScript *)(f->data);
if (strcmp(script->filename, uri) == 0) {
msg = g_strdup_printf(_("File `%s' already loaded"), uri);
gm_debug_msg(DEBUG_DEFAULT, "GmScripts.AddFile: %s", msg);
g_signal_emit(scripts, gm_scripts_signals[ERROR], 0, msg);
g_free(msg);
return FALSE;
}
}
msg = g_strdup_printf(_("File `%s' added"), uri);
gm_debug_msg(DEBUG_DEFAULT, "GmScripts.AddFile: %s", msg);
g_free(msg);
script = g_new0(GmScript, 1);
script->filename = g_strdup(uri);
if (strncmp(uri, GM_SCRIPTS_GLOBAL,
strlen(GM_SCRIPTS_GLOBAL)) == 0) {
script->type = GM_SCRIPT_TYPE_SHARE;
} else {
script->type = GM_SCRIPT_TYPE_USER;
}
scripts->priv->files = g_list_append(scripts->priv->files, script);
scripts->priv->loading = script;
gm_scripts_register_functions(scripts);
g_signal_emit(scripts, gm_scripts_signals[SCRIPT_ADDED], 0, script);
return TRUE;
}
void
gm_scripts_reload_file(GmScripts *scripts, const gchar *uri) {
GList *files;
GmScript *script;
for (files = scripts->priv->files; files; files = files->next) {
script = (GmScript *)(files->data);
if (strcmp(script->filename, uri) == 0) {
// Remove all functions and reregister the file
scripts->priv->loading = script;
gm_script_destroy_functions(script);
gm_scripts_register_functions(scripts);
g_signal_emit(scripts, gm_scripts_signals[SCRIPT_CHANGED], 0,
script);
return;
}
}
// If the script does not yet exist, add it
gm_scripts_add_file(scripts, uri);
}
void
gm_scripts_load_dir(GmScripts *scripts, gchar *dirname) {
gchar *filename;
gchar *file;
GDir *d;
GnomeVFSMonitorHandle *handle;
if (g_file_test(dirname, G_FILE_TEST_EXISTS) &&
g_file_test(dirname, G_FILE_TEST_IS_DIR)) {
if ((d = g_dir_open(dirname, 0, NULL))) {
while ((file = (gchar *)g_dir_read_name(d))) {
filename = g_strconcat(dirname, "/", file, NULL);
gm_scripts_add_file(scripts, filename);
g_free(filename);
}
}
gnome_vfs_monitor_add(&handle, dirname, GNOME_VFS_MONITOR_DIRECTORY,
(GnomeVFSMonitorCallback)gm_scripts_monitor_cb, scripts);
scripts->priv->monitors = g_list_append(scripts->priv->monitors,
handle);
}
}
void
gm_scripts_load(GmScripts *scripts) {
gchar *path;
if (scripts->priv->files) {
g_signal_emit(scripts, gm_scripts_signals[RELOAD], 0);
gm_scripts_unload(scripts);
}
path = g_strconcat(gm_app_path(gm_app_instance()), "/scripts", NULL);
// Make user dir if it doesn't exist
if (!g_file_test(path, G_FILE_TEST_EXISTS)) {
mkdir(path, 0750);
}
gm_scripts_load_dir(scripts, path);
gm_scripts_load_dir(scripts, GM_SCRIPTS_GLOBAL);
g_free(path);
}
GList *
gm_scripts_scripts(GmScripts *scripts) {
return scripts->priv->files;
}
// Ruby class functions
VALUE
gm_scripts_rb_world_new(GmWorld *world) {
VALUE tdata = Data_Wrap_Struct(rb_world_class, 0, 0, world);
return tdata;
}
VALUE
gm_scripts_rb_scripts_new(GmScripts *scripts) {
VALUE tdata = Data_Wrap_Struct(rb_scripts_class, 0, 0, scripts);
return tdata;
}
// Ruby world class functions
static VALUE
gm_scripts_rb_world_name(VALUE self) {
GmWorld *world;
Data_Get_Struct(self, GmWorld, world);
return rb_str_new2(gm_options_get(gm_world_options(world), "name"));
}
static VALUE
gm_scripts_rb_world_host(VALUE self) {
GmWorld *world;
Data_Get_Struct(self, GmWorld, world);
return rb_str_new2(gm_options_get(gm_world_options(world), "host"));
}
static VALUE
gm_scripts_rb_world_port(VALUE self) {
GmWorld *world;
Data_Get_Struct(self, GmWorld, world);
return rb_str_new2(gm_options_get(gm_world_options(world), "port"));
}
static VALUE
gm_scripts_rb_world_writeln(VALUE self, VALUE str) {
GmWorld *world;
gchar *strVal;
Data_Get_Struct(self, GmWorld, world);
strVal = rb_string_value_cstr(&str);
gm_world_writeln(world, strVal);
return Qnil;
}
static VALUE
gm_scripts_rb_world_status(VALUE self, VALUE str) {
GmWorld *world;
gchar *strVal;
Data_Get_Struct(self, GmWorld, world);
strVal = rb_string_value_cstr(&str);
gm_world_status(world, strVal);
return Qnil;
}
static VALUE
gm_scripts_rb_world_sendln(VALUE self, VALUE str) {
GmWorld *world;
gchar *strVal;
Data_Get_Struct(self, GmWorld, world);
strVal = rb_string_value_cstr(&str);
gm_world_sendln(world, strVal);
return Qnil;
}
static VALUE
gm_scripts_rb_world_input(VALUE self, VALUE str) {
GmWorld *world;
gchar *strVal;
Data_Get_Struct(self, GmWorld, world);
strVal = rb_string_value_cstr(&str);
gm_world_process_input(world, strVal);
return Qnil;
}
static VALUE
gm_scripts_rb_world_loaded(VALUE self) {
GmWorld *world;
Data_Get_Struct(self, GmWorld, world);
if (gm_world_loaded(world)) {
return Qtrue;
} else {
return Qfalse;
}
}
static VALUE
gm_scripts_rb_world_connected(VALUE self) {
GmWorld *world;
Data_Get_Struct(self, GmWorld, world);
if (gm_world_state(world) == GM_NET_STATE_CONNECTED) {
return Qtrue;
} else {
return Qfalse;
}
}
static VALUE
gm_scripts_rb_world_quit(VALUE self) {
GmWorld *world;
Data_Get_Struct(self, GmWorld, world);
gm_world_unload(world);
return Qnil;
}
static VALUE
gm_scripts_rb_world_connect(int argc, VALUE *argv, VALUE self) {
GmWorld *world;
const gchar *strHost, *strPort;
Data_Get_Struct(self, GmWorld, world);
if (argc == 0) {
strHost = gm_options_get(gm_world_options(world), "host");
} else {
strHost = rb_string_value_cstr(&(argv[0]));
}
if (argc == 0 || argc == 1) {
strPort = gm_options_get(gm_world_options(world), "port");
} else {
strPort = rb_string_value_cstr(&(argv[1]));
}
gm_world_connect_to(world, (gchar *)strHost, (gchar *)strPort);
return Qnil;
}
static VALUE
gm_scripts_rb_world_disconnect(VALUE self) {
GmWorld *world;
Data_Get_Struct(self, GmWorld, world);
gm_world_disconnect(world);
return Qnil;
}
// Ruby client class functions
static VALUE
gm_scripts_rb_client_version(VALUE self) {
return rb_str_new2(VERSION);
}
static VALUE
gm_scripts_rb_client_worlds(VALUE self) {
GList *world;
VALUE rb_array = rb_ary_new();
VALUE rb_world;
for (world = gm_app_worlds(gm_app_instance()); world; world = world->next) {
rb_world = gm_scripts_rb_world_new((GmWorld *)(world->data));
rb_ary_push(rb_array, rb_world);
}
return rb_array;
}
static VALUE
gm_scripts_rb_client_open(VALUE self, VALUE str) {
GmWorld *world;
gchar *strVal;
strVal = rb_string_value_cstr(&str);
world = gm_app_world_by_name(gm_app_instance(), strVal);
if (world == NULL) {
return Qfalse;
} else {
gm_world_load(world);
return Qtrue;
}
}
// Ruby scripts class functions
VALUE
gm_scripts_rb_scripts_register(int argc, VALUE *argv, VALUE self) {
char *name, *fname = NULL, *description = NULL;
gchar *msg;
GmScripts *scripts;
Data_Get_Struct(self, GmScripts, scripts);
if (argc > 1) {
name = rb_string_value_cstr(&argv[0]);
description = rb_string_value_cstr(&argv[1]);
if (argc == 2) {
fname = name;
} else {
fname = rb_string_value_cstr(&argv[2]);
}
if (gm_scripts_add(scripts, name, fname, description)) {
msg = g_strdup_printf(_("Register function '%s' from '%s'"), name,
scripts->priv->loading->filename);
gm_debug_msg(DEBUG_DEFAULT, "GmScripts.RbScriptsRegister: Adding script function "
"%s from %s", name, scripts->priv->loading->filename);
g_signal_emit(scripts, gm_scripts_signals[MESSAGE], 0, msg);
g_free(msg);
return Qtrue;
} else {
msg = g_strdup_printf(_("Script '%s' is already defined"), name);
gm_debug_msg(DEBUG_DEFAULT, "GmScripts.RbScriptsRegister: Script function %s "
"already defined!", name);
g_signal_emit(scripts, gm_scripts_signals[ERROR], 0, msg);
g_free(msg);
return Qfalse;
}
} else {
return Qfalse;
}
}
// Ruby class initializations
void
gm_scripts_rb_world_class_init() {
rb_world_class = rb_define_class("World", rb_cObject);
rb_define_method(rb_world_class, "name", gm_scripts_rb_world_name, 0);
rb_define_method(rb_world_class, "host", gm_scripts_rb_world_host, 0);
rb_define_method(rb_world_class, "port", gm_scripts_rb_world_port, 0);
rb_define_method(rb_world_class, "writeln", gm_scripts_rb_world_writeln, 1);
rb_define_method(rb_world_class, "println", gm_scripts_rb_world_writeln, 1);
rb_define_method(rb_world_class, "status", gm_scripts_rb_world_status, 1);
rb_define_method(rb_world_class, "sendln", gm_scripts_rb_world_sendln, 1);
rb_define_method(rb_world_class, "input", gm_scripts_rb_world_input, 1);
rb_define_method(rb_world_class, "quit", gm_scripts_rb_world_quit, 0);
rb_define_method(rb_world_class, "connect",
gm_scripts_rb_world_connect, -1);
rb_define_method(rb_world_class, "disconnect",
gm_scripts_rb_world_disconnect, 0);
rb_define_method(rb_world_class, "loaded?", gm_scripts_rb_world_loaded, 0);
rb_define_method(rb_world_class, "connected?",
gm_scripts_rb_world_connected, 0);
}
void
gm_scripts_rb_client_class_init() {
rb_client_class = rb_define_class("Client", rb_cObject);
rb_define_method(rb_client_class, "version",
gm_scripts_rb_client_version, 0);
rb_define_method(rb_client_class, "worlds",
gm_scripts_rb_client_worlds, 0);
rb_define_method(rb_client_class, "open", gm_scripts_rb_client_open, 1);
}
void
gm_scripts_rb_scripts_class_init() {
rb_scripts_class = rb_define_class("Scripts", rb_cObject);
rb_define_method(rb_scripts_class, "register",
gm_scripts_rb_scripts_register, -1);
}