Editor 전용 C++ 플러그인 또는 도구에서 네이티브 Developer API를 사용합니다. 사용하는 에디터 모듈의 종속성에 Locus 모듈을 추가하고, 획득에는 Locus.h, 요청과 결과에는 Developer/LocusDeveloperApi.h를 포함합니다.
수명 및 비동기 계약
섹션 제목: “수명 및 비동기 계약”GetLocusDeveloperApi()는 활성 FLocusDeveloperApi를 반환하며 초기화된 Locus Editor 수명 밖에서는 nullptr입니다.
- Game Thread에서 획득하고 제출합니다.
- 서브시스템 또는 모듈이 종료된 뒤에도 API 포인터를 보관하지 마세요.
- 모든 완료는 Game Thread에서 정확히 한 번 실행됩니다.
- 수락된 작업은 Locus의 기존 실행기가 다음 tick에서 완료합니다.
- 수락에 실패하면 제출이 반환되기 전에 인라인으로 완료될 수 있습니다.
- 제출하기 전에 콜백이 소유한 상태를 준비합니다.
- 취소는 협력적입니다. 대기 중인 작업을 막을 수 있지만 리포지토리 작업을 중단하거나 이미 영속화가 확정된 변경을 취소 결과로 되돌릴 수 없습니다.
- 블로킹 대기, sleep, Game Thread 펌핑 또는
Future.Get()을 추가하지 마세요.
반환되는 FLocusDeveloperRequestHandle은 요청 ID와 스레드 안전한 협력적 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.}입력 경로는 선택한 구체적인 표시 루트에 상대적입니다. 반환되는 ID는 여전히 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)); } });핀 생성에는 지원되는 저장된 프로젝트 소유 월드가 필요합니다. 메타데이터 업데이트는 위치, 월드, 앵커, 뷰 및 범위를 보존합니다.
작업 매트릭스, ID 계약, 오류 분류, 리비전 및 작업 상태는 Developer API 개요를 참조하세요.