Zum Inhalt springen
SheetForge

API-Referenz — die öffentliche Oberfläche

Diese Seite listet jeden öffentlichen Typ in den Produkt-Assemblies auf. Alles, was hier nicht aufgeführt ist, ist bewusst internal; die öffentliche Oberfläche ist absichtlich schmal gehalten.

  • Core (SheetForge.Core + SheetForge.Core.Tooling): 137 öffentliche Typen (Core: 131, Core.Tooling: 6). Core.Tooling ist die editor-only Hälfte mit Import-Zeit-Diensten wie Reporting und Push-Planung — nichts davon wird in Player-Builds ausgeliefert.
  • Editor: 53 öffentliche Typen der obersten Ebene plus deren öffentliche verschachtelte Typen.
  • Runtime: 7 Typen, plus generierte Ausgaben.

Das ist genau die Oberfläche, gegen die die Konsumenten-Simulationstests (ohne InternalsVisibleTo) kompilieren.

Erkennungsvertrag (kein Typ): Ein separates Asset kann außerdem zur Kompilierzeit erkennen, dass SheetForge installiert ist, über das SHEETFORGE-Scripting-Define-Symbol, das die Editor-Assembly selbst registriert. Es ist ein Define, kein öffentlicher Typ, daher ist es in den folgenden Tabellen nicht aufgeführt — siehe Plugin-Erstellung ▸ SheetForge aus einem anderen Asset erkennen. (Getrennt von SHEETFORGE_ADDRESSABLES, einem internen Version-Define, das lediglich markiert, ob das Addressables-Paket vorhanden ist.)

Konventionen: Signaturen sind abgekürzt ( = siehe XML-Dokumentation im Quellcode); „pure" bedeutet kein UnityEngine / keine IO.


Core-Assembly (SheetForge.Core) — reines C#

Kein UnityEngine, keine IO, kein Netzwerk, keine Domänenkenntnis. Compilererzwungen: Core referenziert nichts.

Plugin-Registrierungsverträge (SheetForge.Core.Plugins)

TypArtRolle & Schlüsselmember
ISheetForgePlugininterfaceDer Basis-Domänen-Plugin-Vertrag. string Name · RegisterEnums(EnumRegistry) · RegisterCellParsers(CellParserRegistry)
ISheetForgeValidatorPlugininterfaceOptionale Erweiterung für Validierungsregeln. RegisterValidators(DomainValidatorRegistry)
ISheetForgeEdgePlugininterfaceOptionale Erweiterung für Kanten-Deklarationen. RegisterEdgeContributors(EdgeContributorRegistry)
ISheetForgeMarkerPlugininterfaceOptionale Erweiterung für benutzerdefinierte Strukturmarkierungen. RegisterStructuralMarkers(MarkerRegistry)
ISheetForgeTemplatePlugininterfaceOptionale Erweiterung für „Create sheet"-Vorlagen. RegisterTemplates(TemplateRegistry)
ISheetForgeGraphPlugininterfaceOptionale Erweiterung, die Canvas-Overrides pro Tab für das Data Studio registriert. RegisterGraphShapes(GraphShapeRegistry)
ISheetForgeCodeRegistryPlugininterfaceOptionale Erweiterung für code-eigene Referenzziele (gesperrte virtuelle Tabs). RegisterCodeRegistries(CodeRegistryCatalog)
ISheetForgeThemePlugininterfaceOptionale Erweiterung für Farb-Presets der Fenster. RegisterThemes(ThemeRegistry)
ISheetForgeStudioPlugininterfaceOptionale Erweiterung für deklarative Authoring-Oberflächen (Aktionen, Panels, Spalten-Badges, Cell-Editor-Hints). RegisterStudioUi(StudioUiRegistry). In Core statt in Editor, damit eine Registrierung sowohl im UIToolkit-Editor als auch im Browser rendert
ISheetForgeStringsPlugininterfaceOptionale Erweiterung, die die eigenen UI-Strings des Pakets pro Sprache registriert. RegisterStrings(StringOverlayRegistry). Ersetzt das ausrangierte editor-seitige Paar ISheetForgeLocPlugin / PluginLocRegistry, das nur den Editor erreichen konnte
ISheetForgePipelinePlugininterfaceOptionale Erweiterung, die Pipeline-Beobachter registriert. RegisterPipelineObservers(PipelineObserverRegistry)

Zusammenstellung und Kompatibilität (SheetForge.Core.Plugins)

Die Entdeckung ist pro Host verschieden — Unitys TypeCache im Editor, der Scan der hochgeladenen Assembly im Browser. Alles danach (Instanziierung, Reihenfolge, Isolation und das Kompatibilitäts-Gate) ist eine einzige gemeinsame Core-Funktion, die verhindert, dass die beiden Hosts Slot für Slot auseinanderdriften.

TypArtRolle & Schlüsselmember
PluginCompositionstatic classDer einzige Assembly-Pfad. Eine Instanz pro Typ, auf jeden Vertrag gecastet, den er implementiert. Die zwei Member und die Diagnose-Aufteilung sind unterhalb der Tabelle
PluginSetsealed classDas zusammengestellte Ergebnis — zwölf Slots: Enums · Parsers · Validators · EdgeContributors · Markers · Templates · GraphShapes · CodeRegistries · Themes · Strings · StudioUi · PipelineObservers. Ein neuer Slot erreicht beide Hosts, indem er hier hinzugefügt wird
SheetForgePluginCompatAttributesealed attribute (assembly)[assembly: SheetForgePluginCompat(SheetForgePluginFormat.Current, MinHostVersion = "…", PluginVersion = "…")]. int FormatVersion · string MinHostVersion (numerischer Punktvergleich; null/leer = keine Anforderung) · string PluginVersion (nur Anzeige, nie verglichen). Wird gelesen, ohne irgendetwas zu instanziieren, und pro Assembly beurteilt — eine abgelehnte Assembly verliert jede Registrierung, statt halb zu laden. Fehlt = Generation Minimum, keine Host-Anforderung
SheetForgePluginFormatstatic classDie Generationskonstanten: const int Current · const int Minimum. Bewegt sich nur, wenn das Plugin-Format selbst ersetzt wird — rein additives Wachstum lässt die Zahl unverändert

PluginComposition — die zwei Member:

  • IReadOnlyList<Type> ContractTypes — der Entdeckungsfilter. Seine Reihenfolge ist fest, weil sie bestimmt, in welcher Reihenfolge Diagnosen erscheinen.
  • PluginSet Compose(IReadOnlyList<Type> candidateTypes, string hostVersion, ErrorCollector errors, ICollection<string> failures, Func<string,bool> isProductKey = null) — der Zusammenstellungsaufruf selbst.

Zwei Arten von Problemen werden auseinandergehalten. Registrierungskonflikte und Kompatibilitätsablehnungen werden zu strukturierten Diagnosen in errors; Implementierungsfehler — Konstruktionsfehler, ein werfender Callback — werden zu englischen Zeilen in failures, und null dort zu übergeben verwirft sie.

Das nachgestellte Prädikat isProductKey ist, wie die Regel „ein Plugin darf keinen Produktschlüssel überschreiben" des String-Overlays erzwungen wird, ohne dass Core je die Sprachtabellen sieht: Die Regel lebt hier, der Host liefert nur das Material. Lassen Sie das Prädikat weg, wird nur diese eine Regel übersprungen.

Registries (SheetForge.Core.Model / .Validation / .Edges)

TypRolle & Schlüsselmember
EnumRegistryenum-Name → CLR-Typ (Codegen-Material). Register<TEnum>() · Register(name, memberNames) · TryGetMembers · TryGetClrTypeName · TryGetClrAssemblyName · RegisteredEnumNames. Drei weitere Member sind unterhalb der Tabelle im Detail beschrieben
CellParserRegistryTypname → Zellparser (open-closed). Doppelte Registrierung wirft eine Exception. Register(ICellValueParser) · TryGet · TryGetCustomRenderer · RegisteredTypeNames · RegisterWrapper(ICellWrapperType) · TryGetWrapper · RegisteredWrapperNames (Wrapper-Typen)
DomainValidatorRegistryNur anfügbare Validator-Liste, Reihenfolge bleibt erhalten. Register(IDomainValidator) · Validators
EdgeContributorRegistryNur anfügbare Contributor-Liste, Reihenfolge bleibt erhalten. Register(IEdgeContributor) · Contributors
MarkerRegistryMarkierungsname (ohne @) → benutzerdefinierte Strukturmarkierung. Kollision mit einer eingebauten Markierung (SheetSyntax.ReservedMarkers@name/@type/@desc/@overlap/@style/@enum/@loc) / Duplikat / ungültiger Bezeichner wirft eine Exception. Register(IStructuralMarkerDefinition) · TryGet · IsEmpty · RegisteredMarkerNames · AppendMarkerTokens
TemplateRegistry„Create sheet"-Vorlagenschlüssel → Vorlage. Leerer/doppelter Schlüssel, leere Anzeige, null Tabs, leeres Tab-TSV werfen eine Exception. Register(DataTemplate) · TryGet · Templates · IsEmpty

EnumRegistry — die drei Member im Detail:

  • EnumRegistry(EnumRegistry parent) — ein Kind, das lesend auf ein Parent zugreift und nur bei sich selbst registriert. Das Parent hält die per Plugin registrierten CLR-Enums für den gesamten Domain-Reload, das Kind die tabellendefinierten dieses Imports, sodass ein Import den gemeinsamen Cache nie mutiert. Die Registrierung eines Namens, den das Parent bereits besitzt, wirft eine Exception, statt ihn zu überschatten.
  • Contains(name) — erst eigene, dann Parent, ordinal.
  • SetClrTypeName(name, fullTypeName) — trägt nach einer reinen String-Registrierung einen CLR-Namen nach. Der Assembly-Name bleibt leer, weil der Typ noch nicht existiert.

„Create sheet"-Vorlagen (SheetForge.Core.Model)

TypRolle & Schlüsselmember
DataTemplateEine von einem Plugin registrierte Vorlage: string Key (Registry-Identität) · string DisplayName (plugin-eigener Text) · IReadOnlyList<DataTemplateTab> Tabs (einer oder mehrere)
DataTemplateTabEin Tab einer Vorlage: string TabName · string Tsv (ein vollständig normalisiertes TSV — Markierungszeilen plus Beispieldaten)

Benutzerdefinierte Zelltypen (SheetForge.Core.Model)

TypRolle & Schlüsselmember
ICellValueParserParst eine skalare Zelle. Fehlschlag = in context.Errors sammeln + false zurückgeben (nie werfen). string TypeName · bool TryParse(CellParseContext, string, out object)
ICustomCellTypeOptionaler Codegen-/Round-Trip-Helfer. Type ValueType · bool TryRender(object, out string text, out string reason)
IReferencingCellTypeOptionale Capability, die ein registrierter ICellValueParser zusätzlich implementieren kann, damit ein in seiner eigenen Notation vergrabener Schlüssel die volle RecordId@Tab-Behandlung erhält — Integrität + Vorschläge, Propagierung von Schlüssel-Umbenennungen unter Erhalt der Nutzlast, Graph-Kanten und Ports, den -Picker, Waisen-Erkennung, exportierte Dropdown-Regeln. Wird per Cast des registrierten Parsers gefunden (kein separater Registrierungskanal). bool TryGetTokenKey(elementText, out key) · string MakeToken(key) · bool TryRetargetToken(elementText, newKey, out newText) · bool TryRemoveToken(elementText, key, out newText) (leeres Ergebnis = das Element verschwindet) · bool TryRewriteKeys(elementText, IReadOnlyDictionary<string,string> renames, out newText). Ein Aufruf = ein Element (die ganze Zelle, oder ein durch ; getrenntes Element), daher darf eine Nutzlast kein ; enthalten; @target muss einen echten Tabellen-Tab benennen (sonst UnknownTargetTab). Wirft nie — false/null bedeutet „kann nicht interpretiert werden", und Umschreibungen bewahren den Rest
IRefBearingValueDie werteseitige Hälfte des Obigen, implementiert vom geparsten Wert: IEnumerable<string> ReferencedKeys (Deklarationsreihenfolge = Diagnose- und Vorschlagsbudget-Reihenfolge; null-/leere Einträge werden übersprungen). Der Scanner liest dies; die obigen Text-Hooks schreiben die Zelle um. Beide werden benötigt — ein geparster Wert kann die Notation des Autors nicht wiederherstellen, und Text kann nicht validiert werden, ohne gelesen zu werden
ICellWrapperTypeEine generische Wrapper-Wertform MyWrapper<T> (z. B. Pair<int> = 1~2) — der Wrapper besitzt die äußere Syntax, und der Core parst den inneren Typ rekursiv. string Name · bool TrySplit(string, out IReadOnlyList<string> pieces, out string reason) · string JoinCanonical(IReadOnlyList<string>) · Type OpenClrType · object Assemble(IReadOnlyList<object>, Type closed) · bool TryDisassemble(object, out IReadOnlyList<object>, out string reason)
WrapperValueDie geparste IR einer Wrapper-Zelle — trägt die Wrapper-Strategie + legt die inneren CellValues offen (sodass Referenzen darin Validierung, Schlüssel-/Tab-Umbenennung und Export durchlaufen). ICellWrapperType Wrapper · IReadOnlyList<CellValue> Inner
IStructuralMarkerDefinitionEine benutzerdefinierte @marker-Zeile (Werte pro Spalte, Spalte für Spalte validiert — verallgemeinert @overlap). string MarkerName (ohne @) · string Description · void ValidateCell(MarkerCellContext)
MarkerCellContextEin Validierungsaufruf für eine Markierungszelle. string MarkerName · string RawText · string FieldName · CellCoordinate Coordinate · void Reject(string reason, string suggestion = null) (→ MarkerCellInvalid)
CellParseContextDer Kontext eines Parse-Aufrufs. TypeToken Type · CellCoordinate Coordinate · ErrorCollector Errors · EnumRegistry Enums

Sheet-Grammatik-Konstanten (SheetForge.Core.Model)

Ein Paket, das Zellentext liest oder schreibt, arbeitet mit derselben Grammatik wie der Import — eine Listenzelle aufteilen, einen @type-String zusammensetzen, prüfen, ob ein Name bereits vergeben ist.

Diese Konstanten sind die einzige Quelle der Wahrheit für diese Grammatik, sodass ein Paket nie ein eigenes Trennzeichen neu festlegt: Ein kopiertes Zeichen läuft an dem Tag auseinander, an dem sich die Grammatik ändert. Die Listen werden schreibgeschützt herausgegeben, sodass nichts, was ein Paket tut, die Grammatik selbst ändern kann. Die Notation, die sie ausbuchstabieren, ist vollständig auf der Seite Tabellensyntax dokumentiert — dies ist der programmatische Zugriff darauf.

TypArtRolle
SheetSyntaxstatische KlasseDie Sheet-Grammatik als Konstanten, unten gruppiert

Markierungen

  • CommentPrefix (#) · MarkerPrefix (@).
  • Eine Konstante pro eingebauter Markierungszeile: NameMarker · TypeMarker · DescMarker · OverlapMarker · StyleMarker · EnumMarker · LocMarker.
  • RequiredMarkers — die drei, die jede Tabelle tragen muss.
  • ReservedMarkers — jeder eingebaute Name. Sehen Sie hier nach, bevor Sie eine eigene Markierung benennen: Eine Kollision wird bei der Registrierung abgelehnt.

Trennzeichen

  • ListSeparator (;) — zwischen Listenelementen.
  • EntrySeparator (,), FieldSeparator (:), SectionSeparator (|), KeyTimeSeparator (@) — die Ebenen innerhalb eines einzelnen Werts, weshalb ; niemals im eigenen Text eines Werts auftaucht.
  • StyleKeyValueSeparator (=) — innerhalb einer @style-Zelle.

@type-Notation

  • OptionalSuffix (?) · DefaultSeparator (=) · TargetSeparator (@, wie in RecordId@Tab).
  • ListTypeName · ListOpen (List<) · ListClose (>).

Typnamen

  • Eine Konstante pro eingebautem Namen: IntTypeName · FloatTypeName · BoolTypeName · StringTypeName · RecordIdTypeName · IntIdTypeName · AssetRefTypeName · LocRefTypeName · ColorTypeName · AnimationCurveTypeName · GradientTypeName · EnumTypeName.
  • BuiltinScalarTypes und IsBuiltinScalarTypeName(name) — beantworten „Ist dieser Name bereits eingebaut?", bevor ein Parser unter diesem Namen registriert wird.
  • StyleKeyNames (title, color) · LocReservedColumns (smart, comment).

Werte

  • TrueCanonical / FalseCanonical — der kanonische bool-Text.
  • NumberCellStyles — die NumberStyles, mit denen jede numerische Zelle gelesen wird. Tausendertrennzeichen sind ausgeschlossen, und die Culture ist immer invariant, sodass ein lokales Dezimalkomma laut fehlschlägt, statt eine Zahl still zu verändern.

Domänen-Validierung (SheetForge.Core.Validation)

TypRolle & Schlüsselmember
IDomainValidatorSpalten-/tab-übergreifende Regel. Verstöße → ctx.Errors als DomainRuleViolation mit allen 4 Elementen. string Name · Validate(DomainValidationContext)
DomainValidationContextTables (Tab → SheetTable) · KeyIndices · AssetKeys (null = übersprungen) · Errors

Kanten-Nahtstelle (SheetForge.Core.Validation / .Edges)

TypRolle & Schlüsselmember
ReferenceScanner (static)Einzige Quelle der Wahrheit für die Aufzählung von Referenz-Vorkommen. Scan(tables) · ScanTable · ScanField · IsReferenceField(TypeToken), plus die zwei Referenz-Prädikate unterhalb der Tabelle im Detail
RefKeyKind (enum)Ob eine Referenz gegen den String- (RecordId) oder den Integer- (IntId) Schlüsselraum abgleicht. Zurückgegeben von ReferenceScanner.GetReferenceKind; Konsumenten verzweigen darauf. Nur anfügbar
ReferenceOccurrence (struct)Ein Vorkommen — Kind · FromTab · RowNumber · ColumnNumber · FieldName · TargetTab · TargetId · ToCoordinate()
ReferenceOccurrenceKind (enum)Scalar · ListElement · ExplicitDefault · WrapperElement · CustomElement (eine Referenz, die ein IRefBearingValue aus seiner eigenen Notation heraus deklariert hat — Koordinaten auf Zellenebene, da das innere Layout diesem Typ gehört). Nur anfügbar, sodass bestehende Werte ihre Bedeutung behalten
IEdgeContributorDeklariert Kanten, die der Scanner nicht sehen kann. Keine Diagnosen. string Name · ContributeEdges(EdgeContributionContext, ICollection<EdgeSpec>)
EdgeSpecEine Kante — FromTab/FromRecordId/ToTab/ToRecordId (+ optional FieldName, PayloadTab/PayloadRecordId für Datensatz-Kanten, Label)
EdgeContributionContextSchreibgeschützte Tables + KeyIndices (kein Error-Collector — Kanten sind keine Validierung)
IAuthorableEdgeContributorOptionale Capability, die ein IEdgeContributor zusätzlich implementieren kann, damit seine Kante auf der Graph-Canvas bearbeitet werden kann. bool TryPlanConnect(EdgeAuthoringContext, fromTab, fromRecordId, toTab, toRecordId, out EdgeCellWrite) · bool TryPlanDisconnect(EdgeAuthoringContext, RecordEdge, out EdgeCellWrite)false = nichts wird vorgemerkt, und die Möglichkeit ist mit einem Grund deaktiviert; beide laufen innerhalb von try/catch
IEdgeTokenEditorOptionale Capability, die ein IEdgeContributor zusätzlich implementieren kann, damit der Rest seines Tokens (alles, was nicht der Schlüssel ist) im Verbindungs-Inspector bearbeitet werden kann. bool TryDescribeToken(EdgeAuthoringContext, RecordEdge, out EdgeTokenDescription) · bool TryPlanSetModifier(EdgeAuthoringContext, RecordEdge, string newModifier, out EdgeCellWrite) — beide lesen dieselbe Zelle (eine Kante weiß, wohin sie zeigt, nicht, wie sie heute geschrieben ist), false = die Zeile ist verborgen oder ehrlich deaktiviert; beide laufen innerhalb von try/catch
EdgeTokenDescriptionWas ein Token ist und wie sein Rest bearbeitet wird — TokenText (das hervorzuhebende Fragment) · ModifierText · HasModifier · ModifierLabel · IsChoice · Options / OptionLabels. new EdgeTokenDescription(tokenText) = kein Rest, daher wird keine Zeile gezeichnet; der Auswahl-Konstruktor fällt bei leerer Optionsliste auf Freitext zurück
IBatchAuthorableEdgeContributorOptionale Capability, Geschwister von IAuthorableEdgeContributor (keine Vererbung): Connect-/Disconnect-Pläne als Liste von Zellschreibvorgängen, für Daten, bei denen eine Geste mehrere gepaarte Zellen gemeinsam ändern muss. bool TryPlanConnectMany(EdgeAuthoringContext, fromTab, fromRecordId, toTab, toRecordId, out IReadOnlyList<EdgeCellWrite>) · bool TryPlanDisconnectMany(EdgeAuthoringContext, RecordEdge, out IReadOnlyList<EdgeCellWrite>) — die gesamte Liste wird als ein Undo-Schritt vorgemerkt oder gar nicht; einzelne Contributor funktionieren weiterhin (Fallback), und Batch gewinnt, wenn eine Klasse beides implementiert
IVirtualNodeFactoryOptionale Capability: Canvas-„Erstellen"-Gesten, die keine neue Sheet-Zeile sind. IReadOnlyList<VirtualNodeKind> KindsFor(EdgeAuthoringContext, tab, recordId) (wird pro Menüaufbau aufgerufen — leicht halten) · bool TryPlanCreate(EdgeAuthoringContext, tab, recordId, VirtualNodeKind, out IReadOnlyList<EdgeCellWrite>)false = die Session bleibt unangetastet. Ein Plan kann keinen Datensatz anvisieren, der in derselben Geste erstellt wurde
VirtualNodeKind (struct)Eine erstellbare Art — Id (wird bei Auswahl wortgetreu zurückgegeben) · Label (bereits übersetzter Menütext; / verschachtelt) · IsUsable. Null-sicher, default-sicher
IEdgeSlotDeclarerOptionale Capability: Ports, die ein (virtueller) Node öffnet, ohne eine lebende Kante zu benötigen. IReadOnlyList<DeclaredSlot> DeclareSlots(EdgeAuthoringContext, nodeTab, nodeRecordId) — deklarierte Slots treten dem Connect-Menü, dem Port-Picker und den Port-Zeilen der Karte bei; wird pro Render aufgerufen, daher müssen Implementierungen leicht und nebenwirkungsfrei sein
DeclaredSlot (struct)Ein deklarierter Slot — FieldName (eindeutig pro Node; muss dem FieldName der Contributor-Kante entsprechen, damit Verbindungen ankern) · TargetTab · IsList · IsUsable. Null-sicher, default-sicher
EdgeAuthoringContextDie Planungseingabe — Tables + string CellText(tab, recordId, field), das die Zelle so, wie sie jetzt gelesen wird zurückgibt (Baseline plus Staging), sodass zwei nacheinander erstellte Verbindungen einander sehen
EdgeCellWrite (struct)Der Plan: TabName · RecordId · FieldName · NewRawText (leer = löschen) · IsAddressable. Adressiert per Schlüssel, nicht per Zeilennummer

ReferenceScanner — die zwei Referenz-Prädikate:

  • GetReferencedTab(TypeToken) — das eine Prädikat, das jeder Konsument fragt: „ist das eine Referenz, und wohin". Es beantwortet dies für RecordId@Tab, für IntId@Tab (den Integer-Schlüsselraum), für das Innere eines Wrappers und für einen mit IsCustomReference markierten benutzerdefinierten Typ. Deshalb aktiviert ein einziges Opt-in — und, für IntId@Tab, eine Erweiterung dieses Prädikats — alle auf einmal.
  • GetReferenceKind(TypeToken)RefKeyKind — ob die Referenz gegen den String- oder den Integer-Schlüsselraum abgleicht, sodass Umbenennungs-Propagierung, Dropdown und Picker korrekt verzweigen.
  • GetReferenceKind(TypeToken, tables) — die tabellenbewusste Überladung.

Eine Core-Referenz nennt ihren eigenen Raum (RecordId / IntId). Ein referenzierender benutzerdefinierter Typ hat keine Notation, um ihn zu benennen — MyType@Tab ist die einzige Schreibweise —, daher wird sein Raum aus der Identität des Ziel-Tabs abgeleitet: Ein RecordId-Eigenschlüssel bedeutet String-Raum, allein IntId bedeutet Integer-Raum, und ein unbekannter Tab oder null-Tabellen fallen auf String-Raum zurück — dieselbe Antwort, die die reine Token-Überladung gibt. Diese Ableitung ist es, die einer bestehenden IReferencingCellType-Implementierung erlaubt, auf einen IntId-Schlüssel-Tab zu zielen, ohne eine einzige Zeile zu ändern.

Referenzgraph-Index (SheetForge.Core.Edges)

Ein unveränderlicher Schnappschuss, der core-gescannte Referenzen und Contributor-Kanten zu einem Modell zusammenführt, in beide Richtungen indiziert. Anzeigematerial — er erzeugt nie Diagnosen (die Diagnostics der Projektion bleiben die einzige Quelle der Wahrheit für Probleme).

TypArtRolle & Schlüsselmember
RecordEdge (struct)WertEine Kante. RecordEdgeOrigin Origin · FromTab · FromRecordId (leer bei Kanten auf Feldebene) · FieldName · RowNumber / ColumnNumber (1-basiert; 0 = Feld-/Tab-Ebene) · ToTab · ToRecordId (die beabsichtigte Id, auch wenn unaufgelöst) · bool IsDangling (zur Bauzeit festgelegt) · Label · PayloadTab / PayloadRecordId (Datensatz-Kanten)
RecordEdgeOrigin (enum)CoreReference (aus einer RecordId@Tab-Zelle gelesen — hat Koordinaten) · Contributor (von einem IEdgeContributor deklariert — auf Datensatzebene)
ReferenceIndexsealed classDer Schnappschuss. static Build(tables, keyIndices, contributorEdges, codeRegistries, extraKeys = null) (die letzten drei dürfen null sein; extraKeys = Tab → Schlüssel, die existieren, aber noch nicht geparst sind, z. B. Zeilen, die eine Authoring-Oberfläche gerade vorgemerkt hat, sodass Links zu ihnen nicht als defekt gezeichnet werden) · AllEdges (deterministische Reihenfolge: Von-Tab ordinal → Zeile → Spalte → Vorkommen) · OutEdges(tab, recordId) / InEdges(tab, recordId) (nie null) · int InCount(tab, recordId) · bool TryGetRowKey(tab, rowNumber, out recordId) · DanglingEdges

Record-Canvas des Data Studio (SheetForge.Core.Graphing)

Die Canvas entscheidet selbst, was sie zeichnet: Sie durchläuft den Referenz-Index ausgehend vom geöffneten Datensatz (der Terminus) und legt das Ergebnis deterministisch an. Ein Plugin ersetzt dieses Bild nicht — es ergänzt es. Durchgehend reine Daten: Spalten sind Grid-Zellen, keine Pixel, und Farben sind ein freier Category-String, den das Fenster auf eine Palette abbildet.

TypArtRolle & Schlüsselmember
IRecordCanvasAugmenterinterfaceDer Canvas-Override eines Tabs, aufgerufen nachdem die Closure zusammengesetzt ist. Augment(GraphBuildContext, CanvasAugmentBuilder, string terminusTab, string terminusRecordId). Nichts hinzuzufügen belässt das Kernbild, wie es ist; ein Wurf wird vom Fenster abgefangen und wird zu einer englischen Konsolen-Warnung. Identität gehört den Daten (ein virtueller Node verliert gegen einen echten Datensatz mit demselben Schlüssel); Darstellung — der Anzeige-Hinweis — nicht
CanvasAugmentBuildersealed classDie Schreiboberfläche, nur vier Dinge — Member und Regeln unterhalb der Tabelle
GraphShapeRegistrysealed classTab-Name → Canvas-Override. Register(tabName, IRecordCanvasAugmenter) (doppelter Tab / leerer Name / null wirft) · TryGet · IsEmpty
GraphBuildContextsealed classDie schreibgeschützte Eingabe des Overrides. Tables (Tab → SheetTable) · ReferenceIndex References · IReadOnlyList<CodeRegistrySource> CodeRegistries (leer, nie null). Kein Error-Collector — eine Canvas ist Anzeige, keine Validierung
GraphSpecBuildersealed classDer Graph-Zusammenbau-Helfer. Konstruktor (GraphBuildContext) · static NodeKey(tab, recordId) (die einzige Wahrheit, auf die Verbindungen zeigen) · AddNode(GraphNodeSpec) (der erste (Key, Column) gewinnt) · AddWire(GraphWireSpec) · AddWire(fromKey, toKey, label, fromTab, fromRecordId, fieldName, isCyclic = false, cyclicNote = null) (der Overload, der zusätzlich die Zelle benennt, in die der Link geschrieben ist, was die Verbindung erst bearbeitbar macht)
GraphSpecsealed classDas zusammengesetzte Ergebnis, das die Canvas zeichnet — Nodes · Wires (der Zusammenbau läuft über den Builder; der Konstruktor ist internal)
GraphNodeSpecsealed classEin Node. Key · Tab · RecordId · Title · Subtitle · Category · CellCoordinate Address · Column / Row (Grid-Zellen, die die Canvas bereits gelöst hat — hier getragen, nicht gewählt) · IsFocus (der Terminus) · IsMissing · InCount · IsCyclic
GraphWireSpecsealed classEine Verbindung. FromKey · ToKey · Label · IsCyclic · CyclicNote, plus die optionale besitzende Zelle: FromTab · FromRecordId · FieldName · RecordEdge? SourceEdge (null = nur-Anzeige-Verbindung; die Canvas sagt dann, dass sie nicht bearbeitet werden kann). Die fünf Anzeige-Argumente bleiben unverändert, sodass bestehende Aufrufe kompilieren und identisch gerendert werden
IAuthorableGraphShapeinterfaceOptionale Capability, die ein IRecordCanvasAugmenter zusätzlich implementieren kann. IReadOnlyList<string> CreatableTabs(GraphBuildContext, string tabName) — wo die Canvas einen Datensatz erstellen darf (leer = nirgends). Die Vorgaben ohne sie sind unterhalb der Tabelle beschrieben

CanvasAugmentBuilder — die Schreiboberfläche. Nur vier Dinge:

  • AddNode(tab, recordId, title = null, category = null) / AddNode(tab, recordId, title, category, CellCoordinate address) — ein virtueller Node für eine Identität, die kein Sheet-Datensatz ist (ein Event-Schlüssel, ein Code-Atom); der Tab darf leer sein.
  • AddEdge(fromTab, fromRecordId, toTab, toRecordId, label = null, fieldName = null, fieldOnTarget = false, isCyclic = false, cyclicNote = null) — eine zusätzliche Kante, die der Core-Scanner nicht sehen kann. Die Benennung von fieldName sagt, in welche Zelle der Link geschrieben ist, fieldOnTarget sagt, dass diese Zelle beim Ziel statt beim Ausgang sitzt, und das Zyklus-Paar markiert eine Schleife zur Anzeige mit der Notiz, die nur die Domäne kennt.
  • SetLayer(tab, recordId, layer) — ein absoluter Layer-Hinweis (0 = ganz links, negativ = weiter links, alles andere verschiebt sich zum Ausgleich nach rechts). SetLayerRelative(tab, recordId, offset) — dasselbe vom Terminus aus gezählt (−1 = eine Spalte links davon), aufgelöst gegen die Terminus-Spalte, bevor irgendein Hinweis sie verschoben hat.
  • SetSubtitle(tab, recordId, subtitle) — ein Anzeige-Hinweis, das Einzige, was auch für bereits existierende Datensätze und für nicht auf dem Bildschirm befindliche Datensätze gilt (der Connect-Picker liest diese).

Einträge mit leerem Schlüssel werden ignoriert; was gesammelt wurde, ist internal, weil die Zusammenführungsregeln an einer Stelle leben. Jede Erweiterung ist nachgestellt, sodass ein gegen eine frühere Oberfläche geschriebener Override weiterhin kompiliert.

IAuthorableGraphShape — die zwei Vorgaben ohne sie:

  • Die Liste erstellbarer Tabs, die diese Capability ersetzt — die Achse, die auch entscheidet, ob eine Canvas überhaupt öffnet und wie weit der Sweep ausstehender Zeilen reicht — deckt jeden Tab ab, der vom Fokus-Tab aus transitiv entlang des Schemas erreichbar ist.
  • Die Verlinkungs-Kaskade, die der Nutzer tatsächlich sieht, beginnt bei den Tabs, auf die die gerade gezeichneten Ports zielen.

Beide lassen Code-Registry-Tabs und Tabs ohne Schlüsselspalte aus. Ein von hier zurückgegebener Tab, den kein gezeichneter Port akzeptiert, bleibt mit angehängtem Grund in der Verlinkungs-Kaskade gelistet, und die eigenen Schranken des Fensters gelten weiterhin zusätzlich.

Farb-Presets (SheetForge.Core.Theming)

TypRolle & Schlüsselmember
ThemeRegistryPreset-Id → Theme. Leere Ids, Duplikate und die zwei reservierten eingebauten Ids werfen eine Exception. Register(SheetForgeTheme) · TryGet · Themes · IsEmpty · IsBuiltInId(id) · BuiltInDefaultId · BuiltInHighContrastId
SheetForgeThemeEin Farb-Preset. Id · DisplayName · DarkColors / LightColors (IReadOnlyDictionary<ThemeColorSlot, uint>, beim Konstruieren kopiert) · TryGetColor(dark, slot, out rgb) · IsEmpty
ThemeColorSlotenum — die 33 Farbrollen, die ein Preset überschreiben darf (Oberflächen, Linien, Text, semantische Farben, Staging-Markierungen, Fehler-Oberflächen, Scrim, Graph). Farben sind 0xRRGGBB: Core referenziert keinen Engine-Typ, und durchscheinende Füllungen leiten sich aus einer Slot-Farbe plus einem festen Alphawert ab. Nur anfügbar.

Ein Preset überschreibt nur die Slots, die es benennt; jeder andere Slot behält die Produktvorgabe, sodass ein Preset gültig bleibt, während Slots hinzukommen. Das Registrieren wendet ein Preset nie an — der Nutzer wählt eines unter Preferences ▸ SheetForge ▸ Theme.

Deklarative Authoring-Oberflächen (SheetForge.Core.Studio)

Ein Plugin beschreibt, was gezeigt werden soll — die Hülle als Daten, Prädikat und Effekt als Delegaten —, und jeder Host zeichnet es mit seinen eigenen Widgets: UIToolkit im Editor, React im Browser. Nirgends erscheinen Layout-Zahlen. Was gesagt wird, gehört dem Plugin, wie es platziert wird, dem Renderer.

Jedes Enum hier ist nur anfügbar, sodass eine Registrierung ihre Bedeutung behält, während das Vokabular wächst.

TypArtRolle & Schlüsselmember
StudioUiRegistrysealed classWas RegisterStudioUi füllt. AddAction(StudioActionDescriptor) · AddPanel(StudioPanelDescriptor) · AddColumnBadge(StudioColumnBadgeDescriptor) · AddCellEditorHint(StudioCellEditorHint) · Actions / Panels / ColumnBadges / CellEditorHints · IsEmpty
StudioUiNodesealed classEin beschriebenes Fragment, unveränderlich, über statische Fabriken gebaut — die Fabriken, die lesbaren Eigenschaften und die URL-Regel stehen unterhalb der Tabelle
StudioUiNodeKindenumDie 13 Arten oben (RowLink)
StudioActionDescriptorsealed classEin Verb. Id (eindeutig) · LabelKey (ein Loc-Schlüssel; nicht registriert = wortgetreu angezeigt) · StudioActionPlacement Placement · Func<StudioSurfaceContext,bool> AppliesTo · Action<StudioSurfaceContext> Execute · ConfirmKey (optional — der Host fragt diesen Satz zuerst). Der Host prüft AppliesTo bei der Ausführung erneut, daher antwortet ein veralteter Menüeintrag mit einem ehrlichen No-op und einem Neuzeichnen
StudioActionPlacementenumInspector · RowContextMenu · TopbarMenu · ColumnHeaderMenu · CanvasNodeMenu. Jede Stelle füllt unterschiedliche Kontextfelder — die Zeilen-Stelle trägt den Datensatz, die Spalten-Stelle den Spaltennamen, die Canvas-Stelle den Datensatz dieses Nodes
StudioPanelDescriptorsealed classEin Panel im rechten Bereich des Studios. Id · TitleKey · Func<StudioSurfaceContext,StudioUiNode> Build — bei jedem Neuberechnungs-Tick neu aufgebaut, hält also keinen Zustand. Ist kein Panel registriert, wird der Bereich gar nicht gezeichnet
StudioColumnBadgeDescriptorsealed classEin Badge neben einem Spaltenkopf. Func<StudioSurfaceContext,string,string,StudioUiNode> Provide (Kontext, Tab, Feld) — null bedeutet nichts auf dieser Spalte
StudioCellEditorHintsealed class„Verwenden Sie für diesen Typ dieses eingebaute Widget" — wählt eine Art statt eine zu liefern. TypeName (ein exakter CellParserRegistry-Typname; eine Listen-Zelle wird anhand ihres Element-Namens abgeglichen; Wrapper-Zellen behalten den kanonischen Text und werden nie abgeglichen) · StudioCellEditorArchetype Archetype · GetOptions (nur Dropdown — Func<context, tab, field, IReadOnlyList<StudioCellOption>>) · SliderMin / SliderMax · ToggleTrueValue / ToggleFalseValue. Vier Konstruktoren, einer pro Materialform. Wird konsultiert, nachdem ein registrierter IStudioCellEditorProvider abgelehnt hat und bevor die eingebauten Zweige greifen; der Hint eines Pakets wird vor den eingebauten Hints unten konsultiert, sodass die Registrierung eines Hints unter Color, AnimationCurve oder Gradient den Standard-Editor für diesen Typ überschreibt. Ein List<>, dessen Element-Hint ColorPicker, CurveEditor oder GradientEditor ist, wird in beiden Hosts zu einem Chip-Editor
StudioCellEditorArchetypeenumDropdown · MultilineText · Slider · Toggle · ColorPicker (Zelltext #RRGGBB / #RRGGBBAA) · CurveEditor (Zelltext = die kanonische CurveValue-Notation) · GradientEditor (Zelltext = die kanonische GradientValue-Notation). Nur anfügbar — die beiden neuesten sind 5 und 6
BuiltinCellEditorHintsstatic classDie drei Hints, die der Core selbst deklariert — ColorColorPicker, AnimationCurveCurveEditor, GradientGradientEditor — auf demselben Weg wie die Hints eines Pakets, sodass der Editor und der Browser für sie keine unterschiedlichen Widgets wählen können. IReadOnlyList<StudioCellEditorHint> All (feste Reihenfolge) · bool TryGet(typeName, out hint) (Ordinal). Hosts konsultieren zuerst StudioUiRegistry.CellEditorHints und fallen auf diese Tabelle zurück
StudioCellOptionsealed classEin Dropdown-Kandidat — Value (der kanonische, in die Zelle geschriebene Text) · Label (was eine Person liest; Standard ist Value)
StudioSurfaceContextsealed classDie eine Nahtstelle, die eine Erweiterung sieht und über die sie handelt. Lesen: Tables · ReferenceIndex References · CodeRegistries · Tab · RecordId · Field · ActionArgument (der Wert, den ein Input-Node committet hat). Vermittelte Mutation, sonst nichts: Action<string,string,string,string> StageCell · Action<IReadOnlyList<EdgeCellWrite>> StageCells (ein Undo-Schritt, alles-oder-nichts) · Action<string,string> FocusRecord · Action RequestRebuild. Staging läuft durch das eigene Gate des Fensters, daher blockiert eine schreibgeschützte Quelle, eine laufende Pipeline oder ein arbeitsmappen-gestützter Tab mit einem Grund (Konstruktor internal: der Host stellt es zusammen)

StudioUiNode — Fabriken, Reads und die URL-Regel:

  • Fabriken: Row · Label · Chip · Badge · Button · Rule · Heading · KeyValue · Table(headerRow, rows) · List · Progress · Input · Link, plus WithTooltip(text), das einen neuen Node zurückgibt statt diesen zu ändern.
  • Reads: Kind · Text · Tooltip · ThemeColorSlot? Tone (nie eine fest codierte Farbe, folgt also dem Theme) · ActionId · Detail · Ratio · Url · Children.
  • static bool IsAllowedUrl(url) — nur http/https. Ein Prädikat, das beide Hosts befragen, sodass sie nie uneinig darüber sein können, was sicher zu öffnen ist.

Plugin-UI-Strings (SheetForge.Core.Model)

TypRolle & Schlüsselmember
StringOverlayRegistryCollector und Lookup-Overlay für per Plugin registrierte UI-Strings; Loc.Tr (Editor) und t() (Browser) befragen es vor den Produkttabellen. Register(key, language, value) · Register(key, IReadOnlyDictionary<string,string> byLanguage) · bool TryGet(key, language, out value) · RegisteredKeys. Sprachabgleich und die vier Ablehnungen stehen unterhalb der Tabelle

StringOverlayRegistry — Abgleich und Ablehnungen. language ist ein IETF-Code ("en", "ko", "zh-Hans", "pt-BR", …), Groß-/Kleinschreibung wird ignoriert. Der Lookup fällt zurück angeforderte Sprache → Englisch → Fehltreffer, und der Fallback lebt hier, damit beide Hosts identisch antworten.

Vier Registrierungen werden abgelehnt, jede mit einem für Entwickler bestimmten protokollierten Grund statt eines stillen Fehlschlags:

  • ein eingebauter Produktschlüssel — ein Overlay darf Schlüssel hinzufügen, nie die eigenen Sätze oder Menüpfade des Produkts überschreiben;
  • ein Schlüssel+Sprache-Paar, das ein anderes Paket bereits registriert hat — die zuerst gefundene gewinnt, weil sonst die Installationsreihenfolge über den Bildschirm entscheiden würde;
  • ein leerer Schlüssel oder Wert;
  • ein Sprachcode, den das Produkt nicht kennt, der nie nach Englisch gefaltet wird.

Pipeline-Beobachtung (SheetForge.Core.Plugins / .Model)

TypRolle & Schlüsselmember
IPipelineObserverSchreibgeschützte Benachrichtigung. void OnImportCompleted(PipelineRunView view) — einmal pro explizitem Import-Zyklus, an dessen Ende, ob erfolgreich oder fehlgeschlagen. Es gibt absichtlich keinen Hook, der einen Wert ändert oder eine Diagnose hinzufügt (das gehört einem Zelltyp und IDomainValidator), und keinen, der auf der Staging-Vorab-Validierung läuft. Ein Wurf wird isoliert, mit protokollierter Begründung; die Import-Ausgabe ändert sich nicht. Künftige Beobachtungspunkte kommen als Sibling-Capability-Interfaces, gecastet vom registrierten Beobachter, sodass eine heute geschriebene Implementierung weiter kompiliert
PipelineObserverRegistryNur anfügbare Beobachterliste, Reihenfolge bleibt erhalten. Register(IPipelineObserver) · Observers
PipelineRunViewDer unveränderliche Snapshot, den ein Beobachter erhält — Success (Validierung, d. h. wurde eine Registry zusammengestellt; Codegen-/Bake-Ergebnisse werden aus den Diagnosen gelesen) · Tables (geparste Tabs; bei einem fehlgeschlagenen Lauf fehlen nur die Tabs, die nicht geparst werden konnten, weil kein-Teil-Zusammenbau eine Ausgabe-Regel ist, keine Beobachtungsregel) · Diagnostics (dieselbe Liste, die der Bericht zeigt) · SkippedTabs · EnumTabs. Sammlungen werden beim Konstruieren kopiert, und der Konstruktor ist internal, sodass kein halb aufgebauter Snapshot an einen Beobachter übergeben werden kann

Code-Registries (SheetForge.Core.Graphing)

Referenzziele, die im Code leben und der Authoring-Oberfläche als gesperrte virtuelle Tabs zugänglich gemacht werden. Wird vom Data Studio konsumiert (Seitenleiste / Graph / Inspector), nicht vom Import-Validator.

TypArtRolle & Schlüsselmember
CodeRegistryCatalogsealed classRegistrierungswurzel. Register(CodeRegistrySource) (null / leerer Tab-Name / doppelter Tab-Name wirft) · TryGet(tabName, out source) · Sources · IsEmpty
CodeRegistrySourcesealed classEin gesperrter virtueller Tab. string TabName · IReadOnlyList<CodeRegistryEntry> Entries (Registrierungsreihenfolge = Anzeigereihenfolge)
CodeRegistryEntrysealed classEin Eintrag. string Key (worauf eine Referenz zeigen darf) · string Label · IReadOnlyList<string> Raises (null normalisiert zu leer). Core behandelt alle drei als opake Strings

Das IR-Lesemodell (SheetForge.Core.Model)

TypRolle & Schlüsselmember
SheetTableDas Parse-Ergebnis eines Tabs. SheetSchema Schema · IReadOnlyList<SheetRecord> Records
SheetSchemastring TabName · Fields · TryGetField(name, out FieldSchema) · SheetStyle Style (die @style-Anzeigemetadaten des Sheets) · bool IsLocalizationSheet (die Markierung @loc ist vorhanden) · IReadOnlyList<LocaleColumn> LocaleColumns (die Sprachspalten in ursprünglicher Spaltenreihenfolge — leer bei einem Sheet, das kein Lokalisierungs-Sheet ist, nie null) · TryGetLocaleColumn(localeCode, out LocaleColumn) (Suche über den Code, ohne Beachtung der Groß-/Kleinschreibung) · TryGetSourceLocale(out LocaleColumn) (die erste Sprachspalte; false, wenn es keine gibt)
SheetStyleDer Wert der @style-Zeile — Anzeigemetadaten für ein Sheet. string Title (Gruppenbezeichnung in der Seitenleiste) · string ColorHex (#RRGGBB wie geschrieben) · bool HasColor · static None (keine Formatierung). Wird nie von Codegen, Bake oder dem Schema-Fingerabdruck gelesen
LocaleColumn (struct)Eine Sprachspalte eines Lokalisierungs-Sheets — das, was die @loc-Zeile auf diese Spalte geschrieben hat. string Code (der Code exakt wie geschrieben; der Core validiert die Schreibform, nie ob die Sprache existiert) · string FieldName · int ColumnNumber (1-basiert) · bool IsSource (die erste Sprachspalte — diejenige, die Inline-Vorschauen lesen und in die das Prägen schreibt)
SheetRecordint RowNumber (Original, 1-basiert) · Values (Feld → CellValue) · TryGet · Indexer
FieldSchemaName · TypeToken Type · Description · ColumnNumber · DefaultValue · AllowOverlap · IReadOnlyDictionary<string,string> MarkerValues (Name der benutzerdefinierten Markierung → der Zelltext dieser Spalte)
TypeTokenGeparste @type-Zelle. RawText · TypeName · TypeArgument · TargetName · IsList · IsOptional · HasExplicitDefault · DefaultValueText · AllowsEmptyCell · IsSelfKey · IsIntId (nur der eigene Integer-Schlüssel dieses Tabs — die Referenz-Form IntId@Tab wird über TargetName + ReferenceScanner.GetReferencedTab gelesen, genau wie RecordId@Tab) · TypeToken InnerToken / IsWrapper (Wrapper-Typen — rekursiv innen) · IsCustomReference (diese Spalte ist MyType@Tab, wobei der Parser IReferencingCellType implementiert; ReferenceScanner.GetReferencedTab ist das einzige Prädikat, das dies liest, wodurch jeder Konsument ohne Signaturänderung mit aufleuchtete) · AssetTypeName (der geschriebene <Type> von AssetRef@Group<Type>, null wenn uneingeschränkt; der Core speichert nur den Namen — dessen Auflösung ist Aufgabe von IAssetTypeResolver —, und er wird auch auf das AssetRef-Token innerhalb einer Liste oder eines Wrappers gestempelt). Die drei nachgestellten Konstruktorparameter (innerToken, isCustomReference, assetTypeName) sind mit Standardwerten versehen, sodass bestehende Aufrufe kompilieren, und die früheren Konstruktoren mit 8 und 10 Argumenten bleiben als Überladungen erhalten, sodass bereits kompilierte Plugin-Assemblies auch ohne Neukompilierung weiterhin funktionieren
CellValue (struct)Ein typisierter Zellwert; keine Nulls (IsDefaulted markiert materialisierte Standardwerte). object Value · IsDefaulted · AsList · static Of / Defaulted
RecordId (struct)Ein Schlüsselwert (ordinale Gleichheit). string Value · IsEmpty
RecordRefValue (struct)Der Wert einer RecordId@Tab-Zelle. TargetTab · Id
IntRefValue (struct)Der Wert einer IntId@Tab-Zelle — das Integer-Schlüssel-Zwilling von RecordRefValue. string TargetTab · int Id · bool IsEmpty · static Empty(tab) (ein optionales IntId@Tab?, das auf nichts zeigt)
LocRefValue (struct)Der Wert einer LocRef@Tab-Zelle — das Lokalisierungs-Zwilling von RecordRefValue, bewusst als eigener Typ gehalten, damit ein Konsument allein am Wert erkennt, dass er auf eine String-Tabelle zeigt. string TargetTab · string Key · bool IsEmpty · static Empty(tab) · ReferencedKeys. Er implementiert IRefBearingValue, sodass der Referenz-Scanner ihn exakt wie eine Core-Referenz behandelt
AssetRefValue (struct)Der Wert einer AssetRef@Group-Zelle. Group · Key (ein Sub-Asset-Schlüssel ist parent[sub])
EnumValue (struct)Der Wert einer Enum<T>-Zelle (String-Paar — CLR-Konvertierung ist Aufgabe des Bake). EnumName · MemberName

Typisierte Asset-Referenzen (SheetForge.Core.Model)

Der <Type> in AssetRef@Group<Type> wird vom Host aufgelöst — der Core kennt weder die Engine noch die Assemblies des Projekts — und der Core beurteilt nur das Ergebnis. Alles hier ist reine Daten.

TypArtRolle & Schlüsselmember
IAssetTypeResolverinterfaceAssetTypeResolution Resolve(string rawName) — ein Name hinein, ein Urteil heraus; derselbe Name erhält immer dieselbe Antwort (Implementierungen dürfen zwischenspeichern). Wird separat von AssetKeyIndex in die ImportPipeline injiziert, sodass Typnamen selbst in einem Projekt aufgelöst werden, das noch keine Addressables-Einstellungen besitzt; ist kein Resolver injiziert (headless, Browser), werden die Typnamen-Diagnosen schlicht nicht erzeugt. Die Implementierung des Editors löst gegen die vom Projekt geladenen, von UnityEngine.Object abgeleiteten Asset-Typen auf (keine Allowlist; Components und reine Editor-Typen ausgeschlossen)
AssetTypeResolutionsealed classDas Urteil für einen Namen — RawName · AssetTypeResolutionStatus Status · FullName (vollständiger CLR-Name, verschachtelte Typen mit +; nur bei Resolved und NotReferenceable) · AssemblyName (die Assembly, die die generierte Begleitassembly referenzieren muss — gesetzt bei Typen mit Assembly-Definition, null bei Engine-Modulen und nicht aufgelösten Namen) · Candidates (nie null: die mehrdeutigen Kandidaten, oder Vorschläge für die nächstliegende Übereinstimmung bei einem unbekannten Namen). Fabriken Resolved(raw, fullName, assemblyName) · Unknown(raw, suggestions) · Ambiguous(raw, candidates) · NotReferenceable(raw, fullName, assemblyName)
AssetTypeResolutionStatusenumResolved · Unknown (kein solcher Typ) · Ambiguous (der Kurzname passt auf mehrere Typen — schreiben Sie den vollständigen Namen) · NotReferenceable (der Typ liegt in einer vordefinierten Assembly wie Assembly-CSharp, die generierter Code nicht referenzieren kann)

Codegen liest das aufgelöste Dictionary, das die Pipeline erzeugt, und gibt für einen aufgelösten Namen AssetReferenceT<global::FullName> aus; ein Name, den es in diesem Dictionary nicht findet, wird nie wortgetreu ausgegeben — das Feld fällt auf AssetReference zurück, und eine AssetTypeUnresolvedFallback-Warnung wird gesammelt. Der aufgelöste vollständige Name fließt außerdem in den Schema-Fingerabdruck ein.

Visuelle Werttypen (SheetForge.Core.Model)

Engine-freie Wertmodelle für die drei eingebauten visuellen Typen. Jeder ist unveränderlich, IEquatable, und besitzt seine eigene Textform (TryParse / Render) — dieselbe Notation, die die Seite Tabellensyntax dokumentiert —, sodass ein Plugin-Typ, der eine Farbe, eine Kurve oder einen Verlauf speichert, sie wiederverwenden kann, statt eine zweite Notation zu erfinden. Der Editor bakt sie in UnityEngine.Color / AnimationCurve / Gradient und liest sie zurück; der Browser sampelt sie über die Evaluatoren unten, statt die Mathematik neu zu implementieren.

TypArtRolle & Schlüsselmember
ColorValuereadonly structVier Bytes R · G · B · A · static Default (#00000000) · static TryParse(text, out value, out error) (akzeptiert #RGB / #RGBA / #RRGGBB / #RRGGBBAA) · Render() (Großbuchstaben, sechs Ziffern, wenn deckend)
CurveValuesealed classKeys (zeitlich aufsteigend) · PreWrap / PostWrap · static Empty (keine Schlüsselpunkte — der einzige Zustand ohne Textform; Render() liefert "") · static Create(keys, preWrap, postWrap)der einzige Konstruktionsweg: sortiert nach Zeit, lehnt doppelte Zeiten ab und wendet CurveTangentSolver an, sodass „der Modus gewinnt" ab dem Moment gilt, in dem eine Kurve existiert · static TryParse (Schlüsselpunkte mit 2/4/7/8 Feldern, Once als Alias von ClampForever akzeptiert, Tangenten Infinity/-Infinity) · Render() (Schlüsselpunkte mit 8 Feldern, Wrap-Suffix nur bei Bedarf)
CurveKeyreadonly structTime · Value · InTangent · OutTangent · InWeight · OutWeight · CurveWeightedMode WeightedMode · CurveTangentMode LeftMode / RightMode · bool Broken; ein Zehn-Argument-Konstruktor ohne eigene Normalisierung
CurveWrapenumClampForever · Loop · PingPong · Default — Unitys Wrap-Vokabular nach Namen (die Zuordnung des Werts zu WrapMode obliegt dem Baker)
CurveTangentModeenumFree = 0 · Auto = 1 · Linear = 2 · Constant = 3 · ClampedAuto = 4 — in Name und Wert identisch mit AnimationUtility.TangentMode, sodass der Baker nach Namen zuordnet und Unitys gepackte Tangenten-Bits nie berührt
CurveWeightedMode[Flags] enumNone = 0 · In = 1 · Out = 2 · Both = 3 — welche Seite eines Schlüsselpunkts gewichtete (Bézier-)Tangenten verwendet
CurveTangentSolverstatic classCurveKey[] Apply(IReadOnlyList<CurveKey> sortedKeys) — leitet die Tangentenwerte ab, die ein Modus vorschreibt, wobei die Stufen in der Reihenfolge der Engine angewendet werden (Linear auf der eigenen Seite → ClampedAuto auf beiden Seiten → Auto auf beiden Seiten → Constant auf der eigenen Seite), und lässt Free-Seiten und Gewichte unangetastet. CurveValue.Create ruft es auf, sodass Aufrufer es selten selbst tun
CurveEvaluatorstatic classfloat Evaluate(CurveValue, float time) · float[] Sample(CurveValue, int count) (count ≥ 2, gleichmäßig verteilt vom ersten bis zum letzten Schlüsselpunkt) — Hermite zwischen Schlüsselpunkten, gewichtetes Bézier auf den Seiten, deren Gewichtungs-Flag gesetzt ist, ein Halten, wenn eine Tangente unendlich ist, und die vier Wrap-Verhalten außerhalb des Schlüsselpunkt-Bereichs; gegen AnimationCurve.Evaluate an zufälligen Kurven verifiziert
GradientValuesealed classColorKeys · AlphaKeys (je 1 bis 8, zeitlich aufsteigend) · GradientBlend Mode · GradientColorSpace ColorSpace · static Default (weiß, vollständig deckend, Blend) · static Create(colorKeys, alphaKeys, mode, colorSpace) (validiert Anzahl und 0…1-Bereiche, quantisiert Zeiten wie Unity auf 16 Bit, sortiert stabil) · static TryParse (drei oder vier durch `
GradientColorKeyreadonly structColorValue Color (Alpha ignoriert — Alpha hat eigene Schlüsselpunkte) · float Time
GradientAlphaKeyreadonly structfloat Alpha · float Time
GradientBlendenumBlend · Fixed · PerceptualBlend
GradientColorSpaceenumUninitialized (nicht geschrieben; wird als Gamma gelesen) · Gamma · Linear — beeinflusst nur PerceptualBlend
GradientEvaluatorstatic classColorValue Evaluate(GradientValue, float time) · ColorValue[] Sample(GradientValue, int count) — lineare, gestufte oder perzeptuelle (Oklab-)Überblendung, wobei die Alpha-Schlüsselpunkte separat überblendet und auf Bytes gerundet werden; gegen Gradient.Evaluate an zufälligen Verläufen verifiziert

Fehler und Ergebnisse (SheetForge.Core.Model / .Reporting)

TypRolle & Schlüsselmember
ImportErrorStrukturierter, gebietsschemaneutraler Fehler. Code · Severity · Coordinate · ActualValue · Expected · Suggestion
ImportErrorCode (enum, 105)Der vollständige „Warum"-Katalog — die Familien, die er abdeckt, stehen unterhalb der Tabelle. Nur anfügbar, weil Renderer-Tabellen über die Member-Werte schlüsseln
ImportSeverity (enum)Error (blockiert die Ausgabe) · Warning
CellCoordinate (struct)Tab · 1-basierte Zeile · 1-basierte Spalte · Feld; berechnet den Tabellen-Spaltenbuchstaben. Factory-Methoden ForTab / ForRow
ErrorCollectorSammelbecken für Alles-sammeln. All · HasErrors · ErrorCount · Add
ImportResultPipeline-Ausgabe. Invariante: Success == false ⇔ Registry == null. Success · Registry · Diagnostics · SkippedTabs · EnumTabs (als Enum-Definitionstabellen gelesene Tabs, daher nie als Datentabellen geparst — getrennt von SkippedTabs gehalten, das „noch keine Tabelle geschrieben" bedeutet, sodass die Übersprungen-Zahl des Berichts wahr bleibt; beide sind Erhaltungsmengen, die generierten Code, per Bake erzeugte Assets und Adressen für diese Tabs bewahren) · static Succeeded / Failed
ImportReport (.Reporting, Assembly SheetForge.Core.Tooling)Eingabe für Berichts-Renderer — Timestamp · SourceDescription · TabCount · RecordCount · Success · Diagnostics · ErrorCount · WarningCount · SkippedTabCount (wie viele von TabCount leere, übersprungene statt importierte Sheets waren — der Kopf druckt es, damit eine Tab-Anzahl nicht mit „alle importiert" verwechselt wird)
ImportReportText (.Reporting, Assembly SheetForge.Core.Tooling, static)Rendert einen Bericht in den eigenen menschenlesbaren String des Produkts, ohne etwas in die Konsole zu schreiben und ohne angehängten Sprunglink oder Maschinenkoordinatenzeile (die gehören zur eigenen Konvention der Konsole). string Render(ImportReport report, IReadOnlyDictionary<string,string> languageTable = null, string operationName = null) — lassen Sie die Tabelle für Englisch weg; der Operationsname wird, wenn weggelassen, aus derselben Tabelle gelesen, damit der Satz nie zwei Sprachen mischt. Aufrufer auf Editor-Seite wollen üblicherweise SheetForgeActions.RenderReportText(report), das die aktuelle Editor-Sprache einträgt (eine reine Assembly kann EditorPrefs nicht lesen)

ImportErrorCode — die Familien, die er abdeckt:

  • Markierungen, Schema, Typen, Zellen, Schlüssel/Referenzen und Asset-Schlüssel;
  • Quellen/Dateien, csv/xlsx, Codegen-Bezeichner, Addressables, Baseline/Export, Google/Auth/Push und Vorlagen;
  • Plugins — PluginRegistrationConflict, plus PluginIncompatible, wenn die Kompatibilitätsdeklaration einer Assembly außerhalb dessen liegt, was dieser Host liest;
  • IntId — DuplicateIntId, und für IntId@Tab-Referenzen UnresolvedIntId · TargetTabHasNoIntId;
  • @overlap und DomainRuleViolation;
  • Enum-Definitionstabellen — EnumSheetMarkerConflict · DuplicateEnumName · EnumSheetEmptyColumn · InvalidEnumIdentifier · InvalidEnumUnderlyingType · InvalidEnumMemberValue;
  • DropdownNotSupportedByFormat, eine Warnung statt eines Fehlers;
  • typisierte Asset-Referenzen — UnknownAssetType · AmbiguousAssetType · AssetTypeNotReferenceable (einmal pro Spalte, auf der @type-Zeile), AssetTypeMismatch pro Zelle, sowie die Codegen-Warnung AssetTypeUnresolvedFallback.

Indizes und Hilfsprogramme (SheetForge.Core.Validation / .Model / .Parsing / .Unparse)

TypRolle & Schlüsselmember
TabKeyIndexDie Schlüssel-Information eines Tabs — die String-Schlüsselspalte plus die Integer-Schlüsselmenge (IntId) des Tabs, sodass sowohl RecordId@Tab- als auch IntId@Tab-Referenzen sich dagegen auflösen. TabName · KeyField · HasKeyColumn · Keys · Contains(id)
KeyIndexBuilder (static)Baut Schlüsselindizes (die String-Schlüssel und die Integer-Schlüsselmenge von IntId, in einem Durchgang), meldet Schlüsselfehler, validiert IntId-Spalten. Build(SheetTable, ErrorCollector) · ValidateIntIdColumns
AssetKeyIndexGruppe → gültige Schlüsselmenge (Editor befüllt aus dem Addressables-Katalog, Sub-Asset-Schlüssel eingeschlossen; null-Injektion = Asset-Validierung überspringen). Register(group, keys) · HasGroup · HasKey · KeysOf · GroupNames, plus die Typ-Schicht, die AssetRef@Group<Type> verwendet: RegisterTyped(group, key, satisfiedTypeFullNames) (der Schlüssel und die Hülle der vollständigen Typnamen, als die er geladen werden kann — sein eigener Typ, Basistypen, Interfaces, die Typen seiner Sub-Assets; erneutes Registrieren vereinigt die Hülle) · HasTypeInfo(group, key) · SatisfiesType(group, key, typeFullName). Ein mit einfachem Register registrierter Schlüssel besitzt keine Hülle und ist von der Typprüfung ausgenommen, statt an ihr zu scheitern
LocalizationCoverage (static)Abdeckung pro Sprache und verwaiste Schlüssel für ein Lokalisierungs-Sheet. Eine reine Berechnung, die Listen zurückgibt statt Fehler zu sammeln, denn eine unübersetzte Zelle und ein unbenutzter Schlüssel sind normale Zustände und keine zu blockierenden Ausgänge. IReadOnlyList<LocaleCoverage> Compute(SheetTable) · IReadOnlyList<string> FindOrphanKeys(locTabName, tables) (Schlüssel, auf die nichts zeigt; bewusst konservativ — jede Referenzform, die der Scanner kennt, zählt als Verwendung, sodass eine lebende Übersetzung nie zur Waise erklärt wird)
LocaleCoverage (sealed class)Die Abdeckung einer Sprache. LocaleColumn Locale · int TotalKeys · int TranslatedKeys · IReadOnlyList<string> MissingKeys (Zeilenreihenfolge des Sheets, nie null) · bool IsComplete
TextSuggestion (static)Vorschläge für die nächstliegende Übereinstimmung (begrenzte Levenshtein-Distanz, deterministisch). FindNearest · Distance · DistanceWithin
BuiltinCellParsers (static)CreateDefaultRegistry() — die 12 eingebauten Parser (int, float, bool, string, Enum, RecordId, AssetRef, IntId, LocRef, Color, AnimationCurve, Gradient).
CanonicalValueRenderer (static)Wert → kanonischer Zellstring (Export/Push). TryRender(…) (delegiert ColorValue / CurveValue / GradientValue an deren eigenes Render(); eine Kurve ohne Schlüsselpunkte wird als leere Zelle gerendert) · RenderFloat(float) (kürzeste Round-Trip-Form)

Push-Plan (SheetForge.Core.Unparse)

Öffentlich, weil IPushApprover.Approve(PushPlan) sie offenlegt; reine Daten.

TypRolle
PushPlan (Assembly SheetForge.Core.Tooling, ebenso die drei Zeilen darunter)Der gesamte Sendeplan. Tabs · HasWork
PushTabPlanEin Tab: Writes · Appends · Deletes (Schlüssel + Zeilennummer; DeleteNotices bleibt die reine Schlüsselansicht)
PlannedCellWriteEin Zellschreibvorgang — Koordinaten, Baseline-Zelle, neuer Wert/Text, String-Familie-Flag
PlannedRowAppendEine angehängte Zeile — vollständige Zelltexte + String-Familie-Spalten

Editor-Assembly (SheetForge.Editor)

Settings, Lokalisierung, Komposition (SheetForge.Editor.Pipeline / .Localization)

TypRolle & Schlüsselmember
SheetForgeSettings (SO)Das Settings-Asset. Felder: sourceProviderId (alleinige Source-Auswahlachse; leer = eingebauter LocalFile) · localFolderPath · bakeOutputFolder · generatedCodeFolder · generatedNamespace · exportFolderPath · exportFormat · spreadsheetId · googleAccessMode · serviceAccountKeyPath · gidMap (Liste von GidMapEntry { tabName, gid }). Aufgelöste Effective*-Eigenschaften.
Loc (static)Einstiegspunkt der Lokalisierung. Tr(key) · TrContent(…) · Table · MenuRoot-Konstante. Tr löst in vier Schritten auf: per Plugin registrierter String (aktuelle Sprache, dann Englisch — das Overlay besitzt diesen Fallback, siehe StringOverlayRegistry) → eingebaute Tabelle (aktuelle Sprache, dann Englisch) → der Schlüssel selbst. Es gibt genau einen Registrierungskanal für Plugin-Strings, daher wird „welche Registrierung gewinnt" nie zur Frage
PluginRegistry (static)Entdeckt Plugins über TypeCache und übergibt die Kandidaten dann an PluginComposition.Compose. Build · BuildValidators · BuildEdgeContributors · BuildStructuralMarkers · BuildTemplates · BuildGraphShapes · BuildCodeRegistries · BuildThemes · BuildAll (Bündel) · InvalidateCache() (verwirft den Cache mit Reload-Lebensdauer — dieselbe Konvention wie SourceProviderRegistry.InvalidateCache; verwirft außerdem den Cache des Kompatibilitäts-Gates, sodass eine geänderte Entdeckungsmenge neu beurteilt wird). Das Bündel und die Slot-Isolation stehen unterhalb der Tabelle
ImportEvents (static)Editor-seitiger Ereignisbus — ein öffentlicher Vertrag: externe Assets können sich abonnieren. event Action<ImportCompletedArgs> ImportCompleted · RaiseImportCompleted(ImportCompletedArgs) feuern nur, wenn ein Import vollständig bis zum Bake durchgelaufen ist, sodass ein Abonnent die per Bake erzeugten Assets lesen darf. event Action<BaselineUpdatedArgs> BaselineUpdated · RaiseBaselineUpdated(BaselineUpdatedArgs) feuern, wann immer ein Tabellen-Snapshot gespeichert wurde — einschließlich eines Laufs, dessen Validierung fehlschlug —, was einer Authoring-Oberfläche erlaubt, sich bei einem unter Quarantäne stehenden Import zu aktualisieren. Zwei Achsen, bewusst nicht zusammengelegt: Die eine bedeutet „die Tabellen haben sich bewegt", die andere „die Assets haben sich bewegt"
BaselineUpdatedArgs (sealed)Baseline-Speicher-Payload. IReadOnlyList<string> Tabs (die in den Snapshot geschriebenen Tabs) · bool Quarantined (ob der gerade gespeicherte Snapshot die Validierung nicht bestanden hat)
SheetForgeActions (static)Die Ausführungs-Fassade — derselbe Ablauf, den ein Menüklick auslöst, aufrufbar aus einem CI-Skript, einem Build-Hook oder Ihrer eigenen Schaltfläche. RunImport() · RunExport() · RunPush() · RunHealthCheck() · RunLocalizationSync() (jede delegiert; Settings-Auflösung, die Addressables-Sperre, gegenseitiger Ausschluss, Bestätigungsdialoge, die Fortschrittsanzeige und die Codegen→Kompilierung→Bake-Fortsetzung bleiben alle im Produkt) · bool IsBusy · bool TryBeginExclusiveScope(out IDisposable scope) (false + scope = null, wenn bereits etwas läuft; der Scope ist das, was freigibt, und ein zweites Dispose kann nicht den Lauf eines anderen freigeben) · string RenderReportText(ImportReport) (die eigenen Sätze des Produkts in der aktuellen Editor-Sprache, ohne Konsolen-Schreibvorgang). Die Abschluss-Semantik steht unterhalb der Tabelle
SheetForgeEditorInfo (static, Namespace SheetForge.Editor)Anker der Editor-Assembly — const Version, das Gegenstück zu SheetForgeRuntimeInfo für Feature-Gating gegen die editor-seitige Oberfläche
ImportCompletedArgs (sealed)Abschluss-Payload, die an Abonnenten übergeben wird. IReadOnlyList<string> Tabs (durch diesen Abschluss gebakte Tabs) · string BakeFolder (Database-SO-Ordner). Args-Objekt-Muster — künftige Felder brechen die Ereignis-Signatur nicht.
GoogleSheetAccessMode (enum)SheetsApi (mit Auth, beschreibbar) · ExportUrl (ohne Auth, schreibgeschützt)
ExportFormat (enum)Tsv · Csv · Xlsx · Json · MatchSource

PluginRegistry — das Bündel und die Slot-Isolation. Das verschachtelte PluginBundle legt das zusammengestellte PluginSet Set offen — die zwölf-Slot-Einheitswahrheit, wodurch ein neu gewachsener Slot gelesen werden kann, ohne das Bündel zu erweitern —, plus neun bequeme Fenster darauf: Enums · Parsers · Validators · EdgeContributors · Markers · Templates · GraphShapes · CodeRegistries · Themes. Die früheren Sechs- und Acht-Argument-Konstruktoren bleiben als Overloads erhalten, die die späteren Registries auf leer setzen, und verhalten sich identisch wie die Versionen vor diesen Verträgen.

Isolation gehört Core, nicht diesem Typ: Ein Plugin, das beim Registrieren wirft, wird namentlich gemeldet und übersprungen, und jeder andere Slot und jedes andere Plugin registriert sich weiterhin.

SheetForgeActions — Abschluss-Semantik. RunImport/RunPush sind Fire-and-Forget. Ihre Bodies sind async void, weil der Editor-Hauptthread bei Netzwerk-IO nicht blockieren kann, daher ist die Rückkehr keine Fertigstellung — abonnieren Sie dafür ImportEvents.ImportCompleted. RunExport/RunHealthCheck/RunLocalizationSync schließen synchron ab — RunLocalizationSync durchläuft den Weg Sheet → StringTable, den auch ein Import-Abschluss durchläuft, und ohne das Unity-Localization-Paket zeigt es den Installationshinweis und ändert nichts.

Source-Provider-Nahtstelle (SheetForge.Editor.Sources)

TypRolle & Schlüsselmember
ISheetSourceProviderDer Provider-Vertrag. Id · DisplayNameKey · CreateTabSource(settings) · GetVisibility(settings) · CanAuthor(settings) · CreateReflectTarget(dispatcher, settings)
ISourceReflectTargetRückschreib-Ziel. void Reflect()
SourceVisibilityWelche Settings-Felder angezeigt werden — 5 bool-Flags
SourceProviderRegistry (static)Entdeckung/Auflösung. All · ResolveActive(SheetForgeSettings) sowie ResolveActive(string providerId) (löst direkt aus einer Id auf, ohne ein Settings-Asset zur Hand zu haben) · TryGet · InvalidateCache
ITabSourceFetch-Abstraktion. Description · Task<TabSourceResult> FetchAsync()
TabSourceResultTabs (Name → roher TSV) + Diagnosen + Format pro Tab; Teilausgabe erlaubt. static Create
TabSourceFormat (enum)Tsv · Csv · Xlsx · GoogleSheet

Data-Studio-Erweiterungspunkte (SheetForge.Editor.Studio)

Editor-seitig, weil sie UIElements zurückgeben oder Fensterzustand berühren — dieselbe gerechtfertigte Asymmetrie wie bei ISheetSourceProvider. Alle vier Verträge werden per TypeCache entdeckt (parameterloser Konstruktor; kein Registrierungsaufruf), und alle werden innerhalb von try/catch aufgerufen. Das Fenster selbst (DataStudioWindow) ist internal.

Alles, was sich als Daten ausdrücken lässt, gehört stattdessen in das Core-Vokabular ISheetForgeStudioPlugin, das auch im Browser rendert. Dies sind die deckenlosen Ausweichmöglichkeiten für das, was Beschreibung nicht sagen kann.

Die letzten vier Einträge sind keine Verträge, sondern Werkzeuge, die ein eingebundenes Widget nutzen kann:

  • die eigenen schreibgeschützten Skin-Werte des Fensters, damit es aussieht, als gehöre es dazu;
  • das Schlüssel-Dropdown, damit ein Cell-Widget Schlüssel auf dieselbe Weise wählt wie die eingebaute Zelle;
  • und das Zurücksetzen des Entdeckungs-Caches, damit Ihre eigenen Tests eine Sonde neu entdecken können.
TypArtRolle & Schlüsselmember
IStudioGraphWidgetinterfaceEin Domänen-Streifen über der Graph-Canvas (Core liefert keinen aus). bool AppliesTo(StudioGraphContext) · VisualElement Create(StudioGraphContext) (bei jedem Graph-Rebuild neu erzeugt — keinen Zustand halten; null fügt nichts hinzu)
StudioGraphContextsealed classSchreibgeschützt: Tab und FocusRecordId (der Terminus) · SheetRecord FocusRecord (null, wenn unaufgelöst) · Tables · ReferenceIndex References · CodeRegistries. Zwei ausrangierte Achsen bleiben aus Signaturkompatibilität erhalten und sind mit [Obsolete] markiert: ShapeId (immer "record") und ModeId (immer leer). Der Vergleich mit einer der beiden kompiliert und ist nie wahr, sodass der Compiler dies jetzt sagt, statt einen toten Zweig zu hinterlassen — löschen Sie die Prüfung. Keine Staging-Oberfläche — Widgets zeigen nur an (Konstruktor internal: das Fenster stellt es zusammen)
IStudioCellEditorProviderinterfaceZeichnet eine Grid-Zelle für einen benannten Typ. string TypeName (entspricht einem Typ- oder Wrapper-Namen der CellParserRegistry, ordinal; leer = Opt-out) · VisualElement CreateEditor(StudioCellEditorContext) — die Rückgabe von null lehnt diese Zelle ab, und das eingebaute Widget übernimmt. Ein doppelter Anspruch auf denselben Typnamen warnt und behält den zuerst gefundenen
StudioCellEditorContextsealed classWas das Cell-Widget erhält: Tab · FieldName · TypeToken Type · CurrentRawText (kanonischer Text mit angewendetem Staging) · Action<string> Commit (eine einmalige Aktion — ihr eigener Undo-Schritt) · Action<string> CommitTyping (ein Tastenanschlag-Schwall — koalesziert pro Zelle) · Func<string,IReadOnlyList<string>> ReferenceKeys (dieselben Kandidaten-Schlüssel, die der eingebaute Picker anbietet). Beide Commits durchlaufen die Staging-Sperre des Fensters (Konstruktor internal: das Fenster stellt es zusammen)
IStudioInspectorActioninterfaceEine zusätzliche Schaltfläche im Node-Inspector. string LabelKey (Loc-Schlüssel; nicht registriert = wortgetreu angezeigt, leer = Typname) · bool AppliesTo(StudioInspectorContext) · void Execute(StudioInspectorContext)
StudioInspectorContextsealed classLesen: Tab · RecordId · SheetRecord Record · Tables · References · CodeRegistries. Vermittelte Mutation: Action<string,string,string,string> StageCell · Action<IReadOnlyList<EdgeCellWrite>> StageCells, beide unterhalb der Tabelle im Detail beschrieben. Dienste: Action<string,int,string> FocusCell · Action RequestRebuild. Die AuthoringSession wird bewusst nicht offengelegt
IStudioPanelProviderinterfaceEin beliebiges UIToolkit-Panel im rechten Bereich des Studios — die Ausweichmöglichkeit neben dem beschreibenden StudioPanelDescriptor. string Id · string TitleKey · bool AppliesTo(StudioSurfaceContext) · VisualElement CreatePanel(StudioSurfaceContext) (null zeichnet diesen Tick nichts). Registrieren Sie ein beschreibendes Panel unter derselben Id, und jeder Host nimmt, was er zeichnen kann: Der Editor bevorzugt dieses, der Browser zeichnet das beschreibende — sodass „so weit der Browser reicht, im Editor die ganze Strecke" keinen zweiten Vertrag braucht. Das Element lebt einen Neuberechnungs-Tick lang, hält also keinen Zustand
StudioPalettestatic classSchreibgeschützte Farb-, Abstands- und Typwerte, mit denen das Fenster selbst zeichnet, damit ein von Ihnen eingebundenes Widget zum Fenster passt, statt Hex-Werte fest zu codieren. Jeder Slot löst zur Lesezeit auf, sodass Widgets Helligkeitsmodus und Farb-Preset kostenlos mitmachen. Die Wahl der Werte (Presets, Helligkeit, Vorgaben) bleibt internal — Widgets folgen der Palette, sie malen sie nicht neu. Die Member-Liste steht unterhalb der Tabelle
StudioThemestatic classNur vier Member: CategoryColor(category) (derselbe deterministische Farbton, den das Fenster dieser Kategorie gibt) · Np(text) (sichere Interpolation in ein Rich-Text-Label) · Mono / ApplyMono(element) (die Mono-Font-Richtlinie: nur Schlüssel, Adressen und Zahlen — Mono-Fonts haben keine CJK-Glyphen). Alles andere an diesem Typ ist internal
StudioKeyPickerstatic classEin Member: Show(Rect screenAnchor, string targetTab, IReadOnlyList<string> candidates, Action<string> picked, string acceptsLabel = null) — dasselbe Dropdown, das die eingebaute Referenzzelle öffnet, für ein Cell-Widget, das einen Schlüssel innerhalb seiner eigenen Notation erreichen muss. Es wählt einen Schlüssel aus den von Ihnen gelieferten Kandidaten und gibt ihn zurück; das Erstellen eines Datensatzes, das Leerlassen der Zelle, das Mehrfach-Umschalten einer Liste und die Frage, welcher Port die Auswahl erhält, sind die eigenen Regeln der eingebauten Referenzzelle, daher stehen sie nicht auf dieser Fassade. picked ist erforderlich (ArgumentNullException, bevor irgendein Fenster erzeugt wird); ohne Kandidaten und ohne etwas anzubieten, loggt es, statt eine leere Liste zu öffnen. Der Fenstertyp selbst bleibt internal
StudioPluginRegistrystatic classEin öffentliches Member: InvalidateCache() — verwirft den Entdeckungs-Cache pro Reload, damit eine Sonde, die Ihre eigenen Tests gerade aktiviert haben, erneut gefunden wird (dieselbe Höflichkeit, die PluginRegistry und SourceProviderRegistry bereits boten; diese war die Ausnahme-Registry). Die entdeckten Listen bleiben internal: Nichts von außen kann lesen oder ersetzen, was das Fenster einbinden wird

StudioInspectorContext — die zwei Staging-Delegates:

  • StageCell nimmt Tab, RecordId, Feld und kanonischen Rohtext entgegen. Das Fenster registriert den Undo-Schritt, erhöht die Projektionsgeneration und merkt die logische Adresse vor.
  • StageCells macht dasselbe für mehrere Zellen, die gemeinsam geändert werden müssen: ein nativer Undo-Schritt, alles-oder-nichts. Kann auch nur eine nicht vorgemerkt werden, bleibt die Session vollständig unangetastet.

Ein Fehlschlag bleibt auf dem Bildschirm so oder so still, wobei nur das Gate sich selbst erklärt. Eine schreibgeschützte Quelle, eine bereits laufende Pipeline oder ein Arbeitsmappen-gestützter Tab schreiben ihren Grund in die Konsole. Eine leere Liste, ein Schreibvorgang ohne Tab oder Feld und ein Datensatz-Schlüssel, der zu keiner Zeile aufgelöst wird, tun nichts und sagen nichts.

StudioPalette — die Member:

  • 33 Farb-Slots: Canvas · Panel · Band · Chrome · Surface · Chip · Selection · PendingCell · Line · LineSoft · GridLine · LineHover · Text · TextMuted · TextFaint · RefText · OnAccent · Accent · AccentDim · Warning · Danger · Ok · SheetTone · CodeTone · EditedCell · NewRowCell · NewRowLine · DangerChip · DangerPanel · Scrim · Wire · WireDot · GridDot.
  • IsDark.
  • Abstände: SectionSpace · RowSpace · RuleHeight · ButtonHeight · PrimaryButtonHeight · GlyphWidth.
  • Schriftgrößen: HeadingFontSize · SectionFontSize · CaptionFontSize.
  • FromRgb(uint) · ToHex(uint).

Push-Bestätigung (SheetForge.Editor.Push)

TypRolle
IPushApproverbool Approve(PushPlan, string humanSummary) · bool ApproveStructureRewrite(string, bool hasLiveConflicts) — Ablehnen = nichts wird gesendet
AutoPushApproverBestätigt immer automatisch (für Tests/Automatisierung)

Authoring-Engine (SheetForge.Editor.Structure / .Pipeline / .Export)

TypRolle & Schlüsselmember
AuthoringSessionBesitzer des Staging-Zustands (serialisierbar — Undo und Reload-Überleben gratis dazu). Edits · IsolatedEdits · NewRows · StructOps · Reorders · TabRenames · EnumMembers (vorgemerkte Enum-Sheet-Member-Ergänzungen) · AssetRegistrations (vorgemerkte Addressables-Registrierungen — auf Projektebene, daher nehmen sie nicht an den Pro-Tab-Gates teil, zählen aber für den Übernehmen-Einstieg, das Verwerfen und die Diff-Zusammenfassung) · HasAssetRegistrations · StageAssetRegistration(r) (dieselbe Guid, oder dieselbe Gruppe bei einer Gruppenerstellung, ersetzt an Ort und Stelle — die letzte Absicht gewinnt; eine Registrierung ohne Identität wird abgelehnt) · RemoveAssetRegistrationsWhere(predicate) · SetStaged · ResolveBaselineEdits · RemapFieldName/RecordId/Tab · StageTabRename · EffectiveStructOps · PendingStructCount · TabNames · TryGetBaselineTable · LastProjectionResult · ClearAll (leert auch die Registrierungen)
AuthoringDispatcherDer Übernehmen-Orchestrator. Konstruktor (session, callbacks, baselines) · Reflect() · BuildProjectionResult() (nebenwirkungsfreie Projektionsabfrage) · IReadOnlyDictionary<string,string> BuildProjectedTabs() (dieselbe Projektion als TSV pro Tab — was ein Rückschreibe-Ziel gleich senden wird, vorschaubar ohne zu schreiben) · void FinalizeReflectSuccess(IReadOnlyList<string> writtenTabs, IReadOnlyList<TabRenameEntry> committedRenames = null) (der Abschluss, den das eigene Rückschreiben einer Quelle erreichen muss: Retain-Bereinigung für die geschriebenen Tabs, die ClearUndo-Grenze und der automatische erneute Import — die eingebauten Pfade laufen durch denselben privaten Rumpf, sodass ein externer Provider genau so endet wie sie; eine leere Liste ist ein No-op, das das Staging intakt lässt) · Session · Callbacks · Baselines
AuthoringDispatchCallbacks13 allgemeine Delegates für Ansichts-Anliegen + IPushApproverResolveSettings · RenderReport (Action<ImportReport>, null-tolerant) · TriggerReimport · ConfirmKeyRenames · ConfirmTabRenames (null-tolerant) · ClearUndo · Rebuild · … Eingebaute Local-/Google-Dialog-Delegates leben im Opt-in-Bündel BuiltInSourceDialogs
BuiltInSourceDialogsOpt-in-Bündel von 14 eingebauten Local-/Google-Source-Dialog-Delegates, getrennt von AuthoringDispatchCallbacks — externe Provider benötigen sie nie. NotifyLocalDone nimmt fünf Argumente; das letzte ist die Addressables-Registrierungs-Zusammenfassungszeile für den Abschlussdialog (null, wenn nichts vorgemerkt war)
BaselineStore (.Export)Normalisierte TSV-Baseline-Schnappschüsse pro Tab

Staging-Werttypen (SheetForge.Editor.Structure; StagedCellEdit/StagedNewRow liegen in SheetForge.Editor.Windows)

TypRolle
StagedCellEdit (struct)Eine vorgemerkte Bearbeitung — TabName · RowOrdinal · FieldName · RawText · RecordId (logischer Schlüssel)
StagedNewRowEine vorgemerkte neue Zeile — TabName · FieldNames · CellTexts
StructureOpEine Strukturoperation — Kind · Koordinaten · Texte · Order-Permutation
StructureOpKind (enum)AddColumn · RemoveColumn · AddMarker · RemoveMarker · RemoveDataRow · ReorderColumns · ReorderDataRows · RenameColumn · EditColumnType · EditColumnDesc · SetColumnOverlap · SetSheetStyle
TabReorderEntryNeuanordnungs-Zustand pro Tab — Tab · ColOrder · RowOrder
TabRenameEntry (struct)OldName · NewName
StagedEnumMember (struct)Ein vorgemerktes „diesen Member zu diesem Enum hinzufügen" — TabName (welche Enum-Definitionstabelle; leer = alle durchsuchen) · EnumName · Member. Auf Session-Ebene statt als StructureOp, aus demselben Grund wie eine Tab-Umbenennung: Eine Enum-Definitionstabelle hat keine Datentabelle, kein Schema und keine Schlüsselspalte, daher kann die (Tab, Datensatz, Feld)-Adresse einer Zellbearbeitung nicht „den nächsten Member dieses Enums" benennen. Nur öffentlich, weil AuthoringSession.EnumMembers es ist (CS0050)
StagedAssetRegistration (struct)Eine vorgemerkte Änderung an den Addressables-Einstellungen des Projekts, entstanden durch das Ablegen oder Auswählen eines Assets in einer AssetRef@Group-Zelle — StagedAssetRegistrationKind Kind · Guid (das Asset; ein Sub-Asset merkt sein Elternteil vor) · Group · FromGroup (nur bei Verschiebungen) · Address (der Dateiname ohne Erweiterung für einen neuen Eintrag; ein bereits registriertes Asset behält seine Adresse) · AssetPath (zur Anzeige). Fabriken Add(guid, group, address, assetPath) · Move(guid, fromGroup, group, address, assetPath) · CreateGroup(group). Wird ausgeführt, nachdem das Schreiben der Tabelle erfolgreich war, und danach geleert. Nur öffentlich, weil AuthoringSession.AssetRegistrations es ist (CS0050), wie StagedEnumMember
StagedAssetRegistrationKind (enum)Add · Move · CreateGroup
TabBaselineAnchor (struct)TabName · Fingerprint · RecordCount
IsolatedEditEine Bearbeitung mit fehlgeschlagener Neuverankerung — Edit · Reason
IsolationReason (enum)Externe Umbenennung / externes Löschen / Schlüsselkonflikt

Authoring-Hilfsprogramme (SheetForge.Editor.Windows / .Structure)

TypRolle
KeyRenamePlanner (static)Planung von Schlüssel-Umbenennungen + tab-übergreifender Propagierung. Plan(…) · verschachteltes KeyRenamePlan · begleitendes Struct KeyRename
RecordIdMinter (static, pure)Id-Vorschläge. Suggest · DetectCommonPrefix · Uniquify · StagedNewRowKeys
IntIdMinter (static, pure)Vorschlag für den nächsten IntId-Wert für einen neuen Datensatz — Suggest(existingIds)max + 1. Eine von RecordIdMinter getrennte Achse, und sie verwendet nie eine gelöschte Lücke erneut
ProjectionErrorMapper (static, pure)Fehlerkoordinate → logische Adresse. TryMap(…) · verschachteltes LogicalAddress
EphemeralSoApply (static)SO-Overlay für vorgemerkte Werte (temporär). Apply(…) · InvalidateIndex(…) · verschachtelte Report / SkipReason / SkippedEdit

Runtime-Assembly (SheetForge.Runtime)

autoReferenced — aus Spielcode ohne asmdef-Referenz verwendbar.

TypRolle & Schlüsselmember
SheetForgeDatabases (static)Der Runtime-Loader — der offiziell vorgesehene Ladepfad. const AddressPrefix = "SheetForge/" · AddressFor(tab) · LoadAsync(tab) · LoadAsync<TDatabase>(tab) · Release(handle) / Release<TDatabase>(db). Die Adress-Helfer sind reine Strings und kompilieren immer; LoadAsync und Release existieren nur unter SHEETFORGE_ADDRESSABLES, dem Versions-Define, das gesetzt wird, wenn com.unity.addressables installiert ist — was es dem Produkt erlaubt, auch ohne das Paket zu kompilieren
DefinitionDatabase (abstract SO)Basis jeder generierten Database pro Tab. abstract TabName · abstract Count · virtual IReadOnlyList<object> RecordsUntyped · virtual InvalidateIndex(). RecordsUntyped ist der offiziell vorgesehene Weg, einen per Bake erzeugten Tab ohne Kenntnis seines generierten Typs aufzuzählen — ein zweiter Baker oder ein Inspector, der jeden Tab durchläuft, musste bisher über Reflection auf das private Feld records zugreifen, was einen Feldnamen zu einem unerklärten Vertrag machte, der am Tag still brach, an dem Codegen ihn umbenannte. Behandeln Sie die Liste als schreibgeschützt (die Tabelle ist kanonisch). Sie ist standardmäßig leer, sodass generierter Code von vor Existenz dieses Members weiterhin kompiliert und läuft; ein erneuter Import gibt den Override aus
RecordRef (struct)Der serialisierte Referenzwert innerhalb per Bake erzeugter SOs (String-Id, bei Lookup aufgelöst). Id · IsEmpty
IntRef (struct)Der serialisierte Integer-Schlüssel-Referenzwert innerhalb per Bake erzeugter SOs — das Zwilling von RecordRef für IntId@Tab-Felder. Weil 0 eine gültige Id ist, sichert ein hasValue-Bit IsEmpty ab. Id · IsEmpty. Codegen gibt ein IntId@Tab-Feld als IntRef aus, und TryGet(IntRef) auf der generierten Database konsumiert es
LocRef (struct)Die serialisierte Lokalisierungsreferenz innerhalb per Bake erzeugter SOs — eine LocRef@Tab-Zelle. Table (der Lokalisierungs-Tab, der zugleich der Name der StringTable-Collection ist) · Key · long KeyId (0 bedeutet „noch nicht aufgelöst": ein Import backt 0, und die Brücke trägt nach einer Tabellensynchronisierung die echte Id nach, sodass eine Referenz eine Schlüsselumbenennung überlebt) · IsEmpty. Sie kompiliert immer — generierter Code und per Bake erzeugte Assets enthalten nie einen Typ des Lokalisierungspakets, und genau das hält das Paket optional
LocRefExtensions (static)Ein einziges Member: LocalizedString ToLocalizedString(this LocRef) — es zeigt über KeyId, wenn diese nicht 0 ist, und sonst über den Schlüsselnamen, und eine leere Referenz konvertiert zu einem leeren LocalizedString. Es existiert nur, wenn com.unity.localization installiert ist, unter dem Versions-Define SHEETFORGE_LOCALIZATION — dieselbe Anordnung, die SHEETFORGE_ADDRESSABLES für die Addressables-Schicht verwendet
SheetForgeRuntimeInfo (static)const Version

Generierte Typen (Muster — pro Projekt, keine ausgelieferte API)

Für jeden Tab Foo erzeugt Codegen in Ihren generatedNamespace:

public sealed partial class FooDefinition    // one strongly-typed field per column; @desc → doc/tooltip
public sealed partial class FooDatabase : DefinitionDatabase
{
    // TabName, Count, SchemaFingerprint, Records, RecordsUntyped override,
    // lazy _byId/_byIntId lookups, InvalidateIndex override
}

Laden Sie mit SheetForgeDatabases.LoadAsync<FooDatabase>("Foo").

Beide Klassen werden partial erzeugt, sodass Sie abgeleitete Member — eine berechnete Eigenschaft, eine Interface-Implementierung, einen Operator — in Ihrer eigenen Datei neben der generierten hinzufügen können, und ein erneuter Import überschreibt sie nicht. Eine Grenze: Fügen Sie in Ihrem Teil keine serialisierten Felder hinzu. Das per Bake erzeugte ScriptableObject wird bei jedem Import aus der Tabelle neu aufgebaut, daher kommt alles, was nur Ihr Teil serialisiert, auf seinen Standardwert zurück — gehört ein Wert zu den Daten, gehört er in eine Spalte. (Das Schlüsselwort partial rührt SchemaFingerprint nicht an, das allein aus dem Schema berechnet wird, daher hat das Partial-Machen der Klassen keinen einzigen bestehenden Bake ungültig gemacht.)


Weitere Assemblies

  • SheetForge.Setup — der abhängigkeitsfreie Bootstrap für den Fall fehlender Addressables. Keine öffentliche API (alles internal; er existiert, um ein Hinweisfenster zu zeigen).

  • SheetForge.PluginDemo (eine zusammengeführte asmdef + eine Demo.Editor-asmdef; der Inhalts-Namespace bleibt SheetForge.Skills) — das Referenzbeispielpaket, keine Produkt-API. Es enthält:

    • SkillsPlugin (sieben Plugin-Interfaces — Basis, Validator, Edge, Vorlage, Graph, Code-Registry, Theme);
    • Modifier + ModifierCellParser (benutzerdefinierter Zelltyp), ModifierStatEdgeContributor (Kanten-Contributor);
    • ExamplePipelineAugmenter / ExampleReactiveAugmenter (Canvas-Overrides), ExampleCodeAtoms (die Code-Registry _Refs);
    • ExampleStudioUi (deklarative Aktionen, Panel, Spalten-Badge und Cell-Editor-Hint), ExampleImportObserver (Pipeline-Beobachter);
    • ExampleStageStripWidget / ExampleInspectorAction / ExampleStudioPanel (Data-Studio-Editor-Erweiterungspunkte, aus der öffentlichen Palette bemalt), ExampleLocStrings (registriert diese Labels in zwei Sprachen — in der Haupt-Assembly, sodass der Browser sie ebenfalls zeigt);
    • eine Assembly-Level-Deklaration SheetForgePluginCompat;
    • SkillRunner (konsumierende Runtime), generierte Example*-Typen im Standard-Namespace SheetForge.Generated (die Isolation erfolgt über das Präfix Example*, nicht über einen eigenen Namespace).

    Das pluginfreie Beispiel SheetForge.CoreDemo wird mit null asmdefs ausgeliefert (kompiliert in Assembly-CSharp).

Verwandte Seiten