| 1064 | } // namespace |
| 1065 | |
| 1066 | bool FindActorsSync( |
| 1067 | const FString& ClassFilter, |
| 1068 | const FString& TagFilter, |
| 1069 | const FString& NamePrefix, |
| 1070 | bool bSearchPieWorld, |
| 1071 | TArray<TSharedPtr<FJsonValue>>& OutActors, |
| 1072 | bool& bOutSearchedPie, |
| 1073 | FString& OutError) |
| 1074 | { |
| 1075 | OutActors.Reset(); |
| 1076 | OutError.Empty(); |
| 1077 | bOutSearchedPie = false; |
| 1078 | |
| 1079 | UWorld* World = PickWorld(bSearchPieWorld, bOutSearchedPie); |
| 1080 | if (!World) |
| 1081 | { |
| 1082 | OutError = TEXT("no world available"); |
| 1083 | return false; |
| 1084 | } |
| 1085 | |
| 1086 | for (TActorIterator<AActor> It(World); It; ++It) |
| 1087 | { |
| 1088 | AActor* A = *It; |
| 1089 | if (!ShouldListActor(A)) |
| 1090 | continue; |
| 1091 | if (!ClassFilter.IsEmpty()) |
| 1092 | { |
| 1093 | // Walk the class hierarchy so a filter like |
| 1094 | // "AMjArticulation" matches BP-derived classes |
| 1095 | // (e.g. golden_scene_C). UE's UClass::GetName() returns |
| 1096 | // the unprefixed form ("MjArticulation"), but most |
| 1097 | // callers write the C++ class name with the A/U/F |
| 1098 | // prefix — accept either form by also comparing |
| 1099 | // against the filter with one leading char stripped. |
| 1100 | const TCHAR FirstChar = ClassFilter.Len() > 1 ? ClassFilter[0] : 0; |
| 1101 | const bool bHasTypePrefix = FirstChar == TEXT('A') || FirstChar == TEXT('U') || FirstChar == TEXT('F'); |
| 1102 | const FString FilterStripped = bHasTypePrefix ? ClassFilter.Mid(1) : FString(); |
| 1103 | bool bMatch = false; |
| 1104 | for (UClass* C = A->GetClass(); C != nullptr; C = C->GetSuperClass()) |
| 1105 | { |
| 1106 | const FString& N = C->GetName(); |
| 1107 | if (N.Equals(ClassFilter, ESearchCase::IgnoreCase) || (!FilterStripped.IsEmpty() && N.Equals(FilterStripped, ESearchCase::IgnoreCase))) |
| 1108 | { |
| 1109 | bMatch = true; |
| 1110 | break; |
| 1111 | } |
| 1112 | } |
| 1113 | if (!bMatch) |
| 1114 | continue; |
| 1115 | } |
| 1116 | if (!TagFilter.IsEmpty() && !A->Tags.Contains(FName(*TagFilter))) |
| 1117 | continue; |
| 1118 | if (!NamePrefix.IsEmpty() && !A->GetName().StartsWith(NamePrefix)) |
| 1119 | continue; |
| 1120 | OutActors.Add(MakeShared<FJsonValueObject>(BuildActorRow(A))); |
| 1121 | } |
| 1122 | return true; |
| 1123 | } |