//--------------------------------------------------------------------------------------- void SkUERemote::get_project_info(SkProjectInfo * out_project_info_p) { // Get platform id string out_project_info_p->m_platform_id = FStringToAString(UGameplayStatics::GetPlatformName()); // Get engine id string out_project_info_p->m_engine_id.ensure_size(20); out_project_info_p->m_engine_id.format("UE%d.%d.%d-%s", ENGINE_MAJOR_VERSION, ENGINE_MINOR_VERSION, ENGINE_PATCH_VERSION, BUILT_FROM_CHANGELIST ? "Installed" : "Compiled"); // Get game name out_project_info_p->m_project_name = FStringToAString(FApp::GetGameName()); // Name of generated scripts overlay TCHAR const * const generated_overlay_name_p = TEXT("Project-Generated"); // Look for default SkookumScript project file in engine folder. FString default_project_path(FPaths::EnginePluginsDir() / TEXT("SkookumScript/Scripts/Skookum-project-default.ini")); SK_ASSERTX(FPaths::FileExists(default_project_path), a_str_format("Cannot find default project settings file '%S'!", *default_project_path)); out_project_info_p->m_default_project_path = FStringToAString(FPaths::ConvertRelativePathToFull(default_project_path)); // Check if we have loaded any game if (!out_project_info_p->m_project_name.is_empty()) { // Look for specific SkookumScript project in game/project folder. // 1) Check permanent location FString project_path(FPaths::GameDir() / TEXT("Scripts/Skookum-project.ini")); if (FPaths::FileExists(project_path)) { #if WITH_EDITORONLY_DATA if (m_editor_interface_p) { m_editor_interface_p->set_overlay_path(FPaths::GetPath(project_path), generated_overlay_name_p); } #endif } else { project_path.Empty(); #if WITH_EDITORONLY_DATA if (m_editor_interface_p) { // 2) Check/create temp location project_path = m_editor_interface_p->ensure_temp_project(generated_overlay_name_p); SK_ASSERTX(!project_path.IsEmpty(), a_str_format("Could not generated project file '%S' for project '%s'!", *project_path, out_project_info_p->m_project_name.as_cstr())); } #endif } out_project_info_p->m_project_path = FStringToAString(FPaths::ConvertRelativePathToFull(project_path)); } }
//--------------------------------------------------------------------------------------- // Get name of this Entity static void mthd_name(SkInvokedMethod * scope_p, SkInstance ** result_pp) { if (result_pp) // Do nothing if result not desired { UObject * this_p = scope_p->this_as<SkUEEntity>(); AString obj_name = this_p ? FStringToAString(this_p->GetName()) : "null"; *result_pp = SkString::new_instance(obj_name); } }
//--------------------------------------------------------------------------------------- // # Skookum: Delegate@String() String // # Author(s): Markus Breyer static void mthd_String(SkInvokedMethod * scope_p, SkInstance ** result_pp) { // Do nothing if result not desired if (result_pp) { const FScriptDelegate & script_delegate = scope_p->this_as<SkUEDelegate>(); *result_pp = SkString::new_instance(FStringToAString(script_delegate.ToString<UObject>())); } }
//--------------------------------------------------------------------------------------- // void FSkookumScriptRuntime::show_ide(const FString & focus_class_name, const FString & focus_member_name, bool is_data_member, bool is_class_member) { #ifdef SKOOKUM_REMOTE_UNREAL // Remove qualifier from member name if present FString focus_class_name_ide = focus_class_name; FString focus_member_name_ide = focus_member_name; int32 at_pos = 0; if (focus_member_name_ide.FindChar('@', at_pos)) { focus_class_name_ide = focus_member_name_ide.Left(at_pos).TrimTrailing(); focus_member_name_ide = focus_member_name_ide.Mid(at_pos + 1).Trim(); } // Convert to symbols and send off ASymbol focus_class_name_sym(ASymbol::create_existing(FStringToAString(focus_class_name_ide))); ASymbol focus_member_name_sym(ASymbol::create_existing(FStringToAString(focus_member_name_ide))); m_remote_client.cmd_show(AFlag_on, focus_class_name_sym, focus_member_name_sym, is_data_member, is_class_member); #endif }
//--------------------------------------------------------------------------------------- // Convert to String static void mthd_String(SkInvokedMethod * scope_p, SkInstance ** result_pp) { if (result_pp) // Do nothing if result not desired { UObject * this_p = scope_p->this_as<SkUEEntity>(); AString obj_name = this_p ? FStringToAString(this_p->GetName()) : "null"; AString class_name = scope_p->get_this()->get_class()->get_name().as_string(); AString uclass_name = this_p ? FStringToAString(this_p->GetClass()->GetName()) : "null"; AString str(nullptr, 9u + obj_name.get_length() + class_name.get_length() + uclass_name.get_length(), 0u); str.append('"'); str.append(obj_name); str.append("\" <", 3u); str.append(class_name); str.append("> (", 3u); str.append(uclass_name); str.append(')'); *result_pp = SkString::new_instance(str); } }
//--------------------------------------------------------------------------------------- // # Skookum: UClass@String() String // # Author(s): Markus Breyer static void mthd_String(SkInvokedMethod * scope_p, SkInstance ** result_pp) { if (result_pp) // Do nothing if result not desired { UClass * uclass_p = scope_p->this_as<SkUEEntityClass>(); AString uclass_name = FStringToAString(uclass_p->GetName()); AString str(nullptr, 3u + uclass_name.get_length(), 0u); str.append('('); str.append(uclass_name); str.append(')'); *result_pp = SkString::new_instance(str); } }
//--------------------------------------------------------------------------------------- // Resolve the raw data info of each raw data member of the given class void SkUEClassBindingHelper::resolve_raw_data(SkClass * class_p, UStruct * ue_struct_or_class_p) { // This loop assumes that the data members of the Sk class were created from this very UE4 class // I.e. that therefore, except for unsupported properties, they must be in the same order // So all we should have to do is loop forward and skip the occasional non-exported UE4 property UProperty * ue_var_p = nullptr; ASymbol ue_var_name; TFieldIterator<UProperty> property_it(ue_struct_or_class_p, EFieldIteratorFlags::ExcludeSuper); tSkTypedNameRawArray & raw_data = class_p->get_instance_data_raw_for_resolving(); for (auto var_p : raw_data) { // Skip variable if already resolved if (var_p->m_raw_data_info != SkRawDataInfo_Invalid) { continue; } // Try to find it in the UE4 reflection data while (property_it) { ue_var_p = *property_it; ue_var_name = ASymbol::create_existing(FStringToAString(FSkookumScriptGeneratorBase::skookify_var_name(ue_var_p->GetName(), ue_var_p->IsA(UBoolProperty::StaticClass()), true))); ++property_it; if (var_p->get_name() == ue_var_name) break; } // Store raw data info in the raw data member object if (var_p->get_name() == ue_var_name) { var_p->m_raw_data_info = compute_raw_data_info(ue_var_p); } else { // Oops didn't find matching variable // This is probably due to an unsaved blueprint variable change in the UE4 editor during the previous session // If this is the case, a recompile would have been triggered when this class was loaded by get_ue_class_from_sk_class() // Which means binaries would be recompiled and reloaded once more, fixing this issue // So make sure this assumption is true SK_ASSERTX(FModuleManager::Get().GetModulePtr<ISkookumScriptRuntime>("SkookumScriptRuntime")->is_freshen_binaries_pending(), a_str_format("Sk Variable '%s.%s' not found in UE4 reflection data.", class_p->get_name_cstr_dbg(), var_p->get_name_cstr())); } } }
//--------------------------------------------------------------------------------------- // Make this editable and tell IDE about it void SkUERemote::on_cmd_make_editable() { SkProjectInfo project_info; FString error_msg(TEXT("Can't make project editable!")); #if WITH_EDITORONLY_DATA if (m_editor_interface_p) { error_msg = m_editor_interface_p->make_project_editable(); } #endif if (error_msg.IsEmpty()) { get_project_info(&project_info); SkookumRuntimeBase::ms_singleton_p->on_binary_hierarchy_path_changed(); } // Send result back cmd_make_editable_reply(FStringToAString(error_msg), project_info); }
//--------------------------------------------------------------------------------------- // Description Returns constants / values used by the SkookumScript library. // Returns constants / values used by the SkookumScript library. // Examples Called internally // Author(s) Conan Reis SkookumVals & get_lib_vals() { static SkookumVals s_values; if (s_values.m_using_defaults) { // Set custom initial values s_values.m_using_defaults = false; // Unreal uses its own actor class s_values.m_use_builtin_actor = false; s_values.m_custom_actor_class_name = "Actor"; // Get platform name s_values.m_platform_id_string = FStringToAString(UGameplayStatics::GetPlatformName()); // Get engine name s_values.m_engine_id_string.ensure_size(20); s_values.m_engine_id_string.format("UE%d.%d.%d-%s", ENGINE_MAJOR_VERSION, ENGINE_MINOR_VERSION, ENGINE_PATCH_VERSION, BUILT_FROM_CHANGELIST ? "Installed" : "Compiled"); } return s_values; }
SkInstance * SkUEBlueprintInterface::fetch_k2_param_string(FFrame & stack) { UStrProperty::TCppType value = UStrProperty::GetDefaultPropertyValue(); stack.StepCompiledIn<UStrProperty>(&value); return SkString::new_instance(FStringToAString(value)); }