- Documentation
- Locus
- C++ Developer API
C++ Developer API
Utilisez la Developer API native depuis un plugin ou outil C++ réservé à l’Editor. Ajoutez le module Locus aux dépendances du module Editor consommateur, incluez Locus.h pour l’acquisition et Developer/LocusDeveloperApi.h pour les requêtes et les résultats.
Contrat de durée de vie et d’asynchronisme
Section intitulée « Contrat de durée de vie et d’asynchronisme »GetLocusDeveloperApi() renvoie le FLocusDeveloperApi actif ou nullptr en dehors de la durée de vie Locus initialisée de l’Editor.
- Acquérez et soumettez sur le Game Thread.
- Ne conservez pas le pointeur API au-delà de l’arrêt du sous-système ou du module.
- Chaque fin d’opération s’exécute exactement une fois sur le Game Thread.
- Le travail accepté se termine lors d’un tick ultérieur de l’exécuteur existant de Locus.
- Un échec d’admission peut se terminer inline avant le retour de la soumission.
- Préparez l’état appartenant au callback avant la soumission.
- L’annulation est coopérative. Elle peut empêcher le travail en file, mais ne peut pas interrompre le travail du dépôt ni annuler rétroactivement une mutation déjà persistée.
- N’ajoutez ni attente bloquante, ni sleep, ni pompage du Game Thread, ni
Future.Get().
Le FLocusDeveloperRequestHandle renvoyé expose l’identité de la requête et un Cancel() coopératif thread-safe.
Créer un Document
Section intitulée « Créer un Document »#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.}Le chemin d’entrée est relatif à la racine de présentation concrète sélectionnée. L’identité renvoyée reste le chemin faisant autorité relatif à ProjectDocuments.
Récupérer, puis mettre à jour
Section intitulée « Récupérer, puis mettre à jour »Ne masquez pas la gestion des révisions. Utilisez la révision du résultat de lecture comme précondition de mutation :
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. } }); });Scope explicite d’une Note
Section intitulée « Scope explicite d’une Note »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 } });Les filtres de scope sont tout aussi explicites. All inclut le contenu Privé ; demandez Shared lorsqu’un outil ne doit pas l’inclure.
Création de base d’un Repère
Section intitulée « Création de base d’un Repère »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)); } });La création d’un Repère nécessite un monde enregistré pris en charge et appartenant au projet. Les mises à jour de métadonnées préservent la position, le monde, l’ancre, la vue et le scope.
Voir la vue d’ensemble de la Developer API pour la matrice d’opérations, le contrat d’identité, la taxonomie des erreurs, les révisions et l’état de l’opération.