//--------------------------------------------------------------------------------------- void FSkookumScriptRuntime::on_world_init_pre(UWorld * world_p, const UWorld::InitializationValues init_vals) { //A_DPRINT("on_world_init_pre: %S %p\n", *world_p->GetName(), world_p); // Use this callback as an opportunity to take care of connecting to the IDE #ifdef SKOOKUM_REMOTE_UNREAL if (!IsRunningCommandlet() && !m_remote_client.is_authenticated()) { m_remote_client.attempt_connect(0.0, true, true); } #endif if (world_p->IsGameWorld()) { if (!m_game_world_p) { m_game_world_p = world_p; if (is_skookum_initialized()) { SkUEClassBindingHelper::set_world(world_p); } m_game_tick_handle = world_p->OnTickDispatch().AddRaw(this, &FSkookumScriptRuntime::tick_game); } } else if (world_p->WorldType == EWorldType::Editor) { if (!m_editor_world_p) { m_editor_world_p = world_p; m_editor_tick_handle = world_p->OnTickDispatch().AddRaw(this, &FSkookumScriptRuntime::tick_editor); } } }
//--------------------------------------------------------------------------------------- // void FSkookumScriptRuntime::tick_remote() { if (!IsRunningCommandlet()) { // Request recompilation of binaries if script files changed if (m_freshen_binaries_requested) { m_remote_client.cmd_compiled_state(true); m_freshen_binaries_requested = false; } // Remote communication to and from SkookumScript IDE. // Needs to be called whether in editor or game and whether paused or not // $Revisit - CReis This is probably a hack. The remote client update should probably // live somewhere other than a tick method such as its own thread. m_remote_client.process_incoming(); // Re-load compiled binaries? if (m_remote_client.is_load_compiled_binaries_requested()) { // Load the Skookum class hierarchy scripts in compiled binary form #if WITH_EDITOR bool is_first_time = !is_skookum_initialized(); #endif bool success_b = m_runtime.load_compiled_scripts(); SK_ASSERTX(success_b, AErrMsg("Unable to load SkookumScript compiled binaries!", AErrLevel_notify)); m_remote_client.clear_load_compiled_binaries_requested(); #if WITH_EDITOR if (is_first_time && is_skookum_initialized()) { // When we load the binaries for the very first time, try regenerating all generated class script files again, // as the editor might have tried to generate them before but skipped because SkookumScript was not initialized yet m_runtime.get_editor_interface()->generate_all_class_script_files(); // Also recompile Blueprints in error state as such error state might have been due to SkookumScript not being initialized at the time of compile m_runtime.get_editor_interface()->recompile_blueprints_with_errors(); // Set world pointer now SkUEClassBindingHelper::set_world(m_game_world_p); } #endif } } }
//--------------------------------------------------------------------------------------- void FSkookumScriptRuntime::on_world_init_pre(UWorld * world_p, const UWorld::InitializationValues init_vals) { //A_DPRINT("on_world_init_pre: %S %p\n", *world_p->GetName(), world_p); // Make sure atomics are bound by now if (m_runtime.is_compiled_scripts_loaded() && !m_runtime.is_compiled_scripts_bound()) { m_runtime.bind_compiled_scripts(); } // Use this callback as an opportunity to take care of connecting to the IDE #ifdef SKOOKUM_REMOTE_UNREAL if (!IsRunningCommandlet() && !m_remote_client.is_authenticated()) { m_remote_client.attempt_connect(0.0, true, true); } #endif if (world_p->IsGameWorld()) { // Keep track of how many game worlds we got ++m_num_game_worlds; if (!m_game_world_p) { m_game_world_p = world_p; if (is_skookum_initialized()) { SkUEClassBindingHelper::set_world(world_p); SkookumScript::initialize_gameplay(); } m_game_tick_handle = world_p->OnTickDispatch().AddRaw(this, &FSkookumScriptRuntime::tick_game); } } else if (world_p->WorldType == EWorldType::Editor) { if (!m_editor_world_p) { m_editor_world_p = world_p; m_editor_tick_handle = world_p->OnTickDispatch().AddRaw(this, &FSkookumScriptRuntime::tick_editor); } } }
//--------------------------------------------------------------------------------------- void FSkookumScriptRuntime::on_world_cleanup(UWorld * world_p, bool session_ended_b, bool cleanup_resources_b) { //A_DPRINT("on_world_cleanup: %S %p\n", *world_p->GetName(), world_p); if (world_p->IsGameWorld()) { // Keep track of how many game worlds we got --m_num_game_worlds; // Set world pointer to null if it was pointing to us if (m_game_world_p == world_p) { m_game_world_p->OnTickDispatch().Remove(m_game_tick_handle); m_game_world_p = nullptr; SkUEClassBindingHelper::set_world(nullptr); } // Restart SkookumScript if initialized if (m_num_game_worlds == 0 && is_skookum_initialized()) { // Simple shutdown //SkookumScript::get_world()->clear_coroutines(); A_DPRINT( "SkookumScript resetting session...\n" " cleaning up...\n"); SkookumScript::deinitialize_gameplay(); SkookumScript::deinitialize_sim(); SkookumScript::initialize_sim(); A_DPRINT(" ...done!\n\n"); } } else if (world_p->WorldType == EWorldType::Editor) { // Set world pointer to null if it was pointing to us if (m_editor_world_p == world_p) { m_editor_world_p->OnTickDispatch().Remove(m_editor_tick_handle); m_editor_world_p = nullptr; } } }
//--------------------------------------------------------------------------------------- // void FSkookumScriptRuntime::tick_remote() { if (!IsRunningCommandlet()) { // Request recompilation of binaries if script files changed if (m_freshen_binaries_requested) { m_remote_client.cmd_compiled_state(true); m_freshen_binaries_requested = false; } // Remote communication to and from SkookumScript IDE. // Needs to be called whether in editor or game and whether paused or not // $Revisit - CReis This is probably a hack. The remote client update should probably // live somewhere other than a tick method such as its own thread. m_remote_client.process_incoming(); // Re-load compiled binaries? // If the game is currently running, delay until it's not if (m_remote_client.is_load_compiled_binaries_requested() && SkookumScript::get_initialization_level() < SkookumScript::InitializationLevel_gameplay) { // Makes sure the SkookumScript runtime object is initialized at this point ensure_runtime_initialized(); // Load the Skookum class hierarchy scripts in compiled binary form bool is_first_time = !is_skookum_initialized(); bool success_b = m_runtime.load_and_bind_compiled_scripts(); SK_ASSERTX(success_b, AErrMsg("Unable to load SkookumScript compiled binaries!", AErrLevel_notify)); m_remote_client.clear_load_compiled_binaries_requested(); // After reloading, re-resolve the raw data of all dynamic classes #if WITH_EDITORONLY_DATA TArray<UObject*> blueprint_array; GetObjectsOfClass(UBlueprint::StaticClass(), blueprint_array, true, RF_ClassDefaultObject); for (UObject * obj_p : blueprint_array) { UBlueprint * blueprint_p = static_cast<UBlueprint *>(obj_p); if (blueprint_p->GeneratedClass) { SkClass * sk_class_p = SkUEClassBindingHelper::get_sk_class_from_ue_class(blueprint_p->GeneratedClass); if (sk_class_p) { SkUEClassBindingHelper::resolve_raw_data(sk_class_p, blueprint_p->GeneratedClass); } } } #endif if (is_first_time && is_skookum_initialized()) { #if WITH_EDITOR // Recompile Blueprints in error state as such error state might have been due to SkookumScript not being initialized at the time of compile if (m_runtime.get_editor_interface()) { m_runtime.get_editor_interface()->recompile_blueprints_with_errors(); } #endif } } } }