Example #1
0
static mrb_value
mrb_env_setenv(mrb_state *mrb, mrb_value name, mrb_value value)
{
  if (mrb_type(name) != MRB_TT_STRING) {
    mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %s into String", mrb_obj_classname(mrb, name));
    return mrb_nil_value();
  }

  if (mrb_nil_p(value)) {
    return mrb_env_unsetenv(mrb, name);
  }

  if (mrb_type(value) != MRB_TT_STRING) {
    mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %s into String", mrb_obj_classname(mrb, value));
    return mrb_nil_value();
  }

  char *nam = mrb_string_value_ptr(mrb, name);
  char *val = mrb_string_value_ptr(mrb, value);
  if (setenv(nam, val, 1) != 0) {
    mrb_raise(mrb, E_RUNTIME_ERROR, "can't change environment variable");
    return mrb_nil_value();;
  }
  return value;
}
Example #2
0
int main(int argc, char** argv)
{
  const char rite[] = "app.mrb";

  mrb_state* mrb = mrb_open();

  FILE* fp = fopen(rite, "r");
  if (fp == NULL) {
    fprintf(stderr, "%s not found.\n", rite);
    fprintf(stderr, "`mruby/bin/mrbc app.rb` to create app.mrb file.\n");
    exit(EXIT_FAILURE);
  }

  int n = mrb_read_irep_file(mrb, fp);
  fclose(fp);
  if (n < 0) {
    fprintf(stderr, "%s - irep load error.\n", rite);
    exit(EXIT_FAILURE);
  }
  mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb));

  if (argc < 2) {
    printf("Usage %s <environment>\n", argv[0]);
    return 0;
  }

  // AppSetting
  struct RClass* clz = mrb_class_get(mrb, "AppSetting");
  mrb_value setting = mrb_obj_value(clz);
  // AppSetting.load(*targets) -> AppConfig
  mrb_value target = mrb_str_new(mrb, argv[1], strlen(argv[1]));
  mrb_value conf = mrb_funcall(mrb, setting, "load", 1, target);
  // AppConfig.#debug -> bool
  mrb_value debug = mrb_funcall(mrb, conf, "debug", 0);
  printf("debug: %d\n", mrb_type(debug) == MRB_TT_TRUE);
  // AppConfig.#timeout -> Integer
  mrb_value timeout = mrb_funcall(mrb, conf, "timeout", 0);
  printf("timeout: %d\n", timeout.value.i);
  // AppConfig.#title -> String
  mrb_value title = mrb_funcall(mrb, conf, "title", 0);
  printf("title: %s\n", mrb_string_value_ptr(mrb, title));
  // AppConfig.#messages -> Array
  mrb_value messages = mrb_funcall(mrb, conf, "messages", 0);
  {
    // Array.#size -> Integer
    mrb_value len = mrb_funcall(mrb, messages, "size", 0);
    int i;
    for (i = 0; i < len.value.i; i++) {
      // Array.#at(nth) -> object
      mrb_value message = mrb_funcall(mrb, messages, "at", 1, mrb_fixnum_value(i));
      printf("%s\n", mrb_string_value_ptr(mrb, message));
    }
  }

  mrb_close(mrb);

  return 0;
}
Example #3
0
static mrb_value
make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass * klass)
{
    mrb_value nstr, *ptr_members;
    mrb_sym id;
    long i, len;
    struct RClass *c;

    //OBJ_FREEZE(members);
    if (mrb_nil_p(name)) {
      c = mrb_class_new(mrb, klass);
      //mrb_make_metaclass(nstr, RBASIC(klass)->c);
      //mrb_class_inherited(klass, nstr);
    }
    else {
      /* old style: should we warn? */
      name = mrb_str_to_str(mrb, name);
      id = mrb_to_id(mrb, name);
      if (!mrb_is_const_id(id)) {
          //mrb_name_error(id, "identifier %s needs to be constant", StringValuePtr(name));
          mrb_name_error(mrb, id, "identifier %s needs to be constant", mrb_string_value_ptr(mrb, name));
      }
      if (mrb_const_defined_at(mrb, klass, id)) {
          //mrb_warn("redefining constant Struct::%s", StringValuePtr(name));
          mrb_warn("redefining constant Struct::%s", mrb_string_value_ptr(mrb, name));
          //?rb_mod_remove_const(klass, mrb_sym2name(mrb, id));
      }
      c = mrb_define_class_under(mrb, klass, RSTRING_PTR(name), klass);
    }
    MRB_SET_INSTANCE_TT(c, MRB_TT_STRUCT);
    nstr = mrb_obj_value(c);
    mrb_iv_set(mrb, nstr, mrb_intern(mrb, "__members__"), members);

    mrb_define_class_method(mrb, c, "new", mrb_class_new_instance_m, ARGS_ANY());
    mrb_define_class_method(mrb, c, "[]", mrb_class_new_instance_m, ARGS_ANY());
    mrb_define_class_method(mrb, c, "members", mrb_struct_s_members_m, ARGS_NONE());
    //RSTRUCT(nstr)->basic.c->super = c->c;
    ptr_members = RARRAY_PTR(members);
    len = RARRAY_LEN(members);
    for (i=0; i< len; i++) {
      mrb_sym id = SYM2ID(ptr_members[i]);
      if (mrb_is_local_id(id) || mrb_is_const_id(id)) {
          if (i < N_REF_FUNC) {
            mrb_define_method_id(mrb, c, id, (mrb_func_t)ref_func[i], 0);
          }
          else {
            mrb_define_method_id(mrb, c, id, mrb_struct_ref, 0);
          }
          mrb_define_method_id(mrb, c, mrb_id_attrset(id), (mrb_func_t)mrb_struct_set, 1);
      }
    }

    return nstr;
}
Example #4
0
static mrb_value
make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass * klass)
{
  mrb_value nstr, *ptr_members;
  mrb_sym id;
  mrb_int i, len;
  struct RClass *c;

  if (mrb_nil_p(name)) {
    c = mrb_class_new(mrb, klass);
  }
  else {
    /* old style: should we warn? */
    name = mrb_str_to_str(mrb, name);
    id = mrb_to_id(mrb, name);
    if (!mrb_is_const_id(id)) {
      mrb_raisef(mrb, E_NAME_ERROR, "identifier %s needs to be constant", mrb_string_value_ptr(mrb, name));
    }
    if (mrb_const_defined_at(mrb, klass, id)) {
      mrb_warn("redefining constant Struct::%s", mrb_string_value_ptr(mrb, name));
      //?rb_mod_remove_const(klass, mrb_sym2name(mrb, id));
    }
    c = mrb_define_class_under(mrb, klass, RSTRING_PTR(name), klass);
  }
  MRB_SET_INSTANCE_TT(c, MRB_TT_ARRAY);
  nstr = mrb_obj_value(c);
  mrb_iv_set(mrb, nstr, mrb_intern2(mrb, "__members__", 11), members);

  mrb_define_class_method(mrb, c, "new", mrb_instance_new, ARGS_ANY());
  mrb_define_class_method(mrb, c, "[]", mrb_instance_new, ARGS_ANY());
  mrb_define_class_method(mrb, c, "members", mrb_struct_s_members_m, ARGS_NONE());
  //RSTRUCT(nstr)->basic.c->super = c->c;
  ptr_members = RARRAY_PTR(members);
  len = RARRAY_LEN(members);
  for (i=0; i< len; i++) {
    mrb_sym id = mrb_symbol(ptr_members[i]);
    if (mrb_is_local_id(id) || mrb_is_const_id(id)) {
      if (i < N_REF_FUNC) {
        mrb_define_method_id(mrb, c, id, ref_func[i], ARGS_NONE());
      }
      else {
        mrb_define_method_id(mrb, c, id, mrb_struct_ref, ARGS_NONE());
      }
      mrb_define_method_id(mrb, c, mrb_id_attrset(mrb, id), mrb_struct_set_m, ARGS_REQ(1));
    }
  }
  return nstr;
}
Example #5
0
int main()
{
    mrb_state* mrb = mrb_open();

    // mrubyファイルをロードする
    FILE *fd = fopen("person.mrb", "r");
    mrb_load_irep_file(mrb, fd);

    // *.rbを直接ロードする
    // FILE *fd = fopen("person.rb", "r");
    // mrb_load_file(mrb, fd);

    // クラスオブジェクトを取得する
    struct RClass *person = mrb_class_get(mrb, "Person");

    // 引数をmrb_valueに変換する
    mrb_value person_value = mrb_obj_value(person);
    mrb_value name_value = mrb_str_new(mrb, "naoty", 5);
    mrb_value age_value = mrb_fixnum_value(25);

    // Person#newを呼び出す
    mrb_value naoty = mrb_funcall(mrb, person_value, "new", 2, name_value, age_value);

    // Person#greetingを呼び出す
    mrb_value greeting_value = mrb_funcall(mrb, naoty, "greeting", 0);

    // 返り値をchar*に変換して出力する
    char *greeting = mrb_string_value_ptr(mrb, greeting_value);
    printf("%s\n", greeting);

    mrb_close(mrb);
    return 0;
}
Example #6
0
mrb_value
cfunc_rubyvm_dispatch(mrb_state *mrb, mrb_value self)
{
    struct cfunc_rubyvm_data *data = mrb_get_datatype(mrb, self, &cfunc_rubyvm_data_type);

    mrb_value name_obj, *args;
    int args_len;
    mrb_get_args(mrb, "o*", &name_obj, &args, &args_len);

    struct queue_task *task = malloc(sizeof(struct queue_task));
    task->refcount = 2;
    task->result = NULL;
    task->status = queue_task_queued;

    pthread_mutex_init(&task->sync_mutex, NULL);
    pthread_cond_init(&task->sync_cond, NULL);

    const char* name = mrb_string_value_ptr(mrb, name_obj);
    int name_len = strlen(name);
    task->name = malloc(name_len+1);
    strncpy(task->name, name, name_len+1);

    task->args_len = args_len;
    task->args = malloc(sizeof(struct task_arg) * task->args_len);
    for(int i=0; i<args_len; ++i) {
        task->args[i] = mrb_value_to_task_arg(mrb, args[i]);
    }

    pthread_mutex_lock(&data->queue_mutex);
    vector_enqueue(data->queue, task);
    pthread_cond_signal(&data->queue_cond);
    pthread_mutex_unlock(&data->queue_mutex);

    return mrb_obj_value((struct RObject *)Data_Wrap_Struct(mrb, cfunc_state(mrb)->rubyvm_task_class, &cfunc_rubyvm_task_data_type, task));
}
Example #7
0
mrb_value 
mrb_dir_entries(mrb_state* mrb, mrb_value self)
{
  mrb_value entries = mrb_ary_new(mrb);
  mrb_value dirname;
  mrb_get_args(mrb, "S", &dirname);
  const char* name = mrb_string_value_ptr(mrb, dirname);

  tinydir_dir dir;  
  if (tinydir_open(&dir, name) == -1)
  {
    mrb_raisef(mrb, E_RUNTIME_ERROR, "Error opening file: %S", mrb_str_new_cstr(mrb, name));
  }

  while (dir.has_next) {
    tinydir_file file;
    tinydir_readfile(&dir, &file);
    
    mrb_ary_push(mrb, entries, mrb_str_new_cstr(mrb, file.name));
      
    tinydir_next(&dir);
  } 
  tinydir_close(&dir);

  return entries;
}
Example #8
0
File: kernel.c Project: hu90/mruby
/*
 *  call-seq:
 *     obj.send(symbol [, args...])        -> obj
 *     obj.__send__(symbol [, args...])      -> obj
 *
 *  Invokes the method identified by _symbol_, passing it any
 *  arguments specified. You can use <code>__send__</code> if the name
 *  +send+ clashes with an existing method in _obj_.
 *
 *     class Klass
 *       def hello(*args)
 *         "Hello " + args.join(' ')
 *       end
 *     end
 *     k = Klass.new
 *     k.send :hello, "gentle", "readers"   #=> "Hello gentle readers"
 */
static mrb_value
mrb_f_send(mrb_state *mrb, mrb_value self)
{
  mrb_value name, block, *argv;
  int argc;
  
  mrb_get_args(mrb, "o*&", &name, &argv, &argc, &block);
  return mrb_funcall_with_block(mrb,self, mrb_string_value_ptr(mrb, name), argc, argv, block);
}
Example #9
0
static mrb_value
mrb_curses_addstr(mrb_state *mrb, mrb_value self)
{
  mrb_value obj;

  mrb_get_args(mrb, "S", &obj);
  const char *body = mrb_string_value_ptr(mrb, obj);
  addstr(body);
  return mrb_bool_value(true);
}
Example #10
0
static mrb_value rb_load_compiled_mrb(mrb_state *mrb, mrb_value self)
{
  mrb_value rstr;
  const char *str;

  mrb_get_args(mrb, "S", &rstr);
  str = mrb_string_value_ptr(mrb, rstr);

  return mrbcc_load_so(mrb, self, str);
}
Example #11
0
static mrb_sym
mrb_sym_value(mrb_state *mrb, mrb_value val)
{
  if(val.tt == MRB_TT_STRING) {
    return mrb_intern(mrb, RSTRING_PTR(val));
  }
  else if(val.tt != MRB_TT_SYMBOL) {
    mrb_value obj = mrb_funcall(mrb, val, "inspect", 0);
    mrb_raise(mrb, E_TYPE_ERROR, "%s is not a symbol",
         mrb_string_value_ptr(mrb, obj));
  }
  return mrb_symbol(val);
}
Example #12
0
static mrb_sym
mrb_sym_value(mrb_state *mrb, mrb_value val)
{
  if (mrb_string_p(val)) {
    return mrb_intern_str(mrb, val);
  }
  else if(!mrb_symbol_p(val)) {
    mrb_value obj = mrb_funcall(mrb, val, "inspect", 0);
    mrb_raisef(mrb, E_TYPE_ERROR, "%s is not a symbol",
         mrb_string_value_ptr(mrb, obj));
  }
  return mrb_symbol(val);
}
Example #13
0
static mrb_value
mrb_curses_ewaddstr(mrb_state *mrb, mrb_value self)
{
  if (echo_win == NULL) {
    return mrb_bool_value(false);
  }

  mrb_value obj;
  mrb_get_args(mrb, "S", &obj);
  const char *body = mrb_string_value_ptr(mrb, obj);
  waddstr(echo_win, body);

  return mrb_bool_value(true);
}
Example #14
0
int main()
{

  mrb_state* mrb;
  int n;
  FILE* f;
  mrb_value ret;

  mrb = mrb_open();
  f = fopen("test.rb", "r");
  mrb_load_file(mrb, f);
  fclose(f);

  ret = mrb_funcall(mrb, mrb_top_self(mrb), "test", 1, mrb_fixnum_value(20) );
  
  //mrb_define_method(mrb, mrb->kernel_module, "cursor_move", cursor_move, MRB_ARGS_REQ(2));
//------------------------------------------

  int  x, y;
  int key=' ';
  char *str;
  initscr();
  keypad(stdscr, TRUE);

  setlocale(LC_ALL, "");

  x = 0;
  y = 0;

  while (1) {
    key = getch();
    ret = mrb_funcall(mrb, mrb_top_self(mrb), "evaluate", 1, mrb_fixnum_value(key) );
    str = mrb_string_value_ptr(mrb, ret);
    addstr(str);
    if (key == 'q') break;
    switch (key) {
      case KEY_UP: y--; break;
      case KEY_DOWN: y++; break;
      case KEY_LEFT: x--; break;
      case KEY_RIGHT: x++; break;
      default : mvprintw(y, x++, "%c", key); break;
    }
    move(y, x);
    //mrb_load_string(mrb,"cursor_move(x, y);");
  }
  endwin();
  mrb_close(mrb);
  return (0);
}
Example #15
0
static mrb_value
mrb_env_unsetenv(mrb_state *mrb, mrb_value name)
{
  mrb_value val = mrb_env_getenv(mrb, name);
  if (mrb_nil_p(val)) {
    return mrb_nil_value();
  }

  char *nam = mrb_string_value_ptr(mrb, name);
  if (unsetenv(nam) != 0) {
    mrb_raise(mrb, E_RUNTIME_ERROR, "can't delete environment variable");
    return mrb_nil_value();
  }
  return val;
}
Example #16
0
static mrb_value
mrb_env_getenv(mrb_state *mrb, mrb_value name)
{
  if (mrb_type(name) != MRB_TT_STRING) {
    mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %s into String", mrb_obj_classname(mrb, name));
    return mrb_nil_value();
  }

  char *nam = mrb_string_value_ptr(mrb, name);
  char *env = getenv(nam);
  if (env == NULL) {
    return mrb_nil_value();
  }
  return mrb_str_new2(mrb, env);
}
Example #17
0
mrb_value
mrb_dir_exists(mrb_state* mrb, mrb_value self)
{
  mrb_value dirname;
  mrb_get_args(mrb, "S", &dirname);
  const char* name = mrb_string_value_ptr(mrb, dirname);

  tinydir_dir dir;
  if (tinydir_open(&dir, name) == -1) {
    return mrb_false_value();
  }
  tinydir_close(&dir);

  return mrb_true_value();
}
Example #18
0
void
mrb_cmperr(mrb_state *mrb, mrb_value x, mrb_value y)
{
  const char *classname;

  if (SPECIAL_CONST_P(y)) {
    y = mrb_inspect(mrb, y);
    //classname = StringValuePtr(y);
    classname = mrb_string_value_ptr(mrb, y);
  }
  else {
    classname = mrb_obj_classname(mrb, y);
  }
  mrb_raise(mrb, E_ARGUMENT_ERROR, "comparison of %s with %s failed",
	    mrb_obj_classname(mrb, x), classname);
}
Example #19
0
File: mrb4R.c Project: rcqls/mrb4R
//convert rbObj in RVector (assumed to be possible!!!)
SEXP mrbArray2RVector(mrb_value rbobj)
{
  SEXP ans;
  mrb_value arr,elt,tmp;
  //char *name;
  int n,i;
  
  if(!mrb_obj_is_kind_of(mrb,rbobj,mrb->array_class)) {
    if(!(mrb_obj_is_kind_of(mrb,rbobj,mrb->fixnum_class) || mrb_obj_is_kind_of(mrb,rbobj,mrb->float_class) || mrb_obj_is_kind_of(mrb,rbobj,mrb->string_class) || mrb_obj_is_kind_of(mrb,rbobj,mrb->true_class) || mrb_obj_is_kind_of(mrb,rbobj,mrb->false_class))) 
      return R_NilValue;
    n=1;
    arr = mrb_ary_new_capa(mrb,1);
    mrb_ary_push(mrb,arr,rbobj);
  } else {
    arr=rbobj;
    n=RARRAY_LEN(rbobj);  
  }

  //Rprintf("n=%d\n",n);

  elt=mrb_ary_entry(arr,0);

  if(mrb_type(elt)==MRB_TT_FLOAT) {
    PROTECT(ans=allocVector(REALSXP,n));
    for(i=0;i<n;i++) {
      REAL(ans)[i]=mrb_float(mrb_ary_entry(arr,i));
    }
  } else if(mrb_type(elt)==MRB_TT_FIXNUM) {
    PROTECT(ans=allocVector(INTSXP,n));
    for(i=0;i<n;i++) {
      INTEGER(ans)[i]=mrb_int(mrb,mrb_ary_entry(arr,i));
    }
  } else if(mrb_type(elt)==MRB_TT_TRUE || mrb_type(elt)==MRB_TT_FALSE) {
    PROTECT(ans=allocVector(LGLSXP,n));
    for(i=0;i<n;i++) {
      LOGICAL(ans)[i]=(mrb_type(mrb_ary_entry(arr,i))==MRB_TT_FALSE ? FALSE : TRUE);
    }
  } else if(mrb_type(elt)==MRB_TT_STRING) {
    PROTECT(ans=allocVector(STRSXP,n));
    for(i=0;i<n;i++) {
      tmp=mrb_ary_entry(arr,i);
      SET_STRING_ELT(ans,i,mkChar(mrb_string_value_ptr(mrb,tmp)));
    }
  } else ans=R_NilValue;
  UNPROTECT(1);
  return ans; 
}
Example #20
0
mrb_value 
mrb_game_reload_file(mrb_state* mrb, mrb_value self)
{
  mrb_value path;
  mrb_get_args(mrb, "S", &path);

  char* file_path = mrb_string_value_ptr(mrb, path);

  FILE* file = fopen(file_path, "r");
  if (file == NULL) {
    printf("Error opening file: %s\n", file_path);
    return self;
  }

  mrb_load_file(mrb,file);

  fclose(file);

  return self;
}
Example #21
0
mrb_value
qgame_shader_asset_load_from_file(mrb_state* mrb, mrb_value self)
{
  mrb_value path;  
  mrb_sym shader_type_sym;
  mrb_get_args(mrb, "nS", &shader_type_sym, &path);

  GLenum shader_type = shader_type_sym_to_enum(mrb, shader_type_sym);

  GLuint shader = glCreateShader(shader_type);
  if(shader == 0) {
    mrb_raisef(mrb, E_RUNTIME_ERROR, "Failed creating shader with type: %i", mrb_fixnum_value(shader_type));
    return self;
  }

  char* shader_source = read_file(mrb_string_value_ptr(mrb, path));
  glShaderSource(shader, 1, (const GLchar**)&shader_source, NULL);
  glCompileShader(shader);
  free(shader_source);

  GLint status;
  glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
  if (status == GL_FALSE) {
      
      GLint infoLogLength;
      glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
      char strInfoLog[infoLogLength + 1];
      glGetShaderInfoLog(shader, infoLogLength, NULL, strInfoLog);

      glDeleteShader(shader); shader = NULL;
      mrb_raisef(mrb, E_RUNTIME_ERROR, "Failed compiling shader '%S': %S", path, mrb_str_new_cstr(mrb, &strInfoLog));
      return self;
  }

  mrb_value shader_id = mrb_fixnum_value(shader);
  mrb_iv_set(mrb, self, mrb_intern(mrb, "shader_id"), shader_id);

  return self;
}
Example #22
0
static mrb_value
cfunc_call(mrb_state *mrb, mrb_value self)
{
    int margc;
    mrb_value mresult_type, mname, *margs;
    void **values = NULL;
    ffi_type **args = NULL;

    mrb_get_args(mrb, "oo*", &mresult_type, &mname, &margs, &margc);

    void *fp = NULL;
    if(mrb_string_p(mname) || mrb_symbol_p(mname)) {
        void *dlh = dlopen(NULL, RTLD_LAZY);
        fp = dlsym(dlh, mrb_string_value_ptr(mrb, mname));
        dlclose(dlh);
    }
    else {
        fp = cfunc_pointer_ptr(mname);
    }

    if(fp == NULL) {
        mrb_raisef(mrb, E_NAME_ERROR, "can't find C function %s", mrb_string_value_ptr(mrb, mname));
        goto cfunc_call_exit;
    }

    args = malloc(sizeof(ffi_type*) * margc);
    values = malloc(sizeof(void*) * margc);
    mrb_sym sym_to_ffi_value = mrb_intern(mrb, "to_ffi_value");

    mrb_value nil_ary[1];
    nil_ary[0] = mrb_nil_value();
    for(int i = 0; i < margc; ++i) {
        if(mrb_respond_to(mrb, margs[i], sym_to_ffi_value)) {
            args[i] = mrb_value_to_mrb_ffi_type(mrb, margs[i])->ffi_type_value;
            values[i] = cfunc_pointer_ptr(mrb_funcall_argv(mrb, margs[i], sym_to_ffi_value, 1, nil_ary));
        }
        else {
            cfunc_mrb_raise_without_jump(mrb, E_TYPE_ERROR, "ignore argument type %s", mrb_obj_classname(mrb, margs[i]));
            goto cfunc_call_exit;
        }
    }

    ffi_type *result_type = rclass_to_mrb_ffi_type(mrb, mrb_class_ptr(mresult_type))->ffi_type_value;
    if (result_type == NULL) {
        cfunc_mrb_raise_without_jump(mrb, E_ARGUMENT_ERROR, "ignore return type %s", mrb_class_name(mrb, mrb_class_ptr(mresult_type)));
        goto cfunc_call_exit;
    }

    mrb_value mresult = mrb_nil_value();
    ffi_cif cif;
    if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, margc, result_type, args) == FFI_OK) {
        void *result;
        if(result_type->size > sizeof(long)) {
            result = malloc(result_type->size);
        }
        else if(result_type->size) {
            result = malloc(sizeof(long));
        }
        else {
            result = NULL;
        }
        ffi_call(&cif, fp, result, values);

        if(result) {
            mrb_value result_ptr = cfunc_pointer_new_with_pointer(mrb, result, true);
            mresult = mrb_funcall(mrb, mresult_type, "refer", 1, result_ptr);
        }
    }
    else {
        mrb_raisef(mrb, E_NAME_ERROR, "Can't find C function %s", mname);
        goto cfunc_call_exit;
    }

cfunc_call_exit:
    free(values);
    free(args);
    return mresult;
}
Example #23
0
static const char *_mrb_string(mrb_state* mrb, mrb_value o) { return mrb_string_value_ptr(mrb, o); }
Example #24
0
mrb_value
qgame_texture_asset_load_from_file(mrb_state* mrb, mrb_value self)
{
  GLuint texture;     // This is a handle to our texture object
  SDL_Surface *surface; // This surface will tell us the details of the image
  GLenum texture_format;

  mrb_value path;
  mrb_get_args(mrb, "S", &path);
  char* file = mrb_string_value_ptr(mrb, path);

  if ( (surface = IMG_Load(file)) ) { 
    // Check that the image's width is a power of 2
    if ( (surface->w & (surface->w - 1)) != 0 ) {
      printf("warning: %s's width is not a power of 2\n", file);
    }
   
    // Also check if the height is a power of 2
    if ( (surface->h & (surface->h - 1)) != 0 ) {
      printf("warning: %s's height is not a power of 2\n", file);
    }

    // get the number of channels in the SDL surface
    GLint  nOfColors = surface->format->BytesPerPixel;
    if (nOfColors == 4)     // contains an alpha channel
    {
      if (surface->format->Rmask == 0x000000ff)
        texture_format = GL_RGBA;
      else
        texture_format = GL_BGRA;
    } else if (nOfColors == 3)     // no alpha channel
    {
      if (surface->format->Rmask == 0x000000ff)
        texture_format = GL_RGB;
      else
        texture_format = GL_BGRA;
    } else {
      printf("warning: the image is not truecolor..  this will probably break\n");
    }

    // Have OpenGL generate a texture object handle for us
    glGenTextures( 1, &texture );
   
    // Bind the texture object
    glBindTexture( GL_TEXTURE_2D, texture );
   
    // Set the texture's stretching properties
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    // Edit the texture object's image data using the information SDL_Surface gives us
    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0,
                        texture_format, GL_UNSIGNED_BYTE, surface->pixels );
    
    GLenum err = glGetError();
    if (err != GL_NO_ERROR) {
      printf("Error loading image into GL: %i\n", err);
    }
    
    mrb_value texture_id = mrb_fixnum_value(texture);
    mrb_iv_set(mrb, self, mrb_intern(mrb, "texture_id"), texture_id);
    
    mrb_value mrb_width = mrb_fixnum_value(surface->w);
    mrb_iv_set(mrb, self, mrb_intern(mrb, "@width"), mrb_width);
  
    mrb_value mrb_height = mrb_fixnum_value(surface->h);
    mrb_iv_set(mrb, self, mrb_intern(mrb, "@height"), mrb_height);
  }
  else {
    printf("SDL could not load image.bmp: %s\n", SDL_GetError());
  }    

  // Free the SDL_Surface only if it was successfully created
  if ( surface ) { 
    SDL_FreeSurface( surface );
  }

  return self;
}