int init_plugin_from_file(Plugin *plugin, const char *path, const char *plugin_name) { int fds[2], flags, buffer_size, n; printf("Loading plugin %s...\n", path); plugin->mrb = mrb_open_allocf(profiler_allocf, (void *)path); setup_api(plugin->mrb); execute_file(plugin->mrb, path); execute_file(plugin->mrb, config_path); C_CHECK("socketpair", socketpair(PF_UNIX, SOCK_DGRAM, 0, fds)); buffer_size = PIPE_BUFFER_SIZE; n = sizeof(buffer_size); C_CHECK("setsockopt 0 snd", setsockopt(fds[0], SOL_SOCKET, SO_SNDBUF, (void *)&buffer_size, n)); C_CHECK("setsockopt 0 rcv", setsockopt(fds[0], SOL_SOCKET, SO_RCVBUF, (void *)&buffer_size, n)); C_CHECK("setsockopt 1 snd", setsockopt(fds[1], SOL_SOCKET, SO_SNDBUF, (void *)&buffer_size, n)); C_CHECK("setsockopt 1 snd", setsockopt(fds[1], SOL_SOCKET, SO_RCVBUF, (void *)&buffer_size, n)); flags = fcntl(fds[0], F_GETFL); flags |= O_NONBLOCK; if( fcntl(fds[0], F_SETFL, flags) == -1 ){ perror("fcntl"); return -1; } plugin->host_pipe = fds[0]; plugin->plugin_pipe = wrap_io(plugin->mrb, fds[1], "w"); strncpy(plugin->name, plugin_name, sizeof(plugin->name) - 1); // set ivs // struct RClass *rprobe = mrb_class_get(plugin->mrb, "D3Probe"); // mrb_value probe_klass = mrb_obj_value(rprobe); mrb_sym plugin_iv_sym = mrb_intern_cstr(plugin->mrb, "@plugin"); plugin->plugin_obj = mrb_iv_get(plugin->mrb, mrb_obj_value(plugin->mrb->top_self), plugin_iv_sym); // pp(plugin->mrb, plugin->plugin_obj, 0); // associates the c structure with the ruby object DATA_PTR(plugin->plugin_obj) = (void*)plugin; mrb_funcall(plugin->mrb, plugin->plugin_obj, "after_config", 0); check_exception("after_config", plugin->mrb); return 0; }
void CEnvDescriptor::load (LPCSTR exec_tm, LPCSTR S, CEnvironment* parent) { Ivector3 tm ={0,0,0}; sscanf (exec_tm,"%d:%d:%d",&tm.x,&tm.y,&tm.z); R_ASSERT3 ((tm.x>=0)&&(tm.x<24)&&(tm.y>=0)&&(tm.y<60)&&(tm.z>=0)&&(tm.z<60),"Incorrect weather time",S); exec_time = tm.x*3600.f+tm.y*60.f+tm.z; exec_time_loaded = exec_time; string_path st,st_env; strcpy_s (st,pSettings->r_string (S,"sky_texture")); strconcat (sizeof(st_env),st_env,st,"#small" ); sky_texture_name = st; sky_texture_env_name = st_env; clouds_texture_name = pSettings->r_string (S,"clouds_texture"); LPCSTR cldclr = pSettings->r_string (S,"clouds_color"); float multiplier = 0, save=0; sscanf (cldclr,"%f,%f,%f,%f,%f",&clouds_color.x,&clouds_color.y,&clouds_color.z,&clouds_color.w,&multiplier); save=clouds_color.w; clouds_color.mul (.5f*multiplier); clouds_color.w = save; sky_color = pSettings->r_fvector3 (S,"sky_color"); sky_color.mul(.5f); if (pSettings->line_exist(S,"sky_rotation")) sky_rotation = deg2rad(pSettings->r_float(S,"sky_rotation")); else sky_rotation = 0; far_plane = pSettings->r_float (S,"far_plane"); fog_color = pSettings->r_fvector3 (S,"fog_color"); fog_density = pSettings->r_float (S,"fog_density"); fog_distance = pSettings->r_float (S,"fog_distance"); rain_density = pSettings->r_float (S,"rain_density"); clamp(rain_density,0.f,1.f); rain_color = pSettings->r_fvector3 (S,"rain_color"); wind_velocity = pSettings->r_float (S,"wind_velocity"); wind_direction = deg2rad(pSettings->r_float(S,"wind_direction")); ambient = pSettings->r_fvector3 (S,"ambient"); hemi_color = pSettings->r_fvector4 (S,"hemi_color"); sun_color = pSettings->r_fvector3 (S,"sun_color"); Fvector2 sund = pSettings->r_fvector2 (S,"sun_dir"); sun_dir.setHP (deg2rad(sund.y),deg2rad(sund.x)); VERIFY2 (sun_dir.y<0,"Invalid sun direction settings while loading"); lens_flare_id = parent->eff_LensFlare->AppendDef(pSettings,pSettings->r_string(S,"flares")); tb_id = parent->eff_Thunderbolt->AppendDef(pSettings,pSettings->r_string(S,"thunderbolt")); bolt_period = (tb_id>=0)?pSettings->r_float (S,"bolt_period"):0.f; bolt_duration = (tb_id>=0)?pSettings->r_float (S,"bolt_duration"):0.f; env_ambient = pSettings->line_exist(S,"env_ambient")?parent->AppendEnvAmb (pSettings->r_string(S,"env_ambient")):0; C_CHECK (clouds_color); C_CHECK (sky_color ); C_CHECK (fog_color ); C_CHECK (rain_color ); C_CHECK (ambient ); // C_CHECK (lmap_color ); C_CHECK (hemi_color ); C_CHECK (sun_color ); on_device_create (); }
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; }
void CEnvDescriptor::load(CEnvironment& environment, CInifile& config) { Ivector3 tm = {0, 0, 0}; sscanf(m_identifier.c_str(), "%d:%d:%d", &tm.x, &tm.y, &tm.z); R_ASSERT3((tm.x >= 0) && (tm.x < 24) && (tm.y >= 0) && (tm.y < 60) && (tm.z >= 0) && (tm.z < 60), "Incorrect weather time", m_identifier.c_str()); exec_time = tm.x*3600.f + tm.y*60.f + tm.z; exec_time_loaded = exec_time; string_path st, st_env; xr_strcpy(st, config.r_string(m_identifier.c_str(), "sky_texture")); strconcat(sizeof(st_env), st_env, st, "#small"); sky_texture_name = st; sky_texture_env_name = st_env; clouds_texture_name = config.r_string(m_identifier.c_str(), "clouds_texture"); LPCSTR cldclr = config.r_string(m_identifier.c_str(), "clouds_color"); float multiplier = 0, save = 0; sscanf(cldclr, "%f,%f,%f,%f,%f", &clouds_color.x, &clouds_color.y, &clouds_color.z, &clouds_color.w, &multiplier); save = clouds_color.w; clouds_color.mul(.5f*multiplier); clouds_color.w = save; sky_color = config.r_fvector3(m_identifier.c_str(), "sky_color"); if (config.line_exist(m_identifier.c_str(), "sky_rotation")) sky_rotation = deg2rad(config.r_float(m_identifier.c_str(), "sky_rotation")); else sky_rotation = 0; far_plane = config.r_float(m_identifier.c_str(), "far_plane"); fog_color = config.r_fvector3(m_identifier.c_str(), "fog_color"); fog_density = config.r_float(m_identifier.c_str(), "fog_density"); fog_distance = config.r_float(m_identifier.c_str(), "fog_distance"); rain_density = config.r_float(m_identifier.c_str(), "rain_density"); clamp(rain_density, 0.f, 1.f); rain_color = config.r_fvector3(m_identifier.c_str(), "rain_color"); wind_velocity = config.r_float(m_identifier.c_str(), "wind_velocity"); wind_direction = deg2rad(config.r_float(m_identifier.c_str(), "wind_direction")); ambient = config.r_fvector3(m_identifier.c_str(), "ambient_color"); hemi_color = config.r_fvector4(m_identifier.c_str(), "hemisphere_color"); sun_color = config.r_fvector3(m_identifier.c_str(), "sun_color"); // if (config.line_exist(m_identifier.c_str(),"sun_altitude")) sun_dir.setHP( deg2rad(config.r_float(m_identifier.c_str(), "sun_altitude")), deg2rad(config.r_float(m_identifier.c_str(), "sun_longitude")) ); R_ASSERT(_valid(sun_dir)); // else // sun_dir.setHP ( // deg2rad(config.r_fvector2(m_identifier.c_str(),"sun_dir").y), // deg2rad(config.r_fvector2(m_identifier.c_str(),"sun_dir").x) // ); //AVO: commented to allow COC run in debug. I belive Cromm set longtitude to negative value in AF3 and that's why it is failing here //VERIFY2(sun_dir.y < 0, "Invalid sun direction settings while loading"); lens_flare_id = environment.eff_LensFlare->AppendDef(environment, environment.m_suns_config, config.r_string(m_identifier.c_str(), "sun")); tb_id = environment.eff_Thunderbolt->AppendDef(environment, environment.m_thunderbolt_collections_config, environment.m_thunderbolts_config, config.r_string(m_identifier.c_str(), "thunderbolt_collection")); bolt_period = (tb_id.size()) ? config.r_float(m_identifier.c_str(), "thunderbolt_period") : 0.f; bolt_duration = (tb_id.size()) ? config.r_float(m_identifier.c_str(), "thunderbolt_duration") : 0.f; env_ambient = config.line_exist(m_identifier.c_str(), "ambient") ? environment.AppendEnvAmb(config.r_string(m_identifier.c_str(), "ambient")) : 0; if (config.line_exist(m_identifier.c_str(), "sun_shafts_intensity")) m_fSunShaftsIntensity = config.r_float(m_identifier.c_str(), "sun_shafts_intensity"); if (config.line_exist(m_identifier.c_str(), "water_intensity")) m_fWaterIntensity = config.r_float(m_identifier.c_str(), "water_intensity"); #ifdef TREE_WIND_EFFECT if (config.line_exist(m_identifier.c_str(), "tree_amplitude_intensity")) m_fTreeAmplitudeIntensity = config.r_float(m_identifier.c_str(), "tree_amplitude_intensity"); #endif C_CHECK(clouds_color); C_CHECK(sky_color); C_CHECK(fog_color); C_CHECK(rain_color); C_CHECK(ambient); C_CHECK(hemi_color); C_CHECK(sun_color); on_device_create(); }