toruby.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. /*
  2. * toruby.c helps expose functionality from C to Mruby for Eruta.
  3. * All functions are prefixed with tr_.
  4. * Look at the tr_*.c files.
  5. * */
  6. #include "toruby.h"
  7. #include "tr_macro.h"
  8. #include "monolog.h"
  9. #include "rh.h"
  10. #include "state.h"
  11. #include "server.h"
  12. #include <mruby/hash.h>
  13. #include <mruby/class.h>
  14. #include <mruby/data.h>
  15. #include <mruby/array.h>
  16. /*
  17. #include "tr_macro.h"
  18. #include "tr_audio.h"
  19. #include "tr_graph.h"
  20. #include "tr_store.h"
  21. #include "tr_sprite.h"
  22. */
  23. /* Documentation of mrb_get_args:
  24. retrieve arguments from mrb_state.
  25. mrb_get_args(mrb, format, ...)
  26. returns number of arguments parsed.
  27. format specifiers:
  28. o: Object [mrb_value]
  29. S: String [mrb_value]
  30. A: Array [mrb_value]
  31. H: Hash [mrb_value]
  32. s: String [char*,int]
  33. z: String [char*] nul terminated
  34. a: Array [mrb_value*,mrb_int]
  35. f: Float [mrb_float]
  36. i: Integer [mrb_int]
  37. b: Binary [int]
  38. n: Symbol [mrb_sym]
  39. &: Block [mrb_value]
  40. *: rest argument [mrb_value*,int]
  41. |: optional
  42. */
  43. /** Writes a NOTE message to the log. */
  44. static mrb_value tr_log(mrb_state * mrb, mrb_value self) {
  45. (void) self; (void) mrb;
  46. mrb_value text = mrb_nil_value();
  47. mrb_get_args(mrb, "S", &text);
  48. LOG_NOTE("%s\n", RSTRING_PTR(text));
  49. return self;
  50. }
  51. /** Writes a messageto a certain log level log. */
  52. static mrb_value tr_log_to(mrb_state * mrb, mrb_value self) {
  53. (void) self; (void) mrb;
  54. mrb_value level = mrb_nil_value();
  55. mrb_value text = mrb_nil_value();
  56. mrb_get_args(mrb, "SS", &level, &text);
  57. LOG_LEVEL(RSTRING_PTR(level), "%s\n", RSTRING_PTR(text));
  58. return self;
  59. }
  60. /** Cause a warning to be logged */
  61. static mrb_value tr_warn(mrb_state * mrb, mrb_value self) {
  62. (void) self; (void) mrb;
  63. mrb_value text = mrb_nil_value();
  64. mrb_get_args(mrb, "S", &text);
  65. LOG_WARNING("%s\n", RSTRING_PTR(text));
  66. return self;
  67. }
  68. /** Enables a certain log level */
  69. static mrb_value tr_log_enable(mrb_state * mrb, mrb_value self) {
  70. (void) self; (void) mrb;
  71. mrb_value text = mrb_nil_value();
  72. mrb_get_args(mrb, "S", &text);
  73. monolog_enable_level(RSTRING_PTR(text));
  74. return self;
  75. }
  76. /** Disables a certain log level */
  77. static mrb_value tr_log_disable(mrb_state * mrb, mrb_value self) {
  78. (void) self; (void) mrb;
  79. mrb_value text = mrb_nil_value();
  80. mrb_get_args(mrb, "S", &text);
  81. monolog_disable_level(RSTRING_PTR(text));
  82. return self;
  83. }
  84. /* Loads another script from the script directory. */
  85. static mrb_value tr_script(mrb_state * mrb, mrb_value self) {
  86. int res;
  87. char * command;
  88. (void) self;
  89. mrb_value text = mrb_nil_value();
  90. mrb_get_args(mrb, "S", &text);
  91. command = mrb_str_to_cstr(mrb, text);
  92. res = rh_run_script(mrb, command);
  93. return mrb_fixnum_value(res);
  94. }
  95. /* Sends data to a given client */
  96. static mrb_value tr_send_to_client(mrb_state * mrb, mrb_value self) {
  97. int res;
  98. mrb_int client = -1;
  99. char * data = NULL;
  100. int size = 0;
  101. struct woe_server * srv = MRB_WOE_SERVER(mrb);
  102. (void) self;
  103. mrb_get_args(mrb, "is", &client, &data, &size);
  104. res = woe_server_send_to_client(srv, client, data, size);
  105. return mrb_fixnum_value(res);
  106. }
  107. /* Shuts down a given client */
  108. static mrb_value tr_server_done(mrb_state * mrb, mrb_value self) {
  109. struct woe_server * srv = MRB_WOE_SERVER(mrb);
  110. (void) self;
  111. woe_server_request_shutdown(srv);
  112. return mrb_nil_value();
  113. }
  114. /* Disconnects a given client by id */
  115. static mrb_value tr_disconnect_client(mrb_state * mrb, mrb_value self) {
  116. int res;
  117. mrb_int client;
  118. struct woe_server * srv = MRB_WOE_SERVER(mrb);
  119. (void) self;
  120. mrb_get_args(mrb, "i", &client);
  121. res = woe_server_disconnect_id(srv, client);
  122. return mrb_fixnum_value(res);
  123. }
  124. /* Yeah, I know, but this reduces boilerplate. */
  125. #define WRAP_SERVER_BEGIN(NAME) \
  126. static mrb_value NAME(mrb_state * mrb, mrb_value self) { \
  127. int res; \
  128. mrb_int client = -1; \
  129. struct woe_server * srv = MRB_WOE_SERVER(mrb); \
  130. (void) self; \
  131. #define WRAP_SERVER_END() \
  132. return mrb_fixnum_value(res); \
  133. }
  134. WRAP_SERVER_BEGIN(tr_server_iac) {
  135. mrb_int command = 0;
  136. mrb_get_args(mrb, "ii", &client, &command);
  137. res = woe_server_iac(srv, client, command);
  138. } WRAP_SERVER_END()
  139. WRAP_SERVER_BEGIN(tr_server_negotiate) {
  140. mrb_int how = 0, option = 0;
  141. mrb_get_args(mrb, "iii", &client, &how, &option);
  142. res = woe_server_negotiate(srv, client, how, option);
  143. } WRAP_SERVER_END()
  144. WRAP_SERVER_BEGIN(tr_server_begin_sb) {
  145. mrb_int telopt = 0;
  146. mrb_get_args(mrb, "ii", &client, &telopt);
  147. res = woe_server_begin_sb(srv, client, telopt);
  148. } WRAP_SERVER_END()
  149. WRAP_SERVER_BEGIN(tr_server_finish_sb) {
  150. mrb_get_args(mrb, "i", &client);
  151. res = woe_server_finish_sb(srv, client);
  152. } WRAP_SERVER_END()
  153. WRAP_SERVER_BEGIN(tr_server_subnegotiation) {
  154. mrb_int telopt = 0, size = 0;
  155. char * data = NULL;
  156. mrb_get_args(mrb, "iis", &client, &telopt, &data, &size);
  157. res = woe_server_subnegotiation(srv, client, telopt, data, size);
  158. } WRAP_SERVER_END()
  159. WRAP_SERVER_BEGIN(tr_server_begin_compress2) {
  160. mrb_get_args(mrb, "i", &client);
  161. res = woe_server_begin_compress2(srv, client);
  162. } WRAP_SERVER_END()
  163. WRAP_SERVER_BEGIN(tr_server_puts) {
  164. char * fmt = NULL;
  165. mrb_get_args(mrb, "iz", &client, &fmt);
  166. res = woe_server_printf(srv, client, fmt);
  167. } WRAP_SERVER_END()
  168. WRAP_SERVER_BEGIN(tr_server_raw_puts) {
  169. char * fmt = NULL;
  170. mrb_get_args(mrb, "iz", &client, &fmt);
  171. res = woe_server_raw_printf(srv, client, fmt);
  172. } WRAP_SERVER_END()
  173. WRAP_SERVER_BEGIN(tr_server_begin_newenviron) {
  174. mrb_int type;
  175. mrb_get_args(mrb, "ii", &client, &type);
  176. res = woe_server_begin_newenviron(srv, client, type);
  177. } WRAP_SERVER_END()
  178. WRAP_SERVER_BEGIN(tr_server_newenviron_value) {
  179. mrb_int type;
  180. char * value = NULL;
  181. mrb_get_args(mrb, "iiz", &client, &type, &value);
  182. res = woe_server_newenviron_value(srv, client, type, value);
  183. } WRAP_SERVER_END()
  184. WRAP_SERVER_BEGIN(tr_server_finish_newenviron) {
  185. mrb_get_args(mrb, "i", &client);
  186. res = woe_server_finish_newenviron(srv, client);
  187. } WRAP_SERVER_END()
  188. WRAP_SERVER_BEGIN(tr_server_ttype_send) {
  189. mrb_get_args(mrb, "i", &client);
  190. res = woe_server_ttype_send(srv, client);
  191. } WRAP_SERVER_END()
  192. WRAP_SERVER_BEGIN(tr_server_ttype_is) {
  193. mrb_int type;
  194. char * ttype = NULL;
  195. mrb_get_args(mrb, "iz", &client, &ttype);
  196. res = woe_server_ttype_is(srv, client, ttype);
  197. } WRAP_SERVER_END()
  198. /*
  199. int woe_server_send_zmp(struct woe_server * srv, int client, int argc, const char ** argv);
  200. int woe_server_send_vzmpv(struct woe_server * srv, int client, va_list va);
  201. int woe_server_send_zmpv(struct woe_server * srv, int client, ...);
  202. */
  203. WRAP_SERVER_BEGIN(tr_server_begin_zmp) {
  204. char * command = NULL;
  205. mrb_get_args(mrb, "iz", &client, &command);
  206. res = woe_server_begin_zmp(srv, client, command);
  207. } WRAP_SERVER_END()
  208. WRAP_SERVER_BEGIN(tr_server_zmp_arg) {
  209. char * arg = NULL;
  210. mrb_get_args(mrb, "iz", &client, &arg);
  211. res = woe_server_zmp_arg(srv, client, arg);
  212. } WRAP_SERVER_END()
  213. WRAP_SERVER_BEGIN(tr_server_finish_zmp) {
  214. char * command;
  215. mrb_get_args(mrb, "iz", &client, &command);
  216. res = woe_server_finish_zmp(srv, client, command);
  217. } WRAP_SERVER_END()
  218. /* Initializes the functionality that Eruta exposes to Ruby. */
  219. int tr_init(mrb_state * mrb) {
  220. // luaL_dostring(lua, "print 'Hello!' ");
  221. struct RClass *woe;
  222. struct RClass *srv;
  223. struct RClass *krn;
  224. woe = mrb_define_module(mrb, "Woe");
  225. srv = mrb_define_module_under(mrb, woe, "Server");
  226. TR_CLASS_METHOD_NOARG(mrb, woe, "quit" , tr_server_done);
  227. TR_CLASS_METHOD_NOARG(mrb, srv, "quit" , tr_server_done);
  228. TR_CLASS_METHOD_ARGC(mrb, srv, "send_to_client" , tr_send_to_client, 2);
  229. TR_CLASS_METHOD_NOARG(mrb, srv, "disconnect" , tr_disconnect_client);
  230. int woe_server_iac(struct woe_server * srv, int client, int command);
  231. int woe_server_negotiate(struct woe_server * srv, int client, int how, int option);
  232. int woe_server_begin_sb(struct woe_server * srv, int client, int telopt);
  233. int woe_server_finish_sb(struct woe_server * srv, int client);
  234. int woe_server_subnegotiation(struct woe_server * srv, int client, int telopt, char * buffer, int size);
  235. int woe_server_begin_compress2(struct woe_server * srv, int client);
  236. int woe_server_vprintf(struct woe_server * srv, int client, const char *fmt, va_list va);
  237. int woe_server_printf(struct woe_server * srv, int client, const char *fmt, ...);
  238. int woe_server_raw_vprintf(struct woe_server * srv, int client, const char *fmt, va_list va);
  239. int woe_server_raw_printf(struct woe_server * srv, int client, const char *fmt, ...);
  240. int woe_server_begin_newenviron(struct woe_server * srv, int client, int type);
  241. int woe_server_newenviron_value(struct woe_server * srv, int client, int type, char * value);
  242. int woe_server_finish_newenviron(struct woe_server * srv, int client);
  243. int woe_server_ttype_send(struct woe_server * srv, int client);
  244. int woe_server_ttype_is(struct woe_server * srv, int client, char * ttype);
  245. int woe_server_send_zmp(struct woe_server * srv, int client, int argc, const char ** argv);
  246. int woe_server_send_vzmpv(struct woe_server * srv, int client, va_list va);
  247. int woe_server_send_zmpv(struct woe_server * srv, int client, ...);
  248. int woe_server_begin_zmp(struct woe_server * srv, int client, const char * cmd);
  249. int woe_server_zmp_arg(struct woe_server * srv, int client, const char * arg);
  250. int woe_server_finish_zmp(struct woe_server * srv, int client, const char * cmd);
  251. TR_CLASS_METHOD_ARGC(mrb, srv, "iac" , tr_server_iac, 2);
  252. TR_CLASS_METHOD_ARGC(mrb, srv, "negotiate" , tr_server_negotiate , 3);
  253. TR_CLASS_METHOD_ARGC(mrb, srv, "begin_sb" , tr_server_begin_sb , 2);
  254. TR_CLASS_METHOD_ARGC(mrb, srv, "finish_sb" , tr_server_finish_sb , 1);
  255. TR_CLASS_METHOD_ARGC(mrb, srv, "subnegotiation" , tr_server_subnegotiation, 3);
  256. TR_CLASS_METHOD_ARGC(mrb, srv, "begin_compress2", tr_server_begin_compress2, 2);
  257. TR_CLASS_METHOD_ARGC(mrb, srv, "puts" , tr_server_puts, 2);
  258. TR_CLASS_METHOD_ARGC(mrb, srv, "raw_puts" , tr_server_raw_puts, 2);
  259. TR_CLASS_METHOD_ARGC(mrb, srv, "begin_newenviron" , tr_server_begin_newenviron, 2);
  260. TR_CLASS_METHOD_ARGC(mrb, srv, "newenviron_value" , tr_server_newenviron_value, 3);
  261. TR_CLASS_METHOD_ARGC(mrb, srv, "finish_newenviron", tr_server_finish_newenviron, 1);
  262. TR_CLASS_METHOD_ARGC(mrb, srv, "ttype_send" , tr_server_ttype_send, 1);
  263. TR_CLASS_METHOD_ARGC(mrb, srv, "ttype_is" , tr_server_ttype_is, 2);
  264. TR_CLASS_METHOD_ARGC(mrb, srv, "begin_zmp" , tr_server_finish_zmp, 2);
  265. TR_CLASS_METHOD_ARGC(mrb, srv, "zmp_arg" , tr_server_finish_zmp, 2);
  266. TR_CLASS_METHOD_ARGC(mrb, srv, "finish_zmp" , tr_server_finish_zmp, 2);
  267. krn = mrb_module_get(mrb, "Kernel");
  268. if(!krn) return -1;
  269. TR_METHOD_ARGC(mrb, krn, "warn" , tr_warn , 1);
  270. TR_METHOD_ARGC(mrb, krn, "warning" , tr_warn , 1);
  271. TR_METHOD_ARGC(mrb, krn, "log" , tr_log , 1);
  272. TR_METHOD_ARGC(mrb, krn, "log_to" , tr_log_to , 2);
  273. TR_METHOD_ARGC(mrb, krn, "log_enable" , tr_log_disable , 1);
  274. TR_METHOD_ARGC(mrb, krn, "log_disable" , tr_log_enable , 1);
  275. TR_METHOD_ARGC(mrb, krn, "script" , tr_script , 1);
  276. // must restore gc area here ????
  277. mrb_gc_arena_restore(mrb, 0);
  278. return 0;
  279. }