Перейти к содержимому
Поиск

C++ Developer API

Используйте нативный Developer API из плагина или инструмента C++, работающего только в редакторе. Добавьте модуль Locus в зависимости модуля редактора-потребителя, подключите Locus.h для получения API и Developer/LocusDeveloperApi.h для запросов и результатов.

GetLocusDeveloperApi() возвращает активный FLocusDeveloperApi или nullptr вне инициализированного времени жизни Locus Editor.

  • Получайте API и отправляйте запросы в Game Thread.
  • Не сохраняйте указатель API после завершения работы подсистемы или модуля.
  • Каждое завершение выполняется ровно один раз в Game Thread.
  • Принятая работа завершается на следующем тике существующего исполнителя Locus.
  • Ошибка допуска может завершить запрос сразу, до возврата из отправки.
  • Подготовьте состояние, принадлежащее callback, до отправки.
  • Отмена кооперативная. Она может предотвратить выполнение ожидающей работы, но не прерывает работу репозитория и не отменяет задним числом уже зафиксированное изменение.
  • Не добавляйте блокирующие ожидания, sleep, прокачку Game Thread или Future.Get().

Возвращённый FLocusDeveloperRequestHandle предоставляет идентичность запроса и потокобезопасный кооперативный Cancel().

#include "Locus.h"
#include "Developer/LocusDeveloperApi.h"
void CreateCombatDocument()
{
FLocusDeveloperApi* Locus = GetLocusDeveloperApi();
if (Locus == nullptr)
{
return;
}
FLocusDeveloperCreateDocumentRequest Request;
Request.Path = TEXT("Design/Combat.md");
Request.Markdown = TEXT("# Combat\n");
Request.PresentationRoot =
ELocusDeveloperDocumentPresentationRoot::LocusDocuments;
FLocusDeveloperRequestHandle Handle = Locus->CreateDocument(
MoveTemp(Request),
[](TLocusDeveloperResult<FLocusDeveloperDocumentSnapshot> Result)
{
if (!Result.IsSuccess())
{
UE_LOG(LogTemp, Error, TEXT("Locus: %s"), *Result.Error.Message);
return;
}
const FLocusDeveloperDocumentSnapshot& Document = Result.Value.GetValue();
UE_LOG(LogTemp, Display, TEXT("Created %s"),
*Document.Identity.RelativePath);
});
// Retain Handle only if this tool needs to offer cancellation.
}

Входной путь задаётся относительно выбранного конкретного корня представления. Возвращённая идентичность остаётся авторитетным путём относительно ProjectDocuments.

Не скрывайте обработку ревизий. Используйте ревизию из результата чтения как предварительное условие изменения:

FLocusDeveloperGetDocumentRequest GetRequest;
GetRequest.Identity.RelativePath = TEXT("Design/Combat.md");
Locus->GetDocument(
MoveTemp(GetRequest),
[Locus](TLocusDeveloperResult<FLocusDeveloperDocumentSnapshot> GetResult)
{
if (!GetResult.IsSuccess())
{
return;
}
const FLocusDeveloperDocumentSnapshot& Current = GetResult.Value.GetValue();
FLocusDeveloperUpdateDocumentRequest UpdateRequest;
UpdateRequest.Identity = Current.Identity;
UpdateRequest.ExpectedRevision = Current.Revision;
UpdateRequest.Markdown = Current.Markdown + TEXT("\n## Abilities\n");
Locus->UpdateDocument(
MoveTemp(UpdateRequest),
[](TLocusDeveloperResult<FLocusDeveloperDocumentSnapshot> Result)
{
if (Result.Error.Code ==
ELocusDeveloperErrorCode::StaleRevision)
{
// Reread before reconsidering the mutation.
}
});
});
FLocusDeveloperCreateNoteRequest Request;
Request.Scope = ELocusDeveloperScope::Private;
Request.Title = TEXT("Local investigation");
Request.Body = TEXT("Not shared with the project repository.");
Request.Tags = {TEXT("investigation")};
FLocusDeveloperRequestHandle Handle = Locus->CreateNote(
MoveTemp(Request),
[](TLocusDeveloperResult<FLocusDeveloperNoteSnapshot> Result)
{
if (Result.IsSuccess())
{
const FLocusDeveloperNoteIdentifier Identity =
Result.Value->Identity; // GUID + Private scope
}
});

Фильтры области столь же явны. All включает Личное содержимое; запрашивайте Shared, когда инструмент не должен его включать.

FLocusDeveloperCreatePinRequest Request;
Request.Scope = ELocusDeveloperScope::Shared;
Request.WorldAssetPath = TEXT("/Game/Maps/Main.Main");
Request.WorldLabel = TEXT("Main");
Request.Location = FVector(120.0, 40.0, 180.0);
Request.Title = TEXT("Check encounter cover");
Request.PinType = ELocusDeveloperPinType::Issue;
FLocusDeveloperRequestHandle Handle = Locus->CreatePin(
MoveTemp(Request),
[](TLocusDeveloperResult<FLocusDeveloperPinSnapshot> Result)
{
if (!Result.IsSuccess())
{
UE_LOG(LogTemp, Warning, TEXT("Pin create failed: %s"),
LexToString(Result.Error.Code));
}
});

Для создания метки требуется поддерживаемый сохранённый принадлежащий проекту мир. Обновления метаданных сохраняют положение, мир, якорь, вид и область.

См. Обзор Developer API с матрицей операций, контрактом идентичности, классификацией ошибок, ревизиями и состоянием операции.