bool rubyval_to_std_vector_string(mrb_state* mrb, mrb_value arg, std::vector<std::string>* ret, const char* funcName)
{
    if (! mrb_array_p(arg)) {
        return false;
    }
    
    mrb_int len = mrb_ary_len(mrb, arg);
    for (mrb_int i = 0; i < len; i++) {
        mrb_value v = mrb_ary_ref(mrb, arg, i);
        std::string str = "";
        if (mrb_fixnum_p(v)) {
            mrb_int val = mrb_fixnum(v);
            char *cstr = nullptr;
            sprintf(cstr, "%d", val);
            str = std::string(cstr);
        } else if (mrb_float_p(v)) {
            mrb_float val = mrb_float(v);
            char *cstr = nullptr;
            sprintf(cstr, "%f", val);
            str = std::string(cstr);
        }
        ret->push_back(str);
    }
    
    return true;
}
예제 #2
0
static mrb_value
mrb_sdl2_video_surface_fill_rects(mrb_state *mrb, mrb_value self)
{
    uint32_t color;
    mrb_value rects;
    mrb_get_args(mrb, "io", &color, &rects);
    if (!mrb_array_p(rects)) {
        mrb_raise(mrb, E_TYPE_ERROR, "given 2nd argument is unexpected type (expected Array).");
    }
    mrb_int const n = mrb_ary_len(mrb, rects);
    SDL_Surface *s = mrb_sdl2_video_surface_get_ptr(mrb, self);
    SDL_Rect r[n];
    mrb_int i;
    for (i = 0; i < n; ++i) {
        SDL_Rect const * const ptr = mrb_sdl2_rect_get_ptr(mrb, mrb_ary_ref(mrb, rects, i));
        if (NULL != ptr) {
            r[i] = *ptr;
        } else {
            r[i] = (SDL_Rect) {
                0, 0, 0, 0
            };
        }
    }
    if (0 != SDL_FillRects(s, r, n, color)) {
        mruby_sdl2_raise_error(mrb);
    }
    return self;
}
bool rubyval_to_ccvaluemapintkey(mrb_state* mrb, mrb_value arg, cocos2d::ValueMapIntKey* ret, const char* funcName)
{
    if (! mrb_hash_p(arg)) {
        return false;
    }
    
    mrb_value key_arr = mrb_hash_keys(mrb, arg);
    mrb_int len = mrb_ary_len(mrb, key_arr);
    ValueMapIntKey& dict = *ret;
    for (mrb_int i = 0; i < len; i++) {
        mrb_value hk = mrb_ary_ref(mrb, key_arr, i);
        mrb_value hv = mrb_hash_get(mrb, arg, hk);
        int int_key = 0;
        
        if (mrb_string_p(hk)) {
            char *kstr = mrb_str_to_cstr(mrb, hk);
            int_key = atoi(kstr);
        } else if (mrb_symbol_p(hk)) {
            mrb_sym sym = mrb_symbol(hk);
            const char* kstr = mrb_sym2name(mrb, sym);
            int_key = atoi(kstr);
        } else {
            return false;
        }
        Value val;
        if (! rubyval_to_ccvalue(mrb, hv, &val)) {
            return false;
        }
        
        dict[int_key] = val;
    }
    return true;
}
bool rubyval_to_dictionary(mrb_state* mrb, mrb_value arg, __Dictionary** outValue, const char* funcName)
{
    if (! mrb_hash_p(arg)) {
        return false;
    }
    
    mrb_value key_arr = mrb_hash_keys(mrb, arg);
    mrb_int len = mrb_ary_len(mrb, key_arr);
    __Dictionary* dic = __Dictionary::create();
    for (mrb_int i = 0; i < len; i++) {
        mrb_value hk = mrb_ary_ref(mrb, key_arr, i);
        mrb_value hv = mrb_hash_get(mrb, arg, hk);
        if (mrb_string_p(hk)) {
            char *kstr = mrb_str_to_cstr(mrb, hk);
            Ref* ref = to_ref_value(mrb, hv);
            dic->setObject(ref, std::string(kstr));
        } else if (mrb_symbol_p(hk)) {
            mrb_sym sym = mrb_symbol(hk);
            const char* kstr = mrb_sym2name(mrb, sym);
            Ref* ref = to_ref_value(mrb, hv);
            dic->setObject(ref, std::string(kstr));
        } else {
            CCASSERT(false, "not supported key value type");
        }
    }
    *outValue = dic;
    
    return true;
}
mrb_value ruby_global_require(mrb_state* mrb, mrb_value self)
{
    
    const char* filename_cstr = nullptr;
    mrb_get_args(mrb, "z", &filename_cstr);
    std::string filename(filename_cstr);
    
    auto engine = cocos2d::RubyEngine::getInstance();
    std::string realfile = engine->findFile(filename);
    
    mrb_value loaded_path_arr = mrb_gv_get(mrb, mrb_intern_cstr(mrb, "$LOADED_FEATURES"));
    if (mrb_array_p(loaded_path_arr)) {
        mrb_int len = mrb_ary_len(mrb, loaded_path_arr);
        for (mrb_int i = 0; i < len; i++) {
            mrb_value path = mrb_ary_ref(mrb, loaded_path_arr, i);
            const char* path_cstr = mrb_str_to_cstr(mrb, path);
            if (realfile.compare(path_cstr) == 0) {
                return mrb_nil_value();
            }
        }
    }
    
    if (! mrb_array_p(loaded_path_arr)) {
        loaded_path_arr = mrb_ary_new(mrb);
        mrb_value path = mrb_str_new_cstr(mrb, realfile.c_str());
        mrb_ary_push(mrb, loaded_path_arr, path);
        mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$LOADED_FEATURES"), loaded_path_arr);
    } else {
        mrb_value path = mrb_str_new_cstr(mrb, realfile.c_str());
        mrb_ary_push(mrb, loaded_path_arr, path);
    }
    engine->executeScriptFile(realfile.c_str());
    
    return mrb_nil_value();
}
bool rubyval_to_array(mrb_state* mrb, mrb_value arg, __Array** outValue, const char* funcName)
{
    if (! mrb_array_p(arg)) {
        return false;
    }
    
    mrb_int len = mrb_ary_len(mrb, arg);
    __Array* arr =  __Array::createWithCapacity(len);
    for (mrb_int i = 0; i < len; i++) {
        mrb_value val = mrb_ary_ref(mrb, arg, i);
        Ref* ref = to_ref_value(mrb, val);
        arr->addObject(ref);
    }
    *outValue = arr;
        
    return true;
}
bool rubyval_to_ccvaluevector(mrb_state* mrb, mrb_value arg, cocos2d::ValueVector* ret, const char* funcName)
{
    if (! mrb_array_p(arg)) {
        return false;
    }
    
    mrb_int len = mrb_ary_len(mrb, arg);
    for (mrb_int i = 0; i < len; i++) {
        mrb_value v = mrb_ary_ref(mrb, arg, i);
        Value val;
        if (! rubyval_to_ccvalue(mrb, v, &val)) {
            return false;
        }
        ret->push_back(val);
    }
    
    return true;
}
bool rubyval_to_carray_float(mrb_state* mrb, mrb_value arg, float** outValue, const char* funcName)
{
    if (! mrb_array_p(arg)) {
        return false;
    }
    
    mrb_int len = mrb_ary_len(mrb, arg);
    float arr[len];
    for (mrb_int i = 0; i < len; i++) {
        mrb_value val = mrb_ary_ref(mrb, arg, i);
        if (! mrb_float_p(val)) {
            return false;
        }
        arr[i] = mrb_float(val);
    }
    *outValue = arr;
    
    return true;
}
예제 #9
0
int main(int argc, char const *argv[])
{
#ifdef _MEM_PROFILER
  uint8_t checkpoint_set = 0;
#endif
  fd_set rfds;
  char buffer[PIPE_BUFFER_SIZE];
  int i, n;
  Plugin plugins[MAX_PLUGINS];
  int plugins_count = 0;
  mrb_state *mrb;
  mrb_value r_output, r_plugins_list;
  mrb_sym output_gv_sym, plugins_to_load_gv_sym;
  
  printf("Version: %s\n", PROBE_VERSION);
  
  if( argc != 2 ){
    printf("Usage: %s <config_path>\n", argv[0]);
    exit(1);
  }
  
#ifdef _MEM_PROFILER
  init_profiler();
#endif
  
  config_path = argv[1];
  
  printf("Initializing core...\n");
  mrb = mrb_open_allocf(profiler_allocf, "main");
  output_gv_sym = mrb_intern_cstr(mrb, "$output");
  plugins_to_load_gv_sym = mrb_intern_cstr(mrb, "$plugins_to_load");
  setup_api(mrb);
  execute_file(mrb, "plugins/main.rb");
  execute_file(mrb, config_path);
  
  printf("Loading plugins...\n");
  r_plugins_list = mrb_gv_get(mrb, plugins_to_load_gv_sym);
  for(i = 0; i< mrb_ary_len(mrb, r_plugins_list); i++){
    char *path, tmp[100];
    int ssize;
    
    mrb_value r_plugin_name = mrb_ary_ref(mrb, r_plugins_list, i);
    const char *plugin_name = mrb_string_value_cstr(mrb, &r_plugin_name);
    
    snprintf(tmp, sizeof(tmp) - 1, "plugins/%s.rb", plugin_name);
    ssize = strlen(tmp);
    
    path = malloc(ssize + 1);
    strncpy(path, tmp, ssize);
    path[ssize] = '\0';
    
    if( access(path, F_OK) == -1 ){
      printf("cannot open plugin file \"%s\": %s\n", path, strerror(errno));
      exit(1);
    }
    
    init_plugin_from_file(&plugins[plugins_count], path, plugin_name); plugins_count++;
  }
  
  printf("Instanciating output class...\n");
  r_output = mrb_gv_get(mrb, output_gv_sym);
  interval = mrb_fixnum(mrb_funcall(mrb, r_output, "interval", 0));
  
  printf("Interval set to %dms\n", (int)interval);
  
  printf("Sending initial report...\n");
  mrb_funcall(mrb, r_output, "send_report", 0);
  
  if (mrb->exc) {
    mrb_print_error(mrb);
    
    exit(1);
  }

  
  // start all the threads
  for(i= 0; i< plugins_count; i++){
    // printf("== plugin %d\n", i);
    n = pthread_create(&plugins[i].thread, NULL, plugin_thread, (void *)&plugins[i]);
    if( n < 0 ){
      fprintf(stderr, "create failed\n");
    }
  }
  
  if( signal(SIGINT, clean_exit) == SIG_ERR){
    perror("signal");
    exit(1);
  }
  
  while(running){
    int fds[MAX_PLUGINS];
    int maxfd = 0, ai;
    struct timeval tv;
    mrb_value r_buffer;
    struct timeval cycle_started_at, cycle_completed_at;
    
    gettimeofday(&cycle_started_at, NULL);
    
    bzero(fds, sizeof(int) * MAX_PLUGINS);
    
    // ask every plugin to send their data
    for(i= 0; i< plugins_count; i++){
      strcpy(buffer, "request");
      if( send(plugins[i].host_pipe, buffer, strlen(buffer), 0) == -1 ){
        printf("send error when writing in pipe connected to plugin '%s'\n", plugins[i].name);
      }
      fds[i] = plugins[i].host_pipe;
      // printf("sent request to %d\n", i);
    }
    
    // printf("waiting answers...\n");
    // and now wait for each answer
    while(1){
      int left = 0;
      
      FD_ZERO(&rfds);
      
      for(i = 0; i< MAX_PLUGINS; i++){
        if( fds[i] != NOPLUGIN_VALUE ){
          FD_SET(fds[i], &rfds);
          left++;
          if( fds[i] > maxfd )
            maxfd = fds[i];
        }
      }
      
      // printf("left: %d %d\n", left, left <= 0);
      
      if( !running || (0 == left) )
        break;
      
      // substract 20ms to stay below the loop delay
      fill_timeout(&tv, cycle_started_at, interval - 20);
      // printf("before select\n");
      n = select(maxfd + 1, &rfds, NULL, NULL, &tv);
      // printf("after select: %d\n", n);
      if( n > 0 ){
        // find out which pipes have data
        for(i = 0; i< MAX_PLUGINS; i++){
          if( (fds[i] != NOPLUGIN_VALUE) && FD_ISSET(fds[i], &rfds) ){
            while (1){
              struct timeval answered_at;
              n = read(fds[i], buffer, sizeof(buffer));
              if( n == -1 ){
                if( errno != EAGAIN )
                  perror("read");
                break;
              }
              
              if( n == PIPE_BUFFER_SIZE ){
                printf("PIPE_BUFFER_SIZE is too small, increase it ! (value: %d)\n", PIPE_BUFFER_SIZE);
                continue;
              }
              
              gettimeofday(&answered_at, NULL);
              // printf("received answer from %s in %u ms\n", (const char *) plugins[i].mrb->ud,
              //     (uint32_t)((answered_at.tv_sec - cycle_started_at.tv_sec) * 1000 +
              //     (answered_at.tv_usec - cycle_started_at.tv_usec) / 1000)
              //   );
              
              buffer[n] = 0x00;
              
              ai = mrb_gc_arena_save(mrb);
              r_buffer = mrb_str_buf_new(mrb, n);
              mrb_str_buf_cat(mrb, r_buffer, buffer, n);
              
              // mrb_funcall(mrb, r_output, "tick", 0);
              mrb_funcall(mrb, r_output, "add", 1, r_buffer);
              check_exception("add", mrb);
              
              // pp(mrb, r_output, 0);
              
              mrb_gc_arena_restore(mrb, ai);
            }
            
            fds[i] = 0;
          }
        }
      }
      else if( n == 0 )  {
        printf("no responses received from %d plugins.\n", left);
        break;
        // timeout
      }
      else {
        perror("select");
      }
    }
    
    int idx = mrb_gc_arena_save(mrb);
    mrb_funcall(mrb, r_output, "flush", 0);
    check_exception("flush", mrb);
    mrb_gc_arena_restore(mrb, idx);
    
    // and now sleep until the next cycle
    gettimeofday(&cycle_completed_at, NULL);
    
  #ifdef _MEM_PROFILER
    if( checkpoint_set ){
      print_allocations();
    }
  #endif
    
    // force a gc run at the end of each cycle
    mrb_full_gc(mrb);
    // printf("[main] capa: %d / %d\n", mrb->arena_idx, mrb->arena_capa);
    // for(i= 0; i< plugins_count; i++){
    //   printf("[%s] capa: %d / %d\n", plugins[i].name, plugins[i].mrb->arena_idx, plugins[i].mrb->arena_capa);
    // }
  
  #ifdef _MEM_PROFILER
    checkpoint_set = 1;
    // and set starting point
    profiler_set_checkpoint();
  #endif

    
  #ifdef _MEM_PROFILER_RUBY
    // dump VMS state
    dump_state(mrb);
    for(i= 0; i< plugins_count; i++){
      dump_state(plugins[i].mrb);
    }
  #endif
    
    fflush(stdout);
    sleep_delay(&cycle_started_at, &cycle_completed_at, interval);
  }
  
  printf("Sending exit signal to all plugins...\n");
  strcpy(buffer, "exit");
  for(i= 0; i< plugins_count; i++){
    C_CHECK("send", send(plugins[i].host_pipe, buffer, strlen(buffer), 0) );
  }
  
  printf("Giving some time for threads to exit...\n\n");
  really_sleep(2000);
  
  
  for(i= 0; i< plugins_count; i++){
    int ret = pthread_kill(plugins[i].thread, 0);
    
    // if a success is returned then the thread is still alive
    // which means the thread did not acknoledged the exit message
    // kill it.
    if( ret == 0 ){
      printf("    - plugin \"%s\" failed to exit properly, killing it...\n", (const char *) plugins[i].mrb->ud);
      pthread_cancel(plugins[i].thread);
    }
    else {
      printf("    - plugin \"%s\" exited properly.\n", (const char *) plugins[i].mrb->allocf_ud);
    }
    
    if( pthread_join(plugins[i].thread, NULL) < 0){
      fprintf(stderr, "join failed\n");
    }
    
    mrb_close(plugins[i].mrb);
  }
  
  mrb_close(mrb);
  
  printf("Exited !\n");
  return 0;
}
예제 #10
0
파일: yaml.c 프로젝트: hone/mruby-yaml
int value_to_node(mrb_state *mrb,
  yaml_document_t *document, mrb_value value)
{
  int node;

  switch (mrb_type(value))
  {
    case MRB_TT_ARRAY:
    {
      mrb_int len = mrb_ary_len(mrb, value);
      mrb_int i;
      int ai = mrb_gc_arena_save(mrb);

      node = yaml_document_add_sequence(document, NULL,
        YAML_ANY_SEQUENCE_STYLE);

      for (i = 0; i < len; i++)
      {
        mrb_value child = mrb_ary_ref(mrb, value, i);
        int child_node = value_to_node(mrb, document, child);

        /* Add the child to the sequence */
        yaml_document_append_sequence_item(document, node, child_node);
        mrb_gc_arena_restore(mrb, ai);
      }

      break;
    }

    case MRB_TT_HASH:
    {
      /* Iterating a list of keys is slow, but it only
       * requires use of the interface defined in `hash.h`.
       */

      mrb_value keys = mrb_hash_keys(mrb, value);
      mrb_int len = mrb_ary_len(mrb, keys);
      mrb_int i;
      int ai = mrb_gc_arena_save(mrb);

      node = yaml_document_add_mapping(document, NULL,
        YAML_ANY_MAPPING_STYLE);

      for (i = 0; i < len; i++)
      {
        mrb_value key = mrb_ary_ref(mrb, keys, i);
        mrb_value child = mrb_hash_get(mrb, value, key);

        int key_node = value_to_node(mrb, document, key);
        int child_node = value_to_node(mrb, document, child);

        /* Add the key/value pair to the mapping */
        yaml_document_append_mapping_pair(document, node,
          key_node, child_node);
        mrb_gc_arena_restore(mrb, ai);
      }

      break;
    }

    default:
    {
      if (mrb_nil_p(value)) {
        /* http://yaml.org/type/null.html
           Canonical form */
        value = mrb_str_new_lit(mrb, "~");
      } else {
        /* Equivalent to `obj = obj#to_s` */
        value = mrb_obj_as_string(mrb, value);
      }
      /* Fallthrough */
    }

    case MRB_TT_STRING:
    {
      yaml_scalar_style_t style = YAML_ANY_SCALAR_STYLE;
      if (RSTRING_LEN(value) == 0) {
        /* If the String is empty, it may be reloaded as a nil instead of an
         * empty string, to avoid that place a quoted string instead */
        style = YAML_SINGLE_QUOTED_SCALAR_STYLE;
      }
      yaml_char_t *value_chars = (unsigned char *) RSTRING_PTR(value);
      node = yaml_document_add_scalar(document, NULL,
        value_chars, RSTRING_LEN(value), style);
      break;
    }
  }

  return node;
}
예제 #11
0
파일: misc.c 프로젝트: asfluido/mruby-sdl2
static mrb_value
mrb_sdl2_misc_bytebuffer_initialize(mrb_state *mrb, mrb_value self)
{
  mrb_value arg;
  mrb_get_args(mrb, "o", &arg);

  mrb_sdl2_misc_buffer_data_t *data =
    (mrb_sdl2_misc_buffer_data_t*)DATA_PTR(self);

  if (NULL == data) {
    data = (mrb_sdl2_misc_buffer_data_t*)mrb_malloc(mrb, sizeof(mrb_sdl2_misc_buffer_data_t));
    if (NULL == data) {
      mrb_raise(mrb, E_RUNTIME_ERROR, "insufficient memory.");
    }
    data->buffer = NULL;
    data->size   = 0;
  }

  enum mrb_vtype const arg_type = mrb_type(arg);
  switch (arg_type) {
  case MRB_TT_FIXNUM:
    data->size = (size_t)mrb_fixnum(arg);
    break;
  case MRB_TT_FLOAT:
    data->size = (size_t)mrb_float(arg);
    break;
  case MRB_TT_STRING:
    data->size = (size_t)mrb_float(mrb_funcall(mrb, arg, "to_f", 0));
    break;
  case MRB_TT_ARRAY:
    {
      mrb_int const n = mrb_ary_len(mrb, arg);
      if (0 == n) {
        mrb_raise(mrb, E_ARGUMENT_ERROR, "cannot accept empty array.");
      }
      data->size = n * sizeof(uint8_t);
    }
    break;
  default:
    if (mrb_respond_to(mrb, arg, mrb_intern(mrb, "to_f", 4))) {
      data->size = (size_t)mrb_float(mrb_funcall(mrb, arg, "to_f", 0));
    } else if (mrb_respond_to(mrb, arg, mrb_intern(mrb, "to_i", 4))) {
      data->size = (size_t)mrb_fixnum(mrb_funcall(mrb, arg, "to_i", 0));
    } else {
      mrb_raise(mrb, E_TYPE_ERROR, "expected Fixnum/Float/String/Array or comvertible type");
    }
    break;
  }

  data->buffer = mrb_malloc(mrb, data->size);
  if (NULL == data->buffer) {
    mrb_free(mrb, data);
    mrb_raise(mrb, E_RUNTIME_ERROR, "insufficient memory.");
  }

  size_t i = 0;
  for (i = 0; i < data->size/sizeof(uint8_t); ++i) {
    ((uint8_t*)data->buffer)[i] = 0;
  }

  if (arg_type == MRB_TT_ARRAY) {
    mrb_int const n = mrb_ary_len(mrb, arg);
    mrb_int i;
    for (i = 0; i < n; ++i) {
      mrb_value const item = mrb_ary_ref(mrb, arg, i);
      switch (mrb_type(item)) {
      case MRB_TT_FIXNUM:
        ((uint8_t*)data->buffer)[i] = (uint8_t)(mrb_fixnum(item) & 0xffu);
        break;
      case MRB_TT_FLOAT:
        ((uint8_t*)data->buffer)[i] = (uint8_t)((uint32_t)mrb_float(item) & 0xffu);
        break;
      case MRB_TT_STRING:
        ((uint8_t*)data->buffer)[i] = (uint8_t)((uint32_t)mrb_float(mrb_funcall(mrb, item, "to_f", 0)) & 0xffu);
        break;
      default:
        if (mrb_respond_to(mrb, item, mrb_intern(mrb, "to_f", 4))) {
          ((uint8_t*)data->buffer)[i] = (uint8_t)((uint32_t)mrb_float(mrb_funcall(mrb, item, "to_f", 0)) & 0xffu);
        } else if (mrb_respond_to(mrb, item, mrb_intern(mrb, "to_i", 4))) {
          ((uint8_t*)data->buffer)[i] = (uint8_t)(mrb_fixnum(mrb_funcall(mrb, item, "to_i", 0)) & 0xffu);
        } else {
          mrb_free(mrb, data->buffer);
          mrb_free(mrb, data);
          mrb_raise(mrb, E_TYPE_ERROR, "expected Fixnum/Float/String or convertible type");
        }
        break;
      }
    }
  }

  DATA_PTR(self) = data;
  DATA_TYPE(self) = &mrb_sdl2_misc_buffer_data_type;

  return self;
}