diff --git a/CMakeLists.txt b/CMakeLists.txt index 595f65b..7d71b6b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -307,6 +307,7 @@ set(BINDING_SOURCE binding-mri/lightmap-binding.cpp binding-mri/signalconnection-binding.cpp binding-mri/gamepad-binding.cpp + binding-mri/profiler-binding.cpp ) source_group("Binding Source" FILES ${BINDING_SOURCE} ${BINDING_HEADERS}) diff --git a/binding-mri/binding-mri.cpp b/binding-mri/binding-mri.cpp index 407f518..ad7d12e 100644 --- a/binding-mri/binding-mri.cpp +++ b/binding-mri/binding-mri.cpp @@ -48,57 +48,6 @@ #include #include #include - -typedef struct { - uint64_t start_ns; -} ud_t; - -//TODO rewrtire profiler bcz ChatGPT bcz WHERE IS DOCS ABOUT RUBY C API TRACEPOINT -static uint64_t now_ns(void) { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return (uint64_t)ts.tv_sec * 1000000000ull + (uint64_t)ts.tv_nsec; -} - -static const char *val_to_cstr(VALUE v, const char *fallback) { - if (NIL_P(v)) return fallback; - VALUE s = rb_funcall(v, rb_intern("to_s"), 0); - if (!RB_TYPE_P(s, T_STRING)) return fallback; - return RSTRING_PTR(s); -} - -static void tp_cb(VALUE tpval, void *data) { - ud_t *ud = (ud_t *)data; - - rb_trace_arg_t *trace_arg = rb_tracearg_from_tracepoint(tpval); - if (!trace_arg) return; - - VALUE path = rb_tracearg_path(trace_arg); - VALUE lineno = rb_tracearg_lineno(trace_arg); - VALUE defined_class = rb_tracearg_defined_class(trace_arg); - VALUE method_id = rb_tracearg_method_id(trace_arg); - rb_event_flag_t ev = rb_tracearg_event_flag(trace_arg); - - const char *path_s = val_to_cstr(path, ""); - const char *class_s = val_to_cstr(defined_class, ""); - - const char *meth_s = ""; - if (!NIL_P(method_id)) { - const char *mn = rb_id2name(SYM2ID(method_id)); - if (mn) meth_s = mn; - } - - long line = NIL_P(lineno) ? 0 : FIX2LONG(lineno); - - if (ev == RUBY_EVENT_CALL) { - ud->start_ns = now_ns(); - } else if (ev == RUBY_EVENT_RETURN) { - uint64_t end_ns = now_ns(); - uint64_t dur_ns = end_ns - ud->start_ns; - printf("[PROFILER] %s %s:%ld class=%s dur_ns=%" PRIu64 "\n", meth_s, path_s, line, class_s, dur_ns); - } -} - extern const char binding_mri_module_rpg1_rb[]; extern const int binding_mri_module_rpg1_rb_len; @@ -147,6 +96,7 @@ void shaderBindingInit(); void ModLoaderBindingInit(); void keybindingsBindingInit(); void lightmapBindingInit(); +void ProfilerInit(); RB_METHOD(mriPrint); RB_METHOD(mriP); @@ -159,10 +109,8 @@ RB_METHOD(mriRgssMain); RB_METHOD(mriRgssStop); RB_METHOD(_kernelCaller); - // TODO: find the reason why Symbol doesn't have some methods -VALUE rb_symbol_to_s(VALUE self) -{ +VALUE rb_symbol_to_s(VALUE self){ ID id = SYM2ID(self); const char *name = rb_id2name(id); @@ -205,6 +153,7 @@ static void mriBindingInit(){ ModLoaderBindingInit(); keybindingsBindingInit(); lightmapBindingInit(); + ProfilerInit(); _rb_define_module_function(rb_mKernel, "rgss_main", mriRgssMain); _rb_define_module_function(rb_mKernel, "rgss_stop", mriRgssStop); @@ -481,7 +430,7 @@ static void runRMXPScripts(BacktraceData &btData){ /* Execute preloaded scripts */ for (std::set::iterator i = preloadScripts.begin(); - i != conf.preloadScripts.end(); ++i) + i != preloadScripts.end(); ++i) runCustomScript(*i); VALUE exc = rb_gv_get("$!"); @@ -591,17 +540,6 @@ static void mriBindingExecute(){ ruby_init_loadpath(); rb_enc_set_default_external(rb_enc_from_encoding(rb_utf8_encoding())); Config &conf = shState->rtData().config; - if(conf.debugMode){ - setvbuf(stdout, NULL, _IOFBF, 1<<20); - ud_t ud; - rb_event_flag_t flags = 0; - flags |= RUBY_EVENT_CALL; - flags |= RUBY_EVENT_RETURN; - flags |= RUBY_EVENT_RAISE; - VALUE tp = rb_tracepoint_new(Qnil, flags, tp_cb, &ud); - rb_tracepoint_enable(tp); - } - if (!conf.rubyLoadpaths.empty()){ /* Setup custom load paths */ VALUE lpaths = rb_gv_get("$:"); diff --git a/binding-mri/profiler-binding.cpp b/binding-mri/profiler-binding.cpp new file mode 100644 index 0000000..c33cf86 --- /dev/null +++ b/binding-mri/profiler-binding.cpp @@ -0,0 +1,101 @@ +// someone plz help me fix it 3: + +#include "binding.h" +#include "binding-util.h" +#include "debugwriter.h" + +#include +#include + +#include +#include + +#include +#include +#include + +static VALUE tp = Qnil; + +static uint64_t now_ns(void) { + timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return (uint64_t)ts.tv_sec * 1000000000ull + (uint64_t)ts.tv_nsec; +} + +static std::string value_to_string(VALUE v, const char *fallback) { + if (NIL_P(v)) return fallback; + return std::string(StringValuePtr(v)); +} + +static void tp_cb(VALUE tpval, void * /*data*/) { + rb_trace_arg_t *trace_arg = rb_tracearg_from_tracepoint(tpval); + if (!trace_arg) return; + + rb_event_flag_t ev = rb_tracearg_event_flag(trace_arg); + struct Stack { + std::vector starts; + }; + static __thread Stack stack; + + if (ev == RUBY_EVENT_CALL) { + stack.starts.push_back(now_ns()); + return; + } + + if (ev == RUBY_EVENT_RETURN || ev == RUBY_EVENT_RAISE) { + if (stack.starts.empty()) return; + + uint64_t end_ns = now_ns(); + uint64_t start_ns = stack.starts.back(); + stack.starts.pop_back(); + + uint64_t dur_ns = end_ns - start_ns; + + VALUE path = rb_tracearg_path(trace_arg); + VALUE lineno = rb_tracearg_lineno(trace_arg); + VALUE defined_class = rb_tracearg_defined_class(trace_arg); + VALUE method_id = rb_tracearg_method_id(trace_arg); + + std::string path_s = value_to_string(path, ""); + std::string class_s = value_to_string(defined_class, ""); + + std::string meth_s = ""; + if (!NIL_P(method_id)) { + const char *mn = rb_id2name((ID)method_id); + if (mn) meth_s = mn; + } + + long line = NIL_P(lineno) ? 0 : FIX2LONG(lineno); + + std::cout << "[PROFILER] " + << meth_s << ' ' + << path_s << ':' << line + << " class=" << class_s + << " dur_ns=" << dur_ns + << (ev == RUBY_EVENT_RAISE ? " event=RAISE" : " event=RETURN") + << '\n'; + return; + } +} + +static VALUE profiler(VALUE /*self*/, VALUE v) { + if (tp == Qnil) return Qnil; + if (v == Qtrue) { + rb_tracepoint_enable(tp); + } else { + rb_tracepoint_disable(tp); + } + return Qnil; +} + +void ProfilerInit() { + Debug() << "[PROFILER] Initializing"; + VALUE module = rb_define_module("Profiler"); + tp = rb_tracepoint_new( + Qnil, + RUBY_EVENT_CALL | RUBY_EVENT_RETURN | RUBY_EVENT_RAISE, + tp_cb, + nullptr + ); + rb_define_singleton_method(module, "set", RUBY_METHOD_FUNC(profiler), 1); +} diff --git a/changelogs/0.1.2.txt b/changelogs/0.1.2.txt index 3298d2d..ff8f494 100644 --- a/changelogs/0.1.2.txt +++ b/changelogs/0.1.2.txt @@ -42,3 +42,5 @@ Fixed bug #21 Fixed OpenGL ES 2 support Added CMake option to build engine with OpenGL ES2 instead Desktop GL(why not?) Added setting that disable some puzzles(For Wayland users) +PreloadScripts moved to modloader +Deleted Battletest and RPGMaker debug code diff --git a/oneshot.conf b/oneshot.conf index ec60cfc..3e701f5 100644 --- a/oneshot.conf +++ b/oneshot.conf @@ -84,17 +84,13 @@ allowSymlinks=false # Set the game window icon to 'path/to/icon.png' iconPath=/path/to/icon.png -# Define raw scripts to be executed before the -# actual Scripts.rxdata execution starts -#preloadScript=my_win32_wrapper.rb -#preloadScript=ruby18_fixes.rb - # Index all accesible assets via their lower case path # (emulates windows case insensitivity) pathCache=true # Add 'rtp1', 'rtp2.zip' and 'game.rgssad' to the # asset search path (multiple allowed) +# this shit dont work btw #RTP=/path/to/rtp1 #RTP=/path/to/rtp2.zip #RTP=/path/to/game.rgssad diff --git a/scripts/Scene_Title.rb b/scripts/Scene_Title.rb index 675e3f9..5a05f7e 100644 --- a/scripts/Scene_Title.rb +++ b/scripts/Scene_Title.rb @@ -191,7 +191,7 @@ class Scene_Title @debug.bitmap.draw_text(0, ENTRY_HEIGHT * 3, 200, ENTRY_HEIGHT, tr("sec_#{Sunshine::SECURITYSTATE}")) if ModLoader::IS_ENABLED @debug.bitmap.draw_text(0, ENTRY_HEIGHT * 4, 200, ENTRY_HEIGHT, tr("Mods loaded: ") + ModLoader::COUNT.to_s) - @debug.bitmap.draw_text(0, ENTRY_HEIGHT * 5, 200, ENTRY_HEIGHT, tr("Preload Scripts loaded: ") + ModLoader::PRELOAD_SCRIPTS_COUNT.to_s) + @debug.bitmap.draw_text(0, ENTRY_HEIGHT * 5, 200, ENTRY_HEIGHT, tr("PreloadScripts loaded: ") + ModLoader::PRELOAD_SCRIPTS_COUNT.to_s) end end diff --git a/src/config.cpp b/src/config.cpp index 1f83c48..5acde84 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -72,7 +72,6 @@ void Config::read(int argc, char *argv[]){ PO_DESC(printFPS, bool, false) \ PO_DESC(fullscreen, bool, false) \ PO_DESC(fixedAspectRatio, bool, true) \ - /*PO_DESC(AspectPreset, int, 1)*/ \ PO_DESC(smoothScaling, bool, false) \ PO_DESC(defScreenW, int, 0) \ PO_DESC(defScreenH, int, 0) \ @@ -98,35 +97,13 @@ void Config::read(int argc, char *argv[]){ // Not gonna take your shit boost #define GUARD_ALL( SDL_exp ) try { SDL_exp } catch(...) {} - - editor.debug = false; - editor.battleTest = false; - - /* Read arguments sent from the editor */ - if (argc > 1){ - std::string argv1 = argv[1]; - /* RGSS1 uses "debug", 2 and 3 use "test" */ - if (argv1 == "debug" || argv1 == "test") - editor.debug = true; - else if (argv1 == "btest") - editor.battleTest = true; - - /* Fix offset */ - if (editor.debug || editor.battleTest){ - argc--; - argv++; - } - } - #define PO_DESC(key, type, def) (#key, po::value< type >()->default_value(def)) po::options_description podesc; podesc.add_options() PO_DESC_ALL - ("preloadScript", po::value()->composing()->default_value(StringVec())) ("fontSub", po::value()->composing()->default_value(StringVec())) - ("rubyLoadpath", po::value()->composing()->default_value(StringVec())) - ; + ("rubyLoadpath", po::value()->composing()->default_value(StringVec())); po::variables_map vm; @@ -156,8 +133,6 @@ void Config::read(int argc, char *argv[]){ PO_DESC_ALL; - GUARD_ALL( preloadScripts = setFromVec(vm["preloadScript"].as()); ); - GUARD_ALL( fontSubs = vm["fontSub"].as(); ); GUARD_ALL( rubyLoadpaths = vm["rubyLoadpath"].as(); ); diff --git a/src/config.h b/src/config.h index a52c709..10e953b 100644 --- a/src/config.h +++ b/src/config.h @@ -51,8 +51,6 @@ struct Config{ int maxTextureSize; std::string gameFolder; - //int AspectPreset; - //std::string AspectPresetRubyConst; bool allowSymlinks; bool pathCache; bool SecurityEngine; @@ -71,19 +69,11 @@ struct Config{ bool useScriptNames; std::string customScript; - std::set preloadScripts; std::vector rtps; std::vector fontSubs; std::vector rubyLoadpaths; - - /* Editor flags */ - struct { - bool debug; - bool battleTest; - } editor; - /* Game INI contents */ struct { std::string scripts;