- Документация
- Locus
- C++ Developer API
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 с матрицей операций, контрактом идентичности, классификацией ошибок, ревизиями и состоянием операции.