Référence de l'API — la surface publique
Cette page liste tous les types publics des assemblies du produit. Tout ce qui n'est pas listé ici est internal par conception ; la surface publique est délibérément étroite.
- Core (
SheetForge.Core+SheetForge.Core.Tooling) : 137 types publics (Core : 131, Core.Tooling : 6). Core.Tooling est la moitié réservée à l'Editor qui héberge les services au moment de l'import comme le reporting et la planification du Push — rien de tout cela n'est livré dans les builds joueur. - Editor : 53 types publics de premier niveau plus leurs types imbriqués publics.
- Runtime : 7 types, plus les sorties générées.
C'est exactement la surface contre laquelle compilent les tests de simulation de consommateur (sans InternalsVisibleTo).
Contrat de détection (pas un type) : un asset séparé peut aussi détecter que SheetForge est installé à la compilation via le symbole de compilation
SHEETFORGEque l'assembly Editor s'auto-enregistre. C'est un define, pas un type public, donc il n'est pas listé dans les tableaux ci-dessous — voir Création de plugins ▸ Détecter SheetForge depuis un autre asset. (Distinct deSHEETFORGE_ADDRESSABLES, un define de version interne qui ne fait que marquer la présence du package Addressables.)
Conventions : les signatures sont abrégées (… = voir les docs XML source) ; « pur » signifie aucun UnityEngine / aucune E/S.
Assembly Core (SheetForge.Core) — C# pur
Aucun UnityEngine, aucune E/S, aucun réseau, aucune connaissance du domaine. Imposé par le compilateur : le Core ne référence rien.
Contrats d'enregistrement de plugin (SheetForge.Core.Plugins)
| Type | Genre | Rôle et membres clés |
|---|---|---|
ISheetForgePlugin | interface | Le contrat de base des plugins de domaine. string Name · RegisterEnums(EnumRegistry) · RegisterCellParsers(CellParserRegistry) |
ISheetForgeValidatorPlugin | interface | Module optionnel pour les règles de validation. RegisterValidators(DomainValidatorRegistry) |
ISheetForgeEdgePlugin | interface | Module optionnel pour les déclarations d'arête. RegisterEdgeContributors(EdgeContributorRegistry) |
ISheetForgeMarkerPlugin | interface | Module optionnel pour les marqueurs structurels personnalisés. RegisterStructuralMarkers(MarkerRegistry) |
ISheetForgeTemplatePlugin | interface | Module optionnel pour les modèles « Créer une feuille ». RegisterTemplates(TemplateRegistry) |
ISheetForgeGraphPlugin | interface | Module optionnel enregistrant les surcharges de canevas du Data Studio par onglet. RegisterGraphShapes(GraphShapeRegistry) |
ISheetForgeCodeRegistryPlugin | interface | Module optionnel pour les cibles de référence possédées par le code (onglets virtuels verrouillés). RegisterCodeRegistries(CodeRegistryCatalog) |
ISheetForgeThemePlugin | interface | Module optionnel pour les préréglages de couleur de fenêtre. RegisterThemes(ThemeRegistry) |
ISheetForgeStudioPlugin | interface | Module optionnel pour les surfaces de création déclaratives (actions, panneaux, badges de colonne, indices d'éditeur de cellule). RegisterStudioUi(StudioUiRegistry). Dans le Core plutôt que dans l'Editor, si bien qu'un seul enregistrement se dessine à la fois dans l'éditeur UIToolkit et dans le navigateur |
ISheetForgeStringsPlugin | interface | Module optionnel enregistrant les chaînes d'UI propres au pack, par langue. RegisterStrings(StringOverlayRegistry). Remplace la paire ISheetForgeLocPlugin / PluginLocRegistry côté Editor, retirée, qui ne pouvait atteindre que l'éditeur |
ISheetForgePipelinePlugin | interface | Module optionnel enregistrant des observateurs de pipeline. RegisterPipelineObservers(PipelineObserverRegistry) |
Composition et compatibilité (SheetForge.Core.Plugins)
La découverte est propre à chaque hôte — le TypeCache d'Unity dans l'éditeur, le scan d'assembly téléversé du navigateur sur le web. Tout ce qui suit (instanciation, ordonnancement, isolation et la barrière de compatibilité) est une seule fonction Core partagée, ce qui est ce qui empêche les deux hôtes de dériver emplacement par emplacement.
| Type | Genre | Rôle et membres clés |
|---|---|---|
PluginComposition | classe statique | Le chemin unique d'assembly. Une instance par type, castée vers chaque contrat qu'elle implémente. Les deux membres et la répartition des diagnostics sont sous le tableau |
PluginSet | classe scellée | Le résultat assemblé — douze emplacements : Enums · Parsers · Validators · EdgeContributors · Markers · Templates · GraphShapes · CodeRegistries · Themes · Strings · StudioUi · PipelineObservers. Un nouvel emplacement atteint les deux hôtes en étant ajouté ici |
SheetForgePluginCompatAttribute | attribut scellé (assembly) | [assembly: SheetForgePluginCompat(SheetForgePluginFormat.Current, MinHostVersion = "…", PluginVersion = "…")]. int FormatVersion · string MinHostVersion (comparaison numérique à points ; null/vide = aucune exigence) · string PluginVersion (affichage seulement, jamais comparé). Lu sans rien instancier, et jugé par assembly — un assembly refusé perd tous ses enregistrements plutôt que de charger à moitié. Absent = génération Minimum, aucune exigence d'hôte |
SheetForgePluginFormat | classe statique | Les constantes de génération : const int Current · const int Minimum. Ne bouge que si le format de plugin lui-même est remplacé — une croissance purement additive garde le nombre où il est |
PluginComposition — les deux membres :
IReadOnlyList<Type> ContractTypes— le filtre de découverte. Son ordre est fixe, car il décide l'ordre dans lequel les diagnostics apparaissent.PluginSet Compose(IReadOnlyList<Type> candidateTypes, string hostVersion, ErrorCollector errors, ICollection<string> failures, Func<string,bool> isProductKey = null)— l'appel d'assemblage lui-même.
Deux sortes de problèmes sont tenues à part. Les conflits d'enregistrement et les refus de compatibilité deviennent des diagnostics structurés dans errors ; les bugs d'implémentation — échec de construction, callback qui lève une exception — deviennent des lignes en anglais dans failures, et passer null là-bas les ignore.
Le prédicat final isProductKey est ce qui impose la règle « un plugin ne peut pas écraser une clé produit » de la surcouche de chaînes sans que le Core ne voie jamais les tables de langue : la règle vit ici, l'hôte ne fournit que la matière. Omettez le prédicat et seule cette règle est ignorée.
Registres (SheetForge.Core.Model / .Validation / .Edges)
| Type | Rôle et membres clés |
|---|---|
EnumRegistry | Nom d'enum → type CLR (matière pour le codegen). Register<TEnum>() · Register(name, memberNames) · TryGetMembers · TryGetClrTypeName · TryGetClrAssemblyName · RegisteredEnumNames. Trois autres membres sont détaillés sous le tableau |
CellParserRegistry | Nom de type → parseur de cellule (ouvert-fermé). Un enregistrement en double lève une exception. Register(ICellValueParser) · TryGet · TryGetCustomRenderer · RegisteredTypeNames · RegisterWrapper(ICellWrapperType) · TryGetWrapper · RegisteredWrapperNames (types wrapper) |
DomainValidatorRegistry | Liste de validateurs en ajout seul, ordre préservé. Register(IDomainValidator) · Validators |
EdgeContributorRegistry | Liste de contributeurs en ajout seul, ordre préservé. Register(IEdgeContributor) · Contributors |
MarkerRegistry | Nom de marqueur (sans @) → marqueur structurel personnalisé. Une collision avec un marqueur intégré (SheetSyntax.ReservedMarkers — @name/@type/@desc/@overlap/@style/@enum/@loc) / un doublon / un identifiant invalide lève une exception. Register(IStructuralMarkerDefinition) · TryGet · IsEmpty · RegisteredMarkerNames · AppendMarkerTokens |
TemplateRegistry | Clé de modèle « Créer une feuille » → modèle. Une clé vide/en double, un nom d'affichage vide, zéro onglet, ou un TSV d'onglet vide lève une exception. Register(DataTemplate) · TryGet · Templates · IsEmpty |
EnumRegistry — les trois membres en détail :
EnumRegistry(EnumRegistry parent)— un enfant qui lit à travers un parent et n'enregistre que sur lui-même. Le parent porte les enums CLR enregistrés par plugin pour tout le rechargement de domaine, l'enfant ceux définis par feuille pour cet import, si bien qu'un import ne modifie jamais le cache partagé. Enregistrer un nom que le parent possède déjà lève une exception plutôt que de le masquer.Contains(name)— soi-même puis le parent, Ordinal.SetClrTypeName(name, fullTypeName)— renseigne un nom CLR après un enregistrement à base de chaîne seule. Le nom d'assembly reste vide car le type n'existe pas encore.
Modèles « Créer une feuille » (SheetForge.Core.Model)
| Type | Rôle et membres clés |
|---|---|
DataTemplate | Un modèle enregistré par un plugin : string Key (identité dans le registre) · string DisplayName (texte détenu par le plugin) · IReadOnlyList<DataTemplateTab> Tabs (un ou plusieurs) |
DataTemplateTab | Un onglet d'un modèle : string TabName · string Tsv (un TSV normalisé complet — lignes de marqueur plus données d'exemple) |
Types de cellule personnalisés (SheetForge.Core.Model)
| Type | Rôle et membres clés |
|---|---|
ICellValueParser | Analyse une cellule scalaire. Échec = collecter dans context.Errors + renvoyer false (ne jamais lever d'exception). string TypeName · bool TryParse(CellParseContext, string, out object) |
ICustomCellType | Assistant optionnel pour le codegen/l'aller-retour. Type ValueType · bool TryRender(object, out string text, out string reason) |
IReferencingCellType | Capacité optionnelle qu'un ICellValueParser enregistré peut aussi implémenter afin qu'une clé enfouie dans sa propre notation reçoive le traitement complet de RecordId@Tab — intégrité + suggestions, propagation de renommage de clé avec la charge utile préservée, arêtes et ports de graphe, le sélecteur ▾, détection d'orphelins, règles de liste déroulante exportée. Trouvée en castant le parseur enregistré (pas d'enregistrement séparé). bool TryGetTokenKey(elementText, out key) · string MakeToken(key) · bool TryRetargetToken(elementText, newKey, out newText) · bool TryRemoveToken(elementText, key, out newText) (résultat vide = l'élément disparaît) · bool TryRewriteKeys(elementText, IReadOnlyDictionary<string,string> renames, out newText). Un appel = un élément : la cellule entière, ou un élément séparé par ;. Donc une charge utile ne peut pas contenir ;. @target doit nommer un véritable onglet de feuille (UnknownTargetTab sinon). Ne lève jamais d'exception — false/null signifie « ne peut pas interpréter », et les réécritures préservent le reste |
IRefBearingValue | La moitié côté valeur de ce qui précède, implémentée par la valeur analysée : IEnumerable<string> ReferencedKeys (l'ordre de déclaration = l'ordre du diagnostic et du budget de suggestion ; les entrées null/vides sont ignorées). Le scanner lit ceci ; les hooks texte ci-dessus réécrivent la cellule. Les deux sont nécessaires — une valeur analysée ne peut pas restaurer la notation de l'auteur, et le texte ne peut pas être validé sans être lu |
ICellWrapperType | Une forme de valeur wrapper générique MyWrapper<T> (par ex. Pair<int> = 1~2) — le wrapper possède la syntaxe externe et le Core analyse le type interne de façon récursive. 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) |
WrapperValue | L'IR analysé d'une cellule wrapper — porte la stratégie du wrapper + expose les CellValue internes (afin que les références internes passent par la validation, le renommage de clé/onglet, et l'Export). ICellWrapperType Wrapper · IReadOnlyList<CellValue> Inner |
IStructuralMarkerDefinition | Une ligne @marker personnalisée (valeurs par colonne, validées colonne par colonne — généralise @overlap). string MarkerName (sans @) · string Description · void ValidateCell(MarkerCellContext) |
MarkerCellContext | Un appel de validation de cellule de marqueur. string MarkerName · string RawText · string FieldName · CellCoordinate Coordinate · void Reject(string reason, string suggestion = null) (→ MarkerCellInvalid) |
CellParseContext | Le contexte d'un appel de parsing. TypeToken Type · CellCoordinate Coordinate · ErrorCollector Errors · EnumRegistry Enums |
Constantes de la grammaire de feuille (SheetForge.Core.Model)
Un pack qui lit ou écrit du texte de cellule fonctionne avec la même grammaire que l'import — découper une cellule de liste, composer une chaîne @type, vérifier si un nom est déjà pris.
Ces constantes sont la source unique de vérité de cette grammaire, si bien qu'un pack ne redéclare jamais son propre séparateur : un caractère recopié dérive le jour où la grammaire change. Les listes sont fournies en lecture seule, si bien que rien de ce qu'un pack fait ne peut changer la grammaire elle-même. La notation qu'elles expriment est intégralement documentée sur la page Syntaxe des feuilles — ceci en est la prise programmatique.
| Type | Genre | Rôle |
|---|---|---|
SheetSyntax | classe statique | La grammaire de la feuille sous forme de constantes, regroupées ci-dessous |
Marqueurs
CommentPrefix(#) ·MarkerPrefix(@).- Une constante par ligne de marqueur intégré :
NameMarker·TypeMarker·DescMarker·OverlapMarker·StyleMarker·EnumMarker·LocMarker. RequiredMarkers— les trois que toute feuille doit porter.ReservedMarkers— chaque nom intégré. Consultez-le avant de nommer un marqueur personnalisé : une collision est refusée à l'enregistrement.
Séparateurs
ListSeparator(;) — entre les éléments d'une liste.EntrySeparator(,),FieldSeparator(:),SectionSeparator(|),KeyTimeSeparator(@) — les couches à l'intérieur d'une seule valeur, raison pour laquelle;n'apparaît jamais dans le texte propre d'une valeur.StyleKeyValueSeparator(=) — à l'intérieur d'une cellule@style.
Notation @type
OptionalSuffix(?) ·DefaultSeparator(=) ·TargetSeparator(@, comme dansRecordId@Tab).ListTypeName·ListOpen(List<) ·ListClose(>).
Noms de type
- Une constante par nom intégré :
IntTypeName·FloatTypeName·BoolTypeName·StringTypeName·RecordIdTypeName·IntIdTypeName·AssetRefTypeName·LocRefTypeName·ColorTypeName·AnimationCurveTypeName·GradientTypeName·EnumTypeName. BuiltinScalarTypesetIsBuiltinScalarTypeName(name)— répondent à « ce nom est-il déjà un type intégré ? » avant qu'un parseur soit enregistré sous ce nom.StyleKeyNames(title,color) ·LocReservedColumns(smart,comment).
Valeurs
TrueCanonical/FalseCanonical— le texte canonique debool.NumberCellStyles— leNumberStylesavec lequel chaque cellule numérique est lue. Les séparateurs de milliers sont exclus et la culture est toujours invariante, si bien qu'une virgule décimale locale échoue bruyamment au lieu de changer silencieusement un nombre.
Validation de domaine (SheetForge.Core.Validation)
| Type | Rôle et membres clés |
|---|---|
IDomainValidator | Règle inter-colonnes/inter-onglets. Les violations → ctx.Errors sous forme de DomainRuleViolation avec les 4 éléments. string Name · Validate(DomainValidationContext) |
DomainValidationContext | Tables (onglet → SheetTable) · KeyIndices · AssetKeys (null = ignoré) · Errors |
Couture des arêtes (SheetForge.Core.Validation / .Edges)
| Type | Rôle et membres clés |
|---|---|
ReferenceScanner (statique) | Source unique de vérité pour l'énumération des occurrences de référence. Scan(tables) · ScanTable · ScanField · IsReferenceField(TypeToken), plus les deux prédicats de référence détaillés sous le tableau |
RefKeyKind (enum) | Si une référence correspond à l'espace de clé chaîne (RecordId) ou entier (IntId). Renvoyé par ReferenceScanner.GetReferenceKind ; les consommateurs branchent dessus. Ajout seul |
ReferenceOccurrence (struct) | Une occurrence — Kind · FromTab · RowNumber · ColumnNumber · FieldName · TargetTab · TargetId · ToCoordinate() |
ReferenceOccurrenceKind (enum) | Scalar · ListElement · ExplicitDefault · WrapperElement · CustomElement (une référence qu'un IRefBearingValue a déclarée en dehors de sa propre notation — coordonnées au niveau de la cellule, puisque la disposition interne appartient à ce type). Ajout seul, si bien que les valeurs existantes gardent leur sens |
IEdgeContributor | Déclare les arêtes que le scanner ne peut pas voir. Aucun diagnostic. string Name · ContributeEdges(EdgeContributionContext, ICollection<EdgeSpec>) |
EdgeSpec | Une arête — FromTab/FromRecordId/ToTab/ToRecordId (+ FieldName optionnel, PayloadTab/PayloadRecordId pour les arêtes d'enregistrement, Label) |
EdgeContributionContext | Tables + KeyIndices en lecture seule (aucun collecteur d'erreurs — les arêtes ne sont pas de la validation) |
IAuthorableEdgeContributor | Capacité optionnelle qu'un IEdgeContributor peut aussi implémenter afin que son arête soit éditable sur le canevas de graphe. bool TryPlanConnect(EdgeAuthoringContext, fromTab, fromRecordId, toTab, toRecordId, out EdgeCellWrite) · bool TryPlanDisconnect(EdgeAuthoringContext, RecordEdge, out EdgeCellWrite) — false = rien n'est préparé et l'affordance est désactivée avec une raison ; les deux s'exécutent à l'intérieur d'un try/catch |
IEdgeTokenEditor | Capacité optionnelle qu'un IEdgeContributor peut aussi implémenter afin que le reste de son jeton (tout ce qui n'est pas la clé) soit éditable dans l'inspecteur de fil. bool TryDescribeToken(EdgeAuthoringContext, RecordEdge, out EdgeTokenDescription) · bool TryPlanSetModifier(EdgeAuthoringContext, RecordEdge, string newModifier, out EdgeCellWrite) — les deux lisent la même cellule (une arête sait vers quoi elle pointe, pas comment elle est écrite aujourd'hui), false = la ligne est cachée ou honnêtement désactivée ; les deux s'exécutent à l'intérieur d'un try/catch |
EdgeTokenDescription | Ce qu'est un jeton et comment éditer son reste — TokenText (le fragment à mettre en évidence) · ModifierText · HasModifier · ModifierLabel · IsChoice · Options / OptionLabels. new EdgeTokenDescription(tokenText) = pas de reste, donc aucune ligne n'est dessinée ; le constructeur à choix retombe sur du texte libre quand la liste d'options est vide |
IBatchAuthorableEdgeContributor | Capacité optionnelle, sœur d'IAuthorableEdgeContributor (pas un héritage) : des plans de connexion/déconnexion sous forme de liste d'écritures de cellule, pour des données où un seul geste doit changer plusieurs cellules appariées ensemble. bool TryPlanConnectMany(EdgeAuthoringContext, fromTab, fromRecordId, toTab, toRecordId, out IReadOnlyList<EdgeCellWrite>) · bool TryPlanDisconnectMany(EdgeAuthoringContext, RecordEdge, out IReadOnlyList<EdgeCellWrite>) — toute la liste est préparée comme une seule étape d'annulation ou pas du tout ; les contributeurs singuliers continuent de fonctionner (repli), et le lot l'emporte quand une classe implémente les deux |
IVirtualNodeFactory | Capacité optionnelle : des gestes « créer » de canevas qui ne sont pas une nouvelle ligne de feuille. IReadOnlyList<VirtualNodeKind> KindsFor(EdgeAuthoringContext, tab, recordId) (appelée à chaque construction de menu — restez léger) · bool TryPlanCreate(EdgeAuthoringContext, tab, recordId, VirtualNodeKind, out IReadOnlyList<EdgeCellWrite>) — false = la session n'est pas touchée. Un plan ne peut pas viser un enregistrement créé dans le même geste |
VirtualNodeKind (struct) | Une sorte créable — Id (renvoyé verbatim au choix) · Label (texte de menu déjà traduit ; / imbrique) · IsUsable. Sûr avec null, sûr avec default |
IEdgeSlotDeclarer | Capacité optionnelle : des ports qu'un nœud (virtuel) ouvre sans avoir besoin d'une arête vivante. IReadOnlyList<DeclaredSlot> DeclareSlots(EdgeAuthoringContext, nodeTab, nodeRecordId) — les slots déclarés rejoignent le menu de connexion, le sélecteur de port et les lignes de port de la carte ; appelée à chaque rendu, donc les implémentations doivent être légères et sans effet de bord |
DeclaredSlot (struct) | Un slot déclaré — FieldName (unique par nœud ; doit correspondre au FieldName de l'arête du contributeur pour que les fils s'ancrent) · TargetTab · IsList · IsUsable. Sûr avec null, sûr avec default |
EdgeAuthoringContext | L'entrée de planification — Tables + string CellText(tab, recordId, field), qui renvoie la cellule telle qu'elle se lit maintenant (baseline plus préparation), si bien que deux liens faits à la suite se voient l'un l'autre |
EdgeCellWrite (struct) | Le plan : TabName · RecordId · FieldName · NewRawText (vide = effacer) · IsAddressable. Adressé par clé, pas par numéro de ligne |
ReferenceScanner — les deux prédicats de référence :
GetReferencedTab(TypeToken)— l'unique prédicat que tout consommateur interroge, « est-ce une référence, et vers où ». Il répond pourRecordId@Tab, pourIntId@Tab(l'espace de clé entier), pour l'intérieur d'un wrapper, et pour un type personnalisé marquéIsCustomReference. C'est pourquoi un seul opt-in — et, pourIntId@Tab, un élargissement de ce prédicat — les active tous à la fois.GetReferenceKind(TypeToken)→RefKeyKind— si la référence se compare contre l'espace de clé chaîne ou entier, afin que la propagation de renommage, la liste déroulante et le sélecteur branchent correctement.GetReferenceKind(TypeToken, tables)— la surcharge consciente des tables.
Une référence du Core énonce son propre espace (RecordId / IntId). Un type personnalisé référençant n'a aucune notation pour le dire — MyType@Tab est la seule orthographe — si bien que son espace est dérivé de la propre identité de l'onglet cible : une clé propre RecordId signifie l'espace chaîne, IntId seul signifie l'espace entier, et un onglet inconnu ou des tables null retombent sur l'espace chaîne, la même réponse que donne la surcharge à jeton seul. Cette dérivation est ce qui permet à une implémentation existante d'IReferencingCellType de viser un onglet à clé IntId sans qu'une seule ligne ne change.
Index du graphe de référence (SheetForge.Core.Edges)
Un instantané immuable qui fusionne les références scannées par le Core et les arêtes de contributeur en un seul modèle, indexé dans les deux sens. Matériau d'affichage — il ne produit jamais de diagnostics (les Diagnostics de la projection restent l'unique source de vérité pour les problèmes).
| Type | Genre | Rôle et membres clés |
|---|---|---|
RecordEdge (struct) | valeur | Une arête. RecordEdgeOrigin Origin · FromTab · FromRecordId (vide pour les arêtes au niveau champ) · FieldName · RowNumber / ColumnNumber (indexés à partir de 1 ; 0 = niveau champ/onglet) · ToTab · ToRecordId (l'id voulu même non résolu) · bool IsDangling (fixé à la construction) · Label · PayloadTab / PayloadRecordId (arêtes d'enregistrement) |
RecordEdgeOrigin (enum) | — | CoreReference (lue depuis une cellule RecordId@Tab — a des coordonnées) · Contributor (déclarée par un IEdgeContributor — au niveau de l'enregistrement) |
ReferenceIndex | classe scellée | L'instantané. Build(tables, keyIndices, contributorEdges, codeRegistries, extraKeys = null) statique (les trois derniers peuvent être null ; extraKeys = onglet → clés qui existent mais ne sont pas encore analysées, par ex. des lignes qu'une surface de création vient de préparer, si bien que les liens vers elles ne sont pas dessinés comme cassés) · AllEdges (ordre déterministe : onglet source Ordinal → ligne → colonne → occurrence) · OutEdges(tab, recordId) / InEdges(tab, recordId) (jamais null) · int InCount(tab, recordId) · bool TryGetRowKey(tab, rowNumber, out recordId) · DanglingEdges |
Canevas d'enregistrements du Data Studio (SheetForge.Core.Graphing)
Le canevas décide seul de ce qu'il dessine : il parcourt l'index de référence vers l'extérieur depuis l'enregistrement que vous avez ouvert (le terminus) et dispose le résultat de façon déterministe. Un plugin ne remplace pas cette image — il l'enrichit. Des données pures de bout en bout : les colonnes sont des cellules de grille, pas des pixels, et les couleurs sont une chaîne Category libre que la fenêtre associe à une palette.
| Type | Genre | Rôle et membres clés |
|---|---|---|
IRecordCanvasAugmenter | interface | La surcharge de canevas d'un onglet, appelée après l'assemblage de la fermeture. Augment(GraphBuildContext, CanvasAugmentBuilder, string terminusTab, string terminusRecordId). N'ajouter rien laisse l'image du Core telle quelle. Une exception levée est interceptée par la fenêtre et devient un avertissement de console en anglais. L'identité appartient aux données — un nœud virtuel perd face à un véritable enregistrement de la même clé. La présentation, l'indice d'affichage, n'y appartient pas |
CanvasAugmentBuilder | classe scellée | La surface d'écriture, seulement quatre choses — membres et règles sous le tableau |
GraphShapeRegistry | classe scellée | Nom d'onglet → surcharge de canevas. Register(tabName, IRecordCanvasAugmenter) (onglet en double / nom vide / null lèvent une exception) · TryGet · IsEmpty |
GraphBuildContext | classe scellée | L'entrée en lecture seule de la surcharge. Tables (onglet → SheetTable) · ReferenceIndex References · IReadOnlyList<CodeRegistrySource> CodeRegistries (vide, jamais null). Aucun collecteur d'erreurs — un canevas est de l'affichage, pas de la validation |
GraphSpecBuilder | classe scellée | L'assistant d'assemblage du graphe. Constructeur (GraphBuildContext) · NodeKey(tab, recordId) statique (l'unique vérité que ciblent les fils) · AddNode(GraphNodeSpec) (le premier (Key, Column) l'emporte) · AddWire(GraphWireSpec) · AddWire(fromKey, toKey, label, fromTab, fromRecordId, fieldName, isCyclic = false, cyclicNote = null) (la surcharge qui nomme aussi la cellule dans laquelle le lien est écrit, ce qui est ce qui rend le fil éditable) |
GraphSpec | classe scellée | Le résultat assemblé que le canevas dessine — Nodes · Wires (l'assemblage passe par le builder ; le constructeur est internal) |
GraphNodeSpec | classe scellée | Un nœud. Key · Tab · RecordId · Title · Subtitle · Category · CellCoordinate Address · Column / Row (cellules de grille déjà résolues par le canevas — portées, pas choisies, ici) · IsFocus (le terminus) · IsMissing · InCount · IsCyclic |
GraphWireSpec | classe scellée | Un fil. FromKey · ToKey · Label · IsCyclic · CyclicNote, plus la cellule propriétaire optionnelle : FromTab · FromRecordId · FieldName · RecordEdge? SourceEdge (null = fil en affichage seul ; le canevas dit alors qu'il ne peut pas être édité). Les cinq arguments d'affichage sont inchangés, si bien que les appels existants compilent et se rendent de façon identique |
IAuthorableGraphShape | interface | Capacité optionnelle qu'un IRecordCanvasAugmenter peut aussi implémenter. IReadOnlyList<string> CreatableTabs(GraphBuildContext, string tabName) — où le canevas peut créer un enregistrement (vide = nulle part). Les comportements par défaut sans elle sont détaillés sous le tableau |
CanvasAugmentBuilder — la surface d'écriture. Seulement quatre choses :
AddNode(tab, recordId, title = null, category = null)/AddNode(tab, recordId, title, category, CellCoordinate address)— un nœud virtuel pour une identité qui n'est pas un enregistrement de feuille (une clé d'événement, un atome de code) ; l'onglet peut être vide.AddEdge(fromTab, fromRecordId, toTab, toRecordId, label = null, fieldName = null, fieldOnTarget = false, isCyclic = false, cyclicNote = null)— une arête supplémentaire que le scanner du Core ne peut pas voir. NommerfieldNameindique dans quelle cellule le lien est écrit,fieldOnTargetindique que cette cellule se trouve sur l'arrivée plutôt que le départ, et la paire de cycle marque une boucle pour l'affichage avec la note que seul le domaine connaît.SetLayer(tab, recordId, layer)— un indice de calque absolu (0 = le plus à gauche, négatif = plus à gauche encore, tout se décale à droite pour compenser).SetLayerRelative(tab, recordId, offset)— le même compté depuis le terminus (−1 = une colonne à sa gauche), résolu par rapport à la colonne du terminus avant qu'un indice ne l'ait déplacée.SetSubtitle(tab, recordId, subtitle)— un indice d'affichage, la seule chose qui s'applique aux enregistrements qui existent déjà et aux enregistrements absents de l'écran (le sélecteur de connexion les lit).
Les éléments avec une clé vide sont ignorés, et ce qui a été collecté est interne, car les règles de fusion vivent en un seul endroit. Chaque élargissement est en fin de liste, si bien qu'une surcharge écrite pour une surface antérieure compile toujours.
IAuthorableGraphShape — les deux comportements par défaut sans elle :
- La liste des onglets créables que cette capacité remplace — l'axe qui décide aussi si un canevas s'ouvre du tout et jusqu'où va le balayage des lignes en attente — couvre chaque onglet atteignable depuis l'onglet ciblé en suivant le schéma transitivement.
- La cascade de liaison que l'utilisateur voit réellement part des onglets que ciblent les ports actuellement dessinés.
Les deux abandonnent les onglets de registre de code et les onglets sans colonne clé. Un onglet renvoyé ici qu'aucun port dessiné n'accepte reste listé dans la cascade de liaison avec sa raison attachée, et les propres barrières de la fenêtre s'appliquent quand même par-dessus.
Préréglages de couleur (SheetForge.Core.Theming)
| Type | Rôle et membres clés |
|---|---|
ThemeRegistry | Id de préréglage → thème. Les id vides, les doublons et les deux id intégrés réservés lèvent une exception. Register(SheetForgeTheme) · TryGet · Themes · IsEmpty · IsBuiltInId(id) · BuiltInDefaultId · BuiltInHighContrastId |
SheetForgeTheme | Un préréglage de couleur. Id · DisplayName · DarkColors / LightColors (IReadOnlyDictionary<ThemeColorSlot, uint>, copié à la construction) · TryGetColor(dark, slot, out rgb) · IsEmpty |
ThemeColorSlot | enum — les 33 rôles de couleur qu'un préréglage peut surcharger (surfaces, lignes, texte, couleurs sémantiques, marques de préparation, surfaces d'échec, voile, graphe). Les couleurs sont en 0xRRGGBB : le Core ne référence aucun type moteur, et les remplissages translucides dérivent d'une couleur de slot plus un alpha fixe. Ajout seul. |
Un préréglage ne surcharge que les slots qu'il nomme ; chaque autre slot garde la valeur par défaut du produit, si bien qu'un préréglage reste valide à mesure que des slots sont ajoutés. Enregistrer n'applique jamais un préréglage — l'utilisateur en choisit un dans Preferences ▸ SheetForge ▸ Theme.
Surfaces de création déclaratives (SheetForge.Core.Studio)
Un plugin décrit ce qu'il faut montrer — la coquille comme données, le prédicat et l'effet comme délégués — et chaque hôte le dessine avec ses propres widgets : UIToolkit dans l'éditeur, React dans le navigateur. Aucun chiffre de mise en page n'apparaît nulle part. Quoi dire appartient au plugin, comment le placer appartient au moteur de rendu.
Chaque enum ici est ajout seul, si bien qu'un enregistrement garde son sens à mesure que le vocabulaire grandit.
| Type | Genre | Rôle et membres clés |
|---|---|---|
StudioUiRegistry | classe scellée | Ce que remplit RegisterStudioUi. AddAction(StudioActionDescriptor) · AddPanel(StudioPanelDescriptor) · AddColumnBadge(StudioColumnBadgeDescriptor) · AddCellEditorHint(StudioCellEditorHint) · Actions / Panels / ColumnBadges / CellEditorHints · IsEmpty |
StudioUiNode | classe scellée | Un fragment décrit, immuable, construit via des fabriques statiques — les fabriques, les propriétés de lecture et la règle d'URL sont sous le tableau |
StudioUiNodeKind | enum | Les 13 genres ci-dessus (Row … Link) |
StudioActionDescriptor | classe scellée | Un verbe. Id (unique) · LabelKey (une clé Loc ; non enregistrée = affichée verbatim) · StudioActionPlacement Placement · Func<StudioSurfaceContext,bool> AppliesTo · Action<StudioSurfaceContext> Execute · ConfirmKey (optionnel — l'hôte demande cette phrase d'abord). L'hôte revérifie AppliesTo au moment de l'invocation, si bien qu'une entrée de menu périmée répond par un no-op honnête et un redessin |
StudioActionPlacement | enum | Inspector · RowContextMenu · TopbarMenu · ColumnHeaderMenu · CanvasNodeMenu. Chaque siège remplit des champs de contexte différents — le siège de ligne porte l'enregistrement, le siège de colonne le nom de colonne, le siège de canevas l'enregistrement de ce nœud |
StudioPanelDescriptor | classe scellée | Un panneau dans le panneau à droite du Studio. Id · TitleKey · Func<StudioSurfaceContext,StudioUiNode> Build — reconstruit à chaque tick de recalcul, il ne porte donc aucun état. Sans panneau enregistré, le panneau n'est pas dessiné du tout |
StudioColumnBadgeDescriptor | classe scellée | Un badge à côté d'un en-tête de colonne. Func<StudioSurfaceContext,string,string,StudioUiNode> Provide (contexte, onglet, champ) — null signifie rien sur cette colonne |
StudioCellEditorHint | classe scellée | « Utiliser ce widget intégré pour ce type » — choisir un genre plutôt qu'en fournir un. TypeName (un nom de type CellParserRegistry exact ; une cellule de liste est mise en correspondance sur le nom de son élément ; les cellules wrapper conservent le texte canonique et ne sont jamais mises en correspondance) · StudioCellEditorArchetype Archetype · GetOptions (liste déroulante seulement — Func<context, tab, field, IReadOnlyList<StudioCellOption>>) · SliderMin / SliderMax · ToggleTrueValue / ToggleFalseValue. Quatre constructeurs, un par forme de matière. Consulté après qu'un IStudioCellEditorProvider enregistré décline et avant les branches intégrées ; l'indice d'un pack est consulté avant les indices intégrés ci-dessous, si bien qu'en enregistrer un sous Color, AnimationCurve ou Gradient remplace l'éditeur par défaut pour ce type. Un List<> dont l'indice d'élément est ColorPicker, CurveEditor ou GradientEditor devient un éditeur à puces dans les deux hôtes |
StudioCellEditorArchetype | enum | Dropdown · MultilineText · Slider · Toggle · ColorPicker (texte de cellule #RRGGBB / #RRGGBBAA) · CurveEditor (texte de cellule = la notation canonique CurveValue) · GradientEditor (texte de cellule = la notation canonique GradientValue). Ajout seul — les deux plus récents sont 5 et 6 |
BuiltinCellEditorHints | classe statique | Les trois indices que le Core déclare lui-même — Color → ColorPicker, AnimationCurve → CurveEditor, Gradient → GradientEditor — empruntant le même chemin que les indices d'un pack, si bien que l'éditeur et le navigateur ne peuvent pas choisir des widgets différents pour eux. IReadOnlyList<StudioCellEditorHint> All (ordre fixe) · bool TryGet(typeName, out hint) (Ordinal). Les hôtes consultent d'abord StudioUiRegistry.CellEditorHints puis se replient sur cette table |
StudioCellOption | classe scellée | Un candidat de liste déroulante — Value (le texte canonique écrit dans la cellule) · Label (ce que lit une personne ; par défaut Value) |
StudioSurfaceContext | classe scellée | L'unique couture qu'une extension voit et par laquelle elle agit. Lecture : Tables · ReferenceIndex References · CodeRegistries · Tab · RecordId · Field · ActionArgument (la valeur qu'un nœud Input a validée). Mutation médiée, et rien d'autre : Action<string,string,string,string> StageCell · Action<IReadOnlyList<EdgeCellWrite>> StageCells (une étape d'annulation, tout ou rien) · Action<string,string> FocusRecord · Action RequestRebuild. La préparation passe par la propre barrière de la fenêtre, si bien qu'une source en lecture seule, un pipeline en cours ou un onglet d'origine classeur la bloque avec une raison (constructeur internal : l'hôte l'assemble) |
StudioUiNode — fabriques, lectures et la règle d'URL :
- Fabriques :
Row·Label·Chip·Badge·Button·Rule·Heading·KeyValue·Table(headerRow, rows)·List·Progress·Input·Link, plusWithTooltip(text), qui renvoie un nouveau nœud plutôt que de modifier celui-ci. - Lectures :
Kind·Text·Tooltip·ThemeColorSlot? Tone(jamais une couleur codée en dur, si bien qu'il suit le thème) ·ActionId·Detail·Ratio·Url·Children. bool IsAllowedUrl(url)statique —http/httpsseulement. Un seul prédicat que les deux hôtes interrogent, si bien qu'ils ne peuvent pas être en désaccord sur ce qui est sûr à ouvrir.
Chaînes d'UI de plugin (SheetForge.Core.Model)
| Type | Rôle et membres clés |
|---|---|
StringOverlayRegistry | Collecteur et surcouche de lookup pour les chaînes d'UI enregistrées par plugin ; Loc.Tr (éditeur) et t() (navigateur) la consultent avant les tables du produit. Register(key, language, value) · Register(key, IReadOnlyDictionary<string,string> byLanguage) · bool TryGet(key, language, out value) · RegisteredKeys. La correspondance de langue et les quatre refus sont sous le tableau |
StringOverlayRegistry — correspondance et refus. language est un code IETF ("en", "ko", "zh-Hans", "pt-BR", …), comparé sans tenir compte de la casse. La recherche retombe langue demandée → anglais → échec, et le repli vit ici afin que les deux hôtes répondent de façon identique.
Quatre enregistrements sont refusés, chacun consignant une raison destinée au développeur plutôt que d'échouer silencieusement :
- une clé intégrée du produit — une surcouche peut ajouter des clés, jamais écraser les propres phrases ou chemins de menu du produit ;
- une clé+langue qu'un autre pack a déjà enregistrée — le premier trouvé l'emporte, sinon l'ordre d'installation déciderait de l'écran ;
- une clé ou une valeur vide ;
- un code de langue que le produit ne connaît pas, jamais replié sur l'anglais.
Observation du pipeline (SheetForge.Core.Plugins / .Model)
| Type | Rôle et membres clés |
|---|---|
IPipelineObserver | Notification en lecture seule. void OnImportCompleted(PipelineRunView view) — une fois par cycle d'import explicite, à sa fin, succès ou échec. Il n'y a délibérément aucun crochet qui modifie une valeur ou ajoute un diagnostic (cela appartient à un type de cellule et à IDomainValidator), et aucun qui s'exécute sur la validation préalable de préparation. Une exception levée est isolée avec sa raison collectée ; la sortie de l'import est inchangée. Les futurs points d'observation arrivent comme des interfaces de capacité sœurs, castées depuis l'observateur enregistré, si bien qu'une implémentation écrite aujourd'hui continue de compiler |
PipelineObserverRegistry | Liste d'observateurs en ajout seul, ordre préservé. Register(IPipelineObserver) · Observers |
PipelineRunView | L'instantané immuable que reçoit un observateur — Success (validation, c.-à-d. un registre a-t-il été assemblé ; les résultats de codegen/bake se lisent depuis les diagnostics) · Tables (les onglets qui se sont analysés ; sur une exécution en échec, seuls les onglets qui n'ont pas pu être analysés manquent, car l'absence d'assemblage partiel est une règle de sortie, pas une règle d'observation) · Diagnostics (la même liste que montre le rapport) · SkippedTabs · EnumTabs. Les collections sont copiées à la construction, et le constructeur est internal afin qu'aucun instantané à moitié construit ne puisse être remis à un observateur |
Registres de code (SheetForge.Core.Graphing)
Des cibles de référence qui vivent dans le code, exposées à la surface de création comme des onglets virtuels verrouillés. Consommées par le Data Studio (barre latérale / graphe / inspecteur), pas par le validateur d'import.
| Type | Genre | Rôle et membres clés |
|---|---|---|
CodeRegistryCatalog | classe scellée | Racine d'enregistrement. Register(CodeRegistrySource) (source null / nom d'onglet vide / nom d'onglet en double lèvent une exception) · TryGet(tabName, out source) · Sources · IsEmpty |
CodeRegistrySource | classe scellée | Un onglet virtuel verrouillé. string TabName · IReadOnlyList<CodeRegistryEntry> Entries (l'ordre d'enregistrement = l'ordre d'affichage) |
CodeRegistryEntry | classe scellée | Une entrée. string Key (ce vers quoi une référence peut pointer) · string Label · IReadOnlyList<string> Raises (null se normalise en vide). Le Core traite les trois comme des chaînes opaques |
Le modèle de lecture de l'IR (SheetForge.Core.Model)
| Type | Rôle et membres clés |
|---|---|
SheetTable | La sortie de parsing d'un onglet. SheetSchema Schema · IReadOnlyList<SheetRecord> Records |
SheetSchema | string TabName · Fields · TryGetField(name, out FieldSchema) · SheetStyle Style (les métadonnées d'affichage @style de la feuille) · bool IsLocalizationSheet (le marqueur @loc est présent) · IReadOnlyList<LocaleColumn> LocaleColumns (les colonnes de locale dans l'ordre de colonnes d'origine — vide sur une feuille qui n'est pas une feuille de localisation, jamais null) · TryGetLocaleColumn(localeCode, out LocaleColumn) (recherche par code, insensible à la casse) · TryGetSourceLocale(out LocaleColumn) (la première colonne de locale ; false quand il n'y en a aucune) |
SheetStyle | La valeur de la ligne @style — métadonnées d'affichage pour une feuille. string Title (libellé de groupe dans la barre latérale) · string ColorHex (#RRGGBB tel qu'écrit) · bool HasColor · None statique (pas de style). Jamais lu par le codegen, le bake ou l'empreinte de schéma |
LocaleColumn (struct) | Une colonne de locale d'une feuille de localisation — ce que la ligne @loc a écrit sur cette colonne. string Code (le code exactement tel qu'écrit ; le Core valide la forme orthographique, jamais l'existence de la locale) · string FieldName · int ColumnNumber (indexé à partir de 1) · bool IsSource (la première colonne de locale — celle que les prévisualisations en ligne lisent et celle où la génération automatique de clé écrit) |
SheetRecord | int RowNumber (original, indexé à partir de 1) · Values (champ → CellValue) · TryGet · indexeur |
FieldSchema | Name · TypeToken Type · Description · ColumnNumber · DefaultValue · AllowOverlap · IReadOnlyDictionary<string,string> MarkerValues (nom de marqueur personnalisé → texte de cellule de cette colonne) |
TypeToken | La cellule @type analysée. RawText · TypeName · TypeArgument · TargetName · IsList · IsOptional · HasExplicitDefault · DefaultValueText · AllowsEmptyCell · IsSelfKey · IsIntId (la clé entière propre de cet onglet uniquement — la forme de référence IntId@Tab se lit via TargetName + ReferenceScanner.GetReferencedTab, comme RecordId@Tab) · TypeToken InnerToken / IsWrapper (types wrapper — élément interne récursif) · IsCustomReference (cette colonne est MyType@Tab où le parseur implémente IReferencingCellType ; ReferenceScanner.GetReferencedTab est l'unique prédicat qui le lit, ce qui explique comment tout consommateur s'est allumé sans changement de signature) · AssetTypeName (le <Type> d'AssetRef@Group<Type> tel qu'écrit, null quand non restreint ; le Core ne stocke que le nom — le résoudre est le travail d'IAssetTypeResolver — et il est aussi estampillé sur le jeton AssetRef à l'intérieur d'une liste ou d'un wrapper). Les trois paramètres finaux du constructeur (innerToken, isCustomReference, assetTypeName) ont une valeur par défaut, si bien que les appels existants compilent, et les précédents constructeurs à 8 et 10 arguments demeurent en tant que surcharges, si bien que les assemblies de plugin déjà compilées continuent de fonctionner sans recompilation |
CellValue (struct) | Une valeur de cellule typée ; aucun null (IsDefaulted marque les valeurs par défaut matérialisées). object Value · IsDefaulted · AsList · statiques Of / Defaulted |
RecordId (struct) | Une valeur de clé (égalité Ordinal). string Value · IsEmpty |
RecordRefValue (struct) | La valeur d'une cellule RecordId@Tab. TargetTab · Id |
IntRefValue (struct) | La valeur d'une cellule IntId@Tab — le jumeau à clé entière de RecordRefValue. string TargetTab · int Id · bool IsEmpty · Empty(tab) statique (un IntId@Tab? optionnel qui ne pointe vers rien) |
LocRefValue (struct) | La valeur d'une cellule LocRef@Tab — le jumeau de localisation de RecordRefValue, conservé comme un type distinct pour qu'un consommateur sache d'après la seule valeur qu'elle pointe vers une table de chaînes. string TargetTab · string Key · bool IsEmpty · Empty(tab) statique · ReferencedKeys. Elle implémente IRefBearingValue, si bien que le scanner de références la traite exactement comme une référence du Core |
AssetRefValue (struct) | La valeur d'une cellule AssetRef@Group. Group · Key (la clé d'un sous-asset est parent[sub]) |
EnumValue (struct) | La valeur d'une cellule Enum<T> (paire de chaînes — la conversion CLR est le travail du bake). EnumName · MemberName |
Références d'asset typées (SheetForge.Core.Model)
Le <Type> de AssetRef@Group<Type> est résolu par l'hôte — le Core ne connaît ni le moteur ni les assemblies du projet — et le Core ne fait que juger le résultat. Tout ici est de la donnée pure.
| Type | Genre | Rôle et membres clés |
|---|---|---|
IAssetTypeResolver | interface | AssetTypeResolution Resolve(string rawName) — un nom en entrée, un verdict en sortie ; le même nom obtient toujours la même réponse (les implémentations peuvent mettre en cache). Injecté dans ImportPipeline séparément d'AssetKeyIndex, si bien que les noms de type sont résolus même dans un projet qui n'a pas encore de paramètres Addressables ; quand aucun résolveur n'est injecté (headless, navigateur), les diagnostics de nom de type ne sont tout simplement pas produits. L'implémentation de l'Editor résout par rapport aux types d'asset chargés du projet dérivés d'UnityEngine.Object (aucune liste blanche ; les composants et les types réservés à l'éditeur sont exclus) |
AssetTypeResolution | classe scellée | Le verdict pour un nom — RawName · AssetTypeResolutionStatus Status · FullName (nom complet CLR, types imbriqués avec + ; Resolved et NotReferenceable seulement) · AssemblyName (l'assembly que l'assembly compagnon généré doit référencer — renseigné pour les types à assembly definition, null pour les modules moteur et les noms non résolus) · Candidates (jamais null : les candidats ambigus, ou des suggestions de correspondance la plus proche pour un nom inconnu). Fabriques Resolved(raw, fullName, assemblyName) · Unknown(raw, suggestions) · Ambiguous(raw, candidates) · NotReferenceable(raw, fullName, assemblyName) |
AssetTypeResolutionStatus | enum | Resolved · Unknown (aucun type de ce genre) · Ambiguous (le nom court correspond à plusieurs types — écrivez le nom complet) · NotReferenceable (le type vit dans un assembly prédéfini tel que Assembly-CSharp, que le code généré ne peut pas référencer) |
Le codegen lit le dictionnaire résolu que produit le pipeline et émet AssetReferenceT<global::FullName> pour un nom résolu ; un nom qu'il ne trouve pas dans ce dictionnaire n'est jamais émis tel quel — le champ se replie sur AssetReference et un avertissement AssetTypeUnresolvedFallback est collecté. Le nom complet résolu est aussi mélangé dans l'empreinte de schéma.
Types de valeur visuelle (SheetForge.Core.Model)
Modèles de valeur indépendants du moteur pour les trois types visuels intégrés. Chacun est immuable, IEquatable, et possède sa propre forme de texte (TryParse / Render) — la même notation que documente la page Syntaxe des feuilles — si bien qu'un type de plugin qui stocke une couleur, une courbe ou un dégradé peut les réutiliser au lieu d'inventer une seconde notation. L'Editor les bake dans UnityEngine.Color / AnimationCurve / Gradient et les relit ; le navigateur les échantillonne via les évaluateurs ci-dessous plutôt que de réimplémenter les mathématiques.
| Type | Genre | Rôle et membres clés |
|---|---|---|
ColorValue | struct en lecture seule | Quatre octets R · G · B · A · Default statique (#00000000) · TryParse(text, out value, out error) statique (accepte #RGB / #RGBA / #RRGGBB / #RRGGBBAA) · Render() (majuscules, six chiffres quand opaque) |
CurveValue | classe scellée | Keys (croissant par temps) · PreWrap / PostWrap · Empty statique (aucune clé — le seul état sans forme de texte ; Render() donne "") · Create(keys, preWrap, postWrap) statique — l'unique chemin de construction : trie par temps, rejette les temps en double, et applique CurveTangentSolver afin que « le mode l'emporte » tienne dès l'instant où une courbe existe · TryParse statique (clés à 2/4/7/8 champs, Once accepté comme alias de ClampForever, tangentes Infinity/-Infinity) · Render() (clés à 8 champs, suffixe de wrap seulement quand nécessaire) |
CurveKey | struct en lecture seule | Time · Value · InTangent · OutTangent · InWeight · OutWeight · CurveWeightedMode WeightedMode · CurveTangentMode LeftMode / RightMode · bool Broken ; un constructeur à dix arguments sans normalisation propre |
CurveWrap | enum | ClampForever · Loop · PingPong · Default — le vocabulaire de wrap d'Unity par son nom (la mise en correspondance de la valeur avec WrapMode appartient au baker) |
CurveTangentMode | enum | Free = 0 · Auto = 1 · Linear = 2 · Constant = 3 · ClampedAuto = 4 — nom et valeur identiques à AnimationUtility.TangentMode, si bien que le baker fait la correspondance par nom et ne touche jamais aux bits de tangente compactés d'Unity |
CurveWeightedMode | [Flags] enum | None = 0 · In = 1 · Out = 2 · Both = 3 — quel côté d'une clé utilise des tangentes pondérées (Bézier) |
CurveTangentSolver | classe statique | CurveKey[] Apply(IReadOnlyList<CurveKey> sortedKeys) — dérive les nombres de tangente que dicte un mode, en appliquant les étapes dans l'ordre du moteur (Linear sur son propre côté → ClampedAuto des deux côtés → Auto des deux côtés → Constant sur son propre côté), en laissant intacts les côtés Free et les poids. CurveValue.Create l'appelle, si bien que les appelants le font rarement eux-mêmes |
CurveEvaluator | classe statique | float Evaluate(CurveValue, float time) · float[] Sample(CurveValue, int count) (count ≥ 2, régulièrement espacé de la première à la dernière clé) — Hermite entre les clés, Bézier pondéré sur les côtés dont le drapeau de poids est activé, un maintien quand une tangente est infinie, et les quatre comportements de wrap hors de la plage de clés ; vérifié contre AnimationCurve.Evaluate sur des courbes aléatoires |
GradientValue | classe scellée | ColorKeys · AlphaKeys (1 à 8 chacune, croissant par temps) · GradientBlend Mode · GradientColorSpace ColorSpace · Default statique (blanc, entièrement opaque, Blend) · Create(colorKeys, alphaKeys, mode, colorSpace) statique (valide les comptes et les plages 0…1, quantifie les temps sur 16 bits comme le fait Unity, trie de façon stable) · TryParse statique (trois ou quatre sections séparées par ` |
GradientColorKey | struct en lecture seule | ColorValue Color (alpha ignoré — l'alpha a ses propres clés) · float Time |
GradientAlphaKey | struct en lecture seule | float Alpha · float Time |
GradientBlend | enum | Blend · Fixed · PerceptualBlend |
GradientColorSpace | enum | Uninitialized (non écrit ; se lit comme Gamma) · Gamma · Linear — seul PerceptualBlend est affecté |
GradientEvaluator | classe statique | ColorValue Evaluate(GradientValue, float time) · ColorValue[] Sample(GradientValue, int count) — fondu linéaire, en paliers ou perceptif (Oklab) avec les clés alpha fondues séparément, arrondies en octets ; vérifié contre Gradient.Evaluate sur des dégradés aléatoires |
Erreurs et résultats (SheetForge.Core.Model / .Reporting)
| Type | Rôle et membres clés |
|---|---|
ImportError | Erreur structurée, neutre vis-à-vis de la locale. Code · Severity · Coordinate · ActualValue · Expected · Suggestion |
ImportErrorCode (enum, 105) | Le catalogue complet des « pourquoi » — les familles qu'il couvre sont listées sous le tableau. Ajout seul, car les tables des moteurs de rendu s'indexent sur les valeurs des membres |
ImportSeverity (enum) | Error (bloque la sortie) · Warning |
CellCoordinate (struct) | Onglet · ligne indexée à partir de 1 · colonne indexée à partir de 1 · champ ; calcule la lettre de colonne façon tableur. Fabriques ForTab / ForRow |
ErrorCollector | Puits qui collecte tout. All · HasErrors · ErrorCount · Add |
ImportResult | La sortie du pipeline. Invariant : Success == false ⇔ Registry == null. Success · Registry · Diagnostics · SkippedTabs · EnumTabs (onglets lus comme des feuilles de définition d'enum, donc jamais analysés comme des tables de données. Ils sont tenus à part des SkippedTabs, qui signifie « pas encore de table écrite », si bien que le compte « sauté » du rapport reste vrai. Les deux sont des ensembles de préservation qui conservent le code généré, les assets bake et les adresses pour ces onglets) · statiques Succeeded / Failed |
ImportReport (.Reporting, assembly SheetForge.Core.Tooling) | L'entrée des moteurs de rendu de rapport — Timestamp · SourceDescription · TabCount · RecordCount · Success · Diagnostics · ErrorCount · WarningCount · SkippedTabCount (combien de TabCount étaient des feuilles vides sautées plutôt qu'importées — l'en-tête l'imprime pour qu'un nombre d'onglets ne soit pas confondu avec « tout importé ») |
ImportReportText (.Reporting, assembly SheetForge.Core.Tooling, statique) | Rend un rapport sous la propre chaîne lisible par un humain du produit. Rien n'est écrit dans la console, et aucun lien de saut ni ligne de coordonnées machine n'est ajouté — cela appartient à la propre convention de la console. string Render(ImportReport report, IReadOnlyDictionary<string,string> languageTable = null, string operationName = null) — omettez la table pour l'anglais. Le nom de l'opération, quand il est omis, est lu depuis la même table afin que la phrase ne mélange jamais deux langues. Les appelants côté Editor veulent généralement SheetForgeActions.RenderReportText(report), qui renseigne la langue d'éditeur actuelle (un assembly pur ne peut pas lire EditorPrefs) |
ImportErrorCode — les familles qu'il couvre :
- marqueurs, schéma, types, cellules, clés/références et clés d'asset ;
- sources/fichiers, csv/xlsx, identifiants de codegen, addressables, baseline/export, Google/authentification/Push et modèles ;
- plugins —
PluginRegistrationConflict, plusPluginIncompatiblequand la déclaration de compatibilité d'un assembly tombe hors de ce que cet hôte lit ; - IntId —
DuplicateIntId, et pour les référencesIntId@TabUnresolvedIntId·TargetTabHasNoIntId; @overlapetDomainRuleViolation;- feuilles de définition d'enum —
EnumSheetMarkerConflict·DuplicateEnumName·EnumSheetEmptyColumn·InvalidEnumIdentifier·InvalidEnumUnderlyingType·InvalidEnumMemberValue; DropdownNotSupportedByFormat, qui est un avertissement plutôt qu'une erreur ;- références d'asset typées —
UnknownAssetType·AmbiguousAssetType·AssetTypeNotReferenceable(une fois par colonne, sur la ligne@type),AssetTypeMismatchpar cellule, et l'avertissement de codegenAssetTypeUnresolvedFallback.
Index et utilitaires (SheetForge.Core.Validation / .Model / .Parsing / .Unparse)
| Type | Rôle et membres clés |
|---|---|
TabKeyIndex | Les informations de clé d'un onglet — la colonne clé chaîne plus l'ensemble de clés entières IntId de l'onglet, si bien que les références RecordId@Tab et IntId@Tab se résolvent toutes deux contre lui. TabName · KeyField · HasKeyColumn · Keys · Contains(id) |
KeyIndexBuilder (statique) | Construit les index de clé (les clés chaîne et l'ensemble de clés entières IntId, en une seule passe), signale les erreurs de clé, valide les colonnes IntId. Build(SheetTable, ErrorCollector) · ValidateIntIdColumns |
AssetKeyIndex | Groupe → ensemble de clés valides (l'Editor le remplit depuis le catalogue Addressables, clés de sous-asset comprises ; une injection null = ignorer la validation d'asset). Register(group, keys) · HasGroup · HasKey · KeysOf · GroupNames, plus la couche de type qu'utilise AssetRef@Group<Type> : RegisterTyped(group, key, satisfiedTypeFullNames) (la clé et la fermeture des noms complets de type sous lesquels elle peut être chargée — son propre type, ses bases, ses interfaces, les types de ses sous-assets ; se réenregistrer fait l'union de la fermeture) · HasTypeInfo(group, key) · SatisfiesType(group, key, typeFullName). Une clé enregistrée avec le simple Register n'a pas de fermeture et est exemptée de la vérification de type plutôt que d'y échouer |
LocalizationCoverage (statique) | Couverture par locale et clés orphelines d'une feuille de localisation. Un calcul pur qui renvoie des listes au lieu de collecter des erreurs, parce qu'une cellule non traduite et une clé inutilisée sont des états normaux plutôt que des sorties à bloquer. IReadOnlyList<LocaleCoverage> Compute(SheetTable) · IReadOnlyList<string> FindOrphanKeys(locTabName, tables) (les clés que rien ne pointe ; délibérément conservateur — toute forme de référence que le scanner connaît compte comme un usage, si bien qu'une traduction vivante n'est jamais qualifiée d'orpheline) |
LocaleCoverage (sealed class) | La couverture d'une locale. LocaleColumn Locale · int TotalKeys · int TranslatedKeys · IReadOnlyList<string> MissingKeys (ordre des lignes de la feuille, jamais null) · bool IsComplete |
TextSuggestion (statique) | Suggestions de correspondance la plus proche (Levenshtein borné, déterministe). FindNearest · Distance · DistanceWithin |
BuiltinCellParsers (statique) | CreateDefaultRegistry() — les 12 parseurs intégrés (int, float, bool, string, Enum, RecordId, AssetRef, IntId, LocRef, Color, AnimationCurve, Gradient). |
CanonicalValueRenderer (statique) | Valeur → chaîne de cellule canonique (Export/Push). TryRender(…) (délègue une ColorValue / CurveValue / GradientValue à son propre Render() ; une courbe sans clé se rend comme une cellule vide) · RenderFloat(float) (aller-retour le plus court) |
Plan de Push (SheetForge.Core.Unparse)
Public car IPushApprover.Approve(PushPlan) les expose ; données pures.
| Type | Rôle |
|---|---|
PushPlan (assembly SheetForge.Core.Tooling, comme les trois lignes ci-dessous) | Le plan d'envoi complet. Tabs · HasWork |
PushTabPlan | Un onglet : Writes · Appends · Deletes (clé + numéro de ligne ; DeleteNotices reste la vue clé seule) |
PlannedCellWrite | Une écriture de cellule — coordonnées, cellule de baseline, nouvelle valeur/texte, indicateur de famille de chaîne |
PlannedRowAppend | Une ligne ajoutée — textes de cellule complets + colonnes de famille de chaîne |
Assembly Editor (SheetForge.Editor)
Paramètres, localisation, composition (SheetForge.Editor.Pipeline / .Localization)
| Type | Rôle et membres clés |
|---|---|
SheetForgeSettings (SO) | L'asset de paramètres. Champs : sourceProviderId (seul axe de sélection de source ; vide = LocalFile intégré) · localFolderPath · bakeOutputFolder · generatedCodeFolder · generatedNamespace · exportFolderPath · exportFormat · spreadsheetId · googleAccessMode · serviceAccountKeyPath · gidMap (liste de GidMapEntry { tabName, gid }). Propriétés résolues Effective*. |
Loc (statique) | Le point d'entrée de la localisation. Tr(key) · TrContent(…) · Table · constante MenuRoot. Tr se résout en quatre étapes : chaîne enregistrée par plugin (langue actuelle, puis anglais — la surcouche possède ce repli, voir StringOverlayRegistry) → table intégrée (langue actuelle, puis anglais) → la clé elle-même. Il n'y a qu'un seul canal d'enregistrement pour les chaînes de plugin, si bien que « quel enregistrement l'emporte » ne devient jamais une question |
PluginRegistry (statique) | Découvre les plugins via TypeCache, puis remet les candidats à PluginComposition.Compose. Build · BuildValidators · BuildEdgeContributors · BuildStructuralMarkers · BuildTemplates · BuildGraphShapes · BuildCodeRegistries · BuildThemes · BuildAll (ensemble groupé) · InvalidateCache() (abandonne le cache à durée de vie du rechargement — même convention que SourceProviderRegistry.InvalidateCache ; abandonne aussi le cache de la barrière de compatibilité, si bien qu'un ensemble de découverte modifié est réjugé). Le bundle et l'isolation des emplacements sont détaillés sous le tableau |
ImportEvents (statique) | Le bus d'événements côté Editor — un contrat public : des assets externes peuvent s'abonner. event Action<ImportCompletedArgs> ImportCompleted · RaiseImportCompleted(ImportCompletedArgs) se déclenchent seulement quand un import est allé jusqu'au bout du bake, si bien qu'un abonné peut lire les assets bakés. event Action<BaselineUpdatedArgs> BaselineUpdated · RaiseBaselineUpdated(BaselineUpdatedArgs) se déclenchent chaque fois qu'un instantané de feuille a été enregistré — y compris une exécution qui a échoué à la validation — ce qui est comment une surface de création se rafraîchit sur un import mis en quarantaine. Deux axes, délibérément non fusionnés : l'un signifie « les feuilles ont bougé », l'autre « les assets ont bougé » |
BaselineUpdatedArgs (sealed) | La charge utile de sauvegarde de baseline. IReadOnlyList<string> Tabs (les onglets écrits dans l'instantané) · bool Quarantined (si l'instantané qui vient d'être enregistré a échoué à la validation) |
SheetForgeActions (statique) | La façade d'exécution — le même cycle qu'un clic de menu exécute, appelable depuis un script de CI, un hook de build ou votre propre bouton. RunImport() · RunExport() · RunPush() · RunHealthCheck() · RunLocalizationSync() (chacune délègue ; la résolution des paramètres, la barrière Addressables, l'exclusion mutuelle, les fenêtres modales de confirmation, la barre de progression et la reprise codegen→compilation→bake restent toutes à l'intérieur du produit) · bool IsBusy · bool TryBeginExclusiveScope(out IDisposable scope) (false + scope = null quand quelque chose est déjà en cours ; le scope est ce qui libère, et un second Dispose ne peut pas libérer l'exécution de quelqu'un d'autre) · string RenderReportText(ImportReport) (les propres phrases du produit dans la langue d'éditeur actuelle, sans écriture console). La sémantique de complétion est détaillée sous le tableau |
SheetForgeEditorInfo (statique, espace de noms SheetForge.Editor) | Ancre de l'assembly Editor — const Version, le miroir de SheetForgeRuntimeInfo pour le gate de fonctionnalités contre la surface côté éditeur |
ImportCompletedArgs (sealed) | La charge utile de complétion transmise aux abonnés. IReadOnlyList<string> Tabs (onglets bake par cette complétion) · string BakeFolder (dossier des SO Database). Motif objet-arguments — les futurs champs ne casseront pas la signature de l'événement. |
GoogleSheetAccessMode (enum) | SheetsApi (authentifié, inscriptible) · ExportUrl (sans authentification, lecture seule) |
ExportFormat (enum) | Tsv · Csv · Xlsx · Json · MatchSource |
PluginRegistry — le bundle et l'isolation des emplacements. Le PluginBundle imbriqué expose le PluginSet Set composé — la vérité unique à douze emplacements, ce qui permet de lire un emplacement nouvellement ajouté sans élargir le bundle — plus neuf fenêtres de commodité dessus : Enums · Parsers · Validators · EdgeContributors · Markers · Templates · GraphShapes · CodeRegistries · Themes. Les constructeurs antérieurs à six et huit arguments sont conservés comme surcharges qui mettent par défaut les registres ultérieurs à vide, ce qui se comporte de façon identique aux versions d'avant l'existence de ces contrats.
L'isolation appartient au Core, pas à ce type : un plugin qui lève une exception pendant l'enregistrement est signalé par son nom et ignoré, et tous les autres emplacements — ainsi que tout autre plugin — s'enregistrent quand même.
SheetForgeActions — sémantique de complétion. RunImport/RunPush sont fire-and-forget. Leur corps est async void car le thread principal de l'éditeur ne peut pas bloquer sur des E/S réseau, donc le retour n'est pas la complétion — abonnez-vous à ImportEvents.ImportCompleted pour cela. RunExport/RunHealthCheck/RunLocalizationSync se terminent de façon synchrone — RunLocalizationSync parcourt le chemin feuille → StringTable que parcourt une complétion d'import, et sans le package Unity Localization il affiche l'avis d'installation et ne change rien.
Couture des fournisseurs de source (SheetForge.Editor.Sources)
| Type | Rôle et membres clés |
|---|---|
ISheetSourceProvider | Le contrat de fournisseur. Id · DisplayNameKey · CreateTabSource(settings) · GetVisibility(settings) · CanAuthor(settings) · CreateReflectTarget(dispatcher, settings) |
ISourceReflectTarget | La cible d'écriture en retour. void Reflect() |
SourceVisibility | Quels champs de paramètres afficher — 5 indicateurs booléens |
SourceProviderRegistry (statique) | Découverte/résolution. All · ResolveActive(SheetForgeSettings) et ResolveActive(string providerId) (résout directement depuis un id, sans asset de paramètres en main) · TryGet · InvalidateCache |
ITabSource | Abstraction de récupération. Description · Task<TabSourceResult> FetchAsync() |
TabSourceResult | Onglets (nom → TSV brut) + diagnostics + formats par onglet ; sortie partielle autorisée. Create statique |
TabSourceFormat (enum) | Tsv · Csv · Xlsx · GoogleSheet |
Points d'extension du Data Studio (SheetForge.Editor.Studio)
Côté Editor car ils touchent aux UIElements / à l'état de fenêtre — la même asymétrie justifiée que pour ISheetSourceProvider. Les quatre contrats sont découverts par TypeCache (constructeur sans paramètre ; aucun appel d'enregistrement), et tous sont appelés à l'intérieur d'un try/catch. La fenêtre elle-même (DataStudioWindow) est internal.
Tout ce qui est exprimable comme données appartient plutôt au vocabulaire Core ISheetForgeStudioPlugin, qui se rend aussi dans le navigateur. Ce sont ici les échappatoires sans plafond pour ce que la description ne peut pas dire.
Les quatre dernières entrées ne sont pas des contrats mais des outils qu'un widget monté peut utiliser :
- les propres valeurs de skin en lecture seule de la fenêtre, pour qu'il ressemble à ce qu'il lui appartient ;
- la liste déroulante de clé, pour qu'un widget de cellule choisisse des clés de la même façon que la cellule intégrée ;
- et la réinitialisation du cache de découverte, pour que vos propres tests puissent redécouvrir une sonde.
| Type | Genre | Rôle et membres clés |
|---|---|---|
IStudioGraphWidget | interface | Une bande de domaine au-dessus du canevas de graphe (le Core n'en fournit aucune). bool AppliesTo(StudioGraphContext) · VisualElement Create(StudioGraphContext) (recréé à chaque reconstruction du graphe — ne gardez aucun état ; null n'ajoute rien) |
StudioGraphContext | classe scellée | Lecture seule : Tab et FocusRecordId (le terminus) · SheetRecord FocusRecord (null si non résolu) · Tables · ReferenceIndex References · CodeRegistries. Deux axes retirés subsistent pour la compatibilité de signature et sont marqués [Obsolete] : ShapeId (toujours "record") et ModeId (toujours vide). Comparer l'un ou l'autre compile et n'est jamais vrai, si bien que le compilateur le signale désormais au lieu de laisser une branche morte — supprimez le test. Aucune surface de préparation — les widgets sont en affichage seul (constructeur internal : la fenêtre l'assemble) |
IStudioCellEditorProvider | interface | Dessine une cellule de grille pour un type nommé. string TypeName (correspond à un type de CellParserRegistry ou à un nom de wrapper, Ordinal ; vide se retire) · VisualElement CreateEditor(StudioCellEditorContext) — renvoyer null refuse cette cellule et le widget intégré prend le relais. Une revendication en double sur le même nom de type avertit et garde le premier trouvé |
StudioCellEditorContext | classe scellée | Ce que reçoit le widget de cellule : Tab · FieldName · TypeToken Type · CurrentRawText (texte canonique avec la préparation appliquée) · Action<string> Commit (un acte ponctuel — sa propre étape d'annulation) · Action<string> CommitTyping (une rafale de frappes — regroupée par cellule) · Func<string,IReadOnlyList<string>> ReferenceKeys (les mêmes clés candidates qu'offre le sélecteur intégré). Les deux validations passent par la barrière de préparation de la fenêtre (constructeur internal : la fenêtre l'assemble) |
IStudioInspectorAction | interface | Un bouton supplémentaire sur l'inspecteur de nœud. string LabelKey (clé Loc ; non enregistrée = affichée verbatim, vide = nom du type) · bool AppliesTo(StudioInspectorContext) · void Execute(StudioInspectorContext) |
StudioInspectorContext | classe scellée | Lecture : Tab · RecordId · SheetRecord Record · Tables · References · CodeRegistries. Mutation médiée : Action<string,string,string,string> StageCell · Action<IReadOnlyList<EdgeCellWrite>> StageCells, tous deux détaillés sous le tableau. Services : Action<string,int,string> FocusCell · Action RequestRebuild. L'AuthoringSession n'est délibérément pas exposée |
IStudioPanelProvider | interface | Un panneau UIToolkit arbitraire dans le panneau à droite du Studio — l'échappatoire à côté du StudioPanelDescriptor descriptif. string Id · string TitleKey · bool AppliesTo(StudioSurfaceContext) · VisualElement CreatePanel(StudioSurfaceContext) (null ne dessine rien ce tick). Enregistrez un panneau descriptif sous le même Id et chaque hôte prend ce qu'il peut dessiner : l'éditeur préfère celui-ci, le navigateur dessine le descriptif — si bien que « aussi loin que va le navigateur, jusqu'au bout dans l'éditeur » n'a besoin d'aucun second contrat. L'élément vit un tick de recalcul, il ne porte donc aucun état |
StudioPalette | classe statique | Des valeurs de couleur, d'espacement et de type en lecture seule avec lesquelles la fenêtre elle-même peint, afin qu'un widget que vous montez corresponde à la fenêtre au lieu de coder des valeurs hexadécimales en dur. Chaque slot se résout à la lecture, si bien que les widgets suivent gratuitement le mode de luminosité et le préréglage de couleur. Choisir les valeurs (préréglages, luminosité, valeurs par défaut) reste interne — les widgets suivent la palette, ils ne la repeignent pas. La liste des membres est sous le tableau |
StudioTheme | classe statique | Quatre membres seulement : CategoryColor(category) (la même teinte déterministe que la fenêtre donne à cette catégorie) · Np(text) (interpolation sûre dans un libellé rich-text) · Mono / ApplyMono(element) (la politique de police mono : clés, adresses et nombres seulement — les polices mono n'ont pas de glyphes CJK). Tout le reste sur ce type est internal |
StudioKeyPicker | classe statique | Un seul membre : Show(Rect screenAnchor, string targetTab, IReadOnlyList<string> candidates, Action<string> picked, string acceptsLabel = null) — la même liste déroulante qu'ouvre la cellule de référence intégrée, pour un widget de cellule qui doit atteindre une clé à l'intérieur de sa propre notation. Il choisit une seule clé parmi les candidates que vous fournissez et la remet. Créer un enregistrement, laisser la cellule vide, cocher plusieurs éléments d'une liste et demander quel port reçoit le choix sont les propres règles de la cellule de référence intégrée, donc elles ne sont pas sur cette façade. picked est requis (ArgumentNullException avant qu'aucune fenêtre ne soit créée). Sans candidat et rien à offrir, il journalise au lieu d'ouvrir une liste vide. Le type de fenêtre lui-même reste internal |
StudioPluginRegistry | classe statique | Un membre public : InvalidateCache() — abandonne le cache de découverte par rechargement afin qu'une sonde que vos propres tests viennent d'activer soit retrouvée (la même courtoisie que PluginRegistry et SourceProviderRegistry offraient déjà ; celui-ci était le registre resté à l'écart). Les listes découvertes restent internal : rien à l'extérieur ne peut lire ou remplacer ce que la fenêtre montera |
StudioInspectorContext — les deux délégués de préparation :
- StageCell prend l'onglet, l'id d'enregistrement, le champ et le texte brut canonique. La fenêtre enregistre l'étape d'annulation, incrémente la génération de projection et prépare l'adresse logique.
- StageCells fait la même chose pour plusieurs cellules qui doivent changer ensemble : une seule étape d'annulation native, tout ou rien. Si l'une ne peut pas être préparée, la session n'est pas touchée du tout.
Un échec est silencieux à l'écran dans les deux cas, et seule la barrière s'explique elle-même. Une source en lecture seule, un pipeline déjà en cours, ou un onglet d'origine classeur écrit sa raison dans la console. Une liste vide, une écriture sans onglet ni champ, et une clé d'enregistrement qui ne résout aucune ligne ne font rien et ne disent rien.
StudioPalette — les membres :
- 33 slots de couleur :
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.- Espacement :
SectionSpace·RowSpace·RuleHeight·ButtonHeight·PrimaryButtonHeight·GlyphWidth. - Tailles de type :
HeadingFontSize·SectionFontSize·CaptionFontSize. FromRgb(uint)·ToHex(uint).
Approbation du Push (SheetForge.Editor.Push)
| Type | Rôle |
|---|---|
IPushApprover | bool Approve(PushPlan, string humanSummary) · bool ApproveStructureRewrite(string, bool hasLiveConflicts) — rejet = zéro envoi |
AutoPushApprover | Approuve toujours (pour les tests/l'automatisation) |
Moteur de création (SheetForge.Editor.Structure / .Pipeline / .Export)
| Type | Rôle et membres clés |
|---|---|
AuthoringSession | Le propriétaire de l'état préparé (sérialisable — Undo gratuit + survie au rechargement). Edits · IsolatedEdits · NewRows · StructOps · Reorders · TabRenames · EnumMembers (ajouts de membre d'enum préparés) · AssetRegistrations (enregistrements Addressables préparés — au niveau du projet, si bien qu'ils ne prennent aucune part aux barrières par onglet mais comptent pour l'entrée en répercussion, l'abandon et le résumé du diff) · HasAssetRegistrations · StageAssetRegistration(r) (même guid, ou même groupe pour une création de groupe, remplace en place — la dernière intention l'emporte ; un enregistrement sans identité est refusé) · RemoveAssetRegistrationsWhere(predicate) · SetStaged · ResolveBaselineEdits · RemapFieldName/RecordId/Tab · StageTabRename · EffectiveStructOps · PendingStructCount · TabNames · TryGetBaselineTable · LastProjectionResult · ClearAll (efface aussi les enregistrements) |
AuthoringDispatcher | L'orchestrateur de la répercussion. Constructeur (session, callbacks, baselines) · Reflect() · BuildProjectionResult() (requête de projection sans effet de bord) · IReadOnlyDictionary<string,string> BuildProjectedTabs() (la même projection sous forme de TSV par onglet — ce qu'une cible d'écriture en retour est sur le point d'envoyer, prévisualisable sans écrire) · void FinalizeReflectSuccess(IReadOnlyList<string> writtenTabs, IReadOnlyList<TabRenameEntry> committedRenames = null) (la fin qu'une propre écriture en retour d'une source doit atteindre : élagage de rétention pour les onglets qu'elle a écrits, la limite ClearUndo, et le réimport automatique. Les chemins intégrés exécutent le même corps privé, si bien qu'un fournisseur externe se termine exactement comme eux. Une liste vide est un no-op qui garde la préparation intacte) · Session · Callbacks · Baselines |
AuthoringDispatchCallbacks | 13 délégués généraux de préoccupation de vue + IPushApprover — ResolveSettings · RenderReport (Action<ImportReport>, tolérant au null) · TriggerReimport · ConfirmKeyRenames · ConfirmTabRenames (tolérant au null) · ClearUndo · Rebuild · … Les délégués de boîte de dialogue intégrés Local/Google vivent dans l'ensemble optionnel BuiltInSourceDialogs |
BuiltInSourceDialogs | Ensemble optionnel de 14 délégués de boîte de dialogue pour les sources intégrées Local/Google, séparé d'AuthoringDispatchCallbacks — les fournisseurs externes n'en ont jamais besoin. NotifyLocalDone prend cinq arguments ; le dernier est la ligne de résumé d'enregistrement Addressables pour la boîte de dialogue de fin (null quand rien n'était préparé) |
BaselineStore (.Export) | Instantanés de baseline TSV normalisés, par onglet |
Types de valeur de préparation (SheetForge.Editor.Structure; StagedCellEdit/StagedNewRow sont dans SheetForge.Editor.Windows)
| Type | Rôle |
|---|---|
StagedCellEdit (struct) | Une modification préparée — TabName · RowOrdinal · FieldName · RawText · RecordId (clé logique) |
StagedNewRow | Une nouvelle ligne préparée — TabName · FieldNames · CellTexts |
StructureOp | Une opération de structure — Kind · coordonnées · textes · permutation Order |
StructureOpKind (enum) | AddColumn · RemoveColumn · AddMarker · RemoveMarker · RemoveDataRow · ReorderColumns · ReorderDataRows · RenameColumn · EditColumnType · EditColumnDesc · SetColumnOverlap · SetSheetStyle |
TabReorderEntry | L'état de réorganisation par onglet — Tab · ColOrder · RowOrder |
TabRenameEntry (struct) | OldName · NewName |
StagedEnumMember (struct) | Un « ajout de ce membre à cet enum » préparé — TabName (quelle feuille d'enum ; vide = les chercher toutes) · EnumName · Member. Au niveau de la session plutôt qu'un StructureOp, pour la même raison qu'un renommage d'onglet : une feuille d'enum n'a pas de table, pas de schéma et pas de colonne clé, donc l'adresse (onglet, enregistrement, champ) d'une modification de cellule ne peut pas nommer « le prochain membre de cet enum ». Public uniquement parce qu'AuthoringSession.EnumMembers l'est (CS0050) |
StagedAssetRegistration (struct) | Un changement préparé sur les paramètres Addressables du projet, fait en déposant ou en choisissant un asset dans une cellule AssetRef@Group — StagedAssetRegistrationKind Kind · Guid (l'asset ; un sous-asset prépare son parent) · Group · FromGroup (déplacements seulement) · Address (le nom de fichier sans extension pour une nouvelle entrée ; un asset déjà enregistré conserve son adresse) · AssetPath (pour l'affichage). Fabriques Add(guid, group, address, assetPath) · Move(guid, fromGroup, group, address, assetPath) · CreateGroup(group). Exécuté après que l'écriture de la feuille a réussi, puis effacé. Public uniquement parce qu'AuthoringSession.AssetRegistrations l'est (CS0050), comme StagedEnumMember |
StagedAssetRegistrationKind (enum) | Add · Move · CreateGroup |
TabBaselineAnchor (struct) | TabName · Fingerprint · RecordCount |
IsolatedEdit | Une modification dont le réancrage a échoué — Edit · Reason |
IsolationReason (enum) | Renommage externe / suppression externe / conflit de clé |
Assistants de création (SheetForge.Editor.Windows / .Structure)
| Type | Rôle |
|---|---|
KeyRenamePlanner (statique) | Planification du renommage de clé + propagation inter-onglets. Plan(…) · KeyRenamePlan imbriqué · struct associée KeyRename |
RecordIdMinter (statique, pur) | Suggestions d'id. Suggest · DetectCommonPrefix · Uniquify · StagedNewRowKeys |
IntIdMinter (statique, pur) | Suggestion du prochain IntId pour un nouvel enregistrement — Suggest(existingIds) → max + 1. Un axe séparé de RecordIdMinter, qui ne réutilise jamais un trou laissé par une suppression |
ProjectionErrorMapper (statique, pur) | Coordonnée d'erreur → adresse logique. TryMap(…) · LogicalAddress imbriqué |
EphemeralSoApply (statique) | Surcouche de SO à valeurs préparées (temporaire). Apply(…) · InvalidateIndex(…) · Report / SkipReason / SkippedEdit imbriqués |
Assembly Runtime (SheetForge.Runtime)
autoReferenced — utilisable depuis le code de jeu sans référence asmdef.
| Type | Rôle et membres clés |
|---|---|
SheetForgeDatabases (statique) | Le chargeur runtime — le chemin de chargement sanctionné. const AddressPrefix = "SheetForge/" · AddressFor(tab) · LoadAsync(tab) · LoadAsync<TDatabase>(tab) · Release(handle) / Release<TDatabase>(db). Les assistants d'adresse sont de simples chaînes et compilent toujours. LoadAsync et Release n'existent que sous SHEETFORGE_ADDRESSABLES, le define de version activé quand com.unity.addressables est installé — ce qui est ce qui permet au produit de compiler sans le package |
DefinitionDatabase (SO abstraite) | La base de chaque Database générée par onglet. abstract TabName · abstract Count · virtual IReadOnlyList<object> RecordsUntyped · virtual InvalidateIndex(). RecordsUntyped est le moyen sanctionné d'énumérer un onglet baké sans connaître son type généré. Un second baker ou un inspecteur qui parcourt chaque onglet devait auparavant faire de la réflexion sur le champ privé records, ce qui transformait un nom de champ en un contrat non déclaré qui casserait silencieusement le jour où le codegen le renommerait. Traitez la liste comme en lecture seule (la feuille est canonique). Elle vaut vide par défaut, si bien que le code généré d'avant l'existence de ce membre compile et s'exécute toujours. Un réimport émet la substitution |
RecordRef (struct) | La valeur de référence sérialisée à l'intérieur des SO bake (id de type chaîne, résolu à la recherche). Id · IsEmpty |
IntRef (struct) | La valeur de référence sérialisée à clé entière à l'intérieur des SO bake — le jumeau de RecordRef pour les champs IntId@Tab. Comme 0 est un id valide, un bit hasValue soutient IsEmpty. Id · IsEmpty. Le codegen émet un champ IntId@Tab comme IntRef, et TryGet(IntRef) sur la Database générée le consomme |
LocRef (struct) | La référence de localisation sérialisée à l'intérieur des SO bake — une cellule LocRef@Tab. Table (l'onglet de localisation, qui est le nom de la collection StringTable) · Key · long KeyId (0 signifie « pas encore résolu » : le bake d'un import y écrit 0 et le pont y inscrit le véritable id après une synchronisation de tables, si bien qu'une référence survit au renommage d'une clé) · IsEmpty. Elle compile toujours — le code généré et les assets bake ne contiennent jamais un type du package de localisation, ce qui est ce qui garde le package optionnel |
LocRefExtensions (statique) | Un seul membre : LocalizedString ToLocalizedString(this LocRef) — il pointe par KeyId quand celui-ci n'est pas 0, et par nom de clé sinon, et une référence vide se convertit en un LocalizedString vide. Il n'existe que lorsque com.unity.localization est installé, sous le define de version SHEETFORGE_LOCALIZATION — le même arrangement qu'utilise SHEETFORGE_ADDRESSABLES pour la couche Addressables |
SheetForgeRuntimeInfo (statique) | const Version |
Types générés (schéma — par projet, pas une API livrée)
Pour chaque onglet Foo, le codegen émet dans votre 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
}Chargez avec SheetForgeDatabases.LoadAsync<FooDatabase>("Foo").
Les deux classes sont émises en partial, si bien que vous pouvez ajouter des membres dérivés — une propriété calculée, une implémentation d'interface, un opérateur — dans votre propre fichier à côté du fichier généré, et un réimport ne l'écrasera pas.
Une limite : n'ajoutez aucun champ sérialisé dans votre partie. Le ScriptableObject bake est reconstruit à partir de la feuille à chaque import, donc tout ce que seule votre partie sérialise revient à sa valeur par défaut. Si une valeur appartient aux données, elle appartient à une colonne.
(Le mot-clé partial ne touche pas SchemaFingerprint, qui est calculé à partir du seul schéma, donc rendre les classes partial n'a invalidé aucun bake existant.)
Autres assemblies
-
SheetForge.Setup— l'amorçage sans dépendance pour l'absence d'Addressables. Aucune API publique (tout est internal ; il existe pour afficher une fenêtre de guidage). -
SheetForge.PluginDemo(un asmdef fusionné + un asmdef Demo.Editor ; l'espace de noms du contenu resteSheetForge.Skills) — le package d'exemple de référence, pas une API produit. Il contient :SkillsPlugin(sept interfaces de plugin — base, validateur, arête, modèle, graphe, registre de code, thème) ;Modifier+ModifierCellParser(type de cellule personnalisé),ModifierStatEdgeContributor(contributeur d'arêtes) ;ExamplePipelineAugmenter/ExampleReactiveAugmenter(surcharges de canevas),ExampleCodeAtoms(le registre de code_Refs) ;ExampleStudioUi(actions déclaratives, panneau, badge de colonne et indice d'éditeur de cellule),ExampleImportObserver(observateur de pipeline) ;ExampleStageStripWidget/ExampleInspectorAction/ExampleStudioPanel(points d'extension Editor du Data Studio, peints à partir de la palette publique),ExampleLocStrings(enregistre ces libellés en deux langues — dans l'assembly principal, si bien que le navigateur les montre aussi) ;- une déclaration
SheetForgePluginCompatau niveau de l'assembly ; SkillRunner(consommation à l'exécution), typesExample*générés dans l'espace de noms par défautSheetForge.Generated(l'isolation se fait par le préfixeExample*, pas par un espace de noms séparé).
L'exemple sans plugin
SheetForge.CoreDemoest livré avec zéro asmdef (compile dansAssembly-CSharp).
Pages associées
- Création de plugins — les contrats utilisés, avec des exemples complets
- Noyau de création — les types du moteur en contexte
- Capacités et limites — les limites comportementales de ces API