API — ICoreSDK/ICoreBlockLibrary
The public contract of 3 header(s) under src/ICoreSDK/ICoreBlockLibrary — 3 class/struct definition(s), 20 declaration(s). Each section shows the header's banner and its public (and protected-virtual) surface exactly as the file writes it.
| Header | Defines | Declarations | Bases |
|---|---|---|---|
ICoreUserBlockDefinition.h | ICoreUserBlockDefinition | 7 | — |
ICoreUserBlockLibrary.h | ICoreUserBlockLibrary | 13 | — |
ICoreUserBlockMaterializer.h | ICoreUserBlockMaterializer | 0 | — |
ICoreUserBlockDefinition.h#
src/ICoreSDK/ICoreBlockLibrary/UserBlocks/ICoreUserBlockDefinition.h
ICoreUserBlockDefinition#
ICoreUserBlockDefinition.h:33 · class · 7 declaration(s)
One parsed .iblock file — a USER-DEFINED block definition, the unit the Block Wizard writes and the user block library (ICoreUserBlockLibrary) scans.
class ICoreUserBlockDefinition {
public:
enum class Kind {
Composite, // body = recipe text (ICoreRecipeSerializer output)
Python // body = Python source with a compute(t, u, state)
};
// ---- identity ---------------------------------------------------------
ICoreString uuid; // v4; identity across renames — never regenerate on edit
ICoreString name; // leaf segment, identifier-safe [A-Za-z0-9_]
ICoreString family; // middle segment, identifier-safe
ICoreString summary; // one line, shown by the navigator entry
ICoreString created; // "YYYY-MM-DD"; informational, not validated
ICoreString modified;
Kind kind = Kind::Composite;
// ---- ports ------------------------------------------------------------
// Counts are what the navigator preview draws (the analogue of
// registerInitialPorts). Labels are empty or exactly count-sized; a side
// with 2+ ports MUST carry labels — same rule as ADDING_NEW_BLOCKS.md §3,
// and validate() enforces it. Labels may not contain commas (they are
// comma-separated in the header).
int inputCount = 0;
int outputCount = 0;
ICoreStringList inputLabels;
ICoreStringList outputLabels;
// ---- payloads ---------------------------------------------------------
ICoreString iconSvg; // may be empty: navigator falls back to a monogram
ICoreString descriptionHtml; // may be empty: hover card shows the summary
ICoreString body; // must be non-empty for Kind::Python
// ---- file text <-> definition -----------------------------------------
// False leaves `err` explaining which line or section refused, in words a
// user can act on ("line 4: ...", "missing section ...ICON...").
// `out` is reset first and is only trustworthy when parse returns true.
static bool parse(const ICoreString& fileText, ICoreUserBlockDefinition& out,
ICoreString& err);
// The exact text parse() accepts. Assumes validate() passed — serialize
// does not re-check.
ICoreString serialize() const;
// The rules a definition must satisfy before it is written or listed:
// uuid present, identifier-safe name/family, non-negative counts, label
// count/mandatory-label rules, non-empty Python body. parse() runs this
// last, so a parsed definition is always a valid one.
bool validate(ICoreString& err) const;
// ---- naming -----------------------------------------------------------
// "My_Blocks/<family>/<name>" — the navigator address. A pseudo-type: it
// is never registered anywhere, and the grand family is reserved for us
// (USER_BLOCK_WIZARD.md §8).
ICoreString pseudoType() const;
static const char* grandFamily();
// ---- helpers ----------------------------------------------------------
static bool isIdentifierSafe(const ICoreString& s); // non-empty, [A-Za-z0-9_]
static ICoreString generateUuid(); // random v4, lowercase
static ICoreString kindName(Kind kind); // "composite" / "python"
static bool kindFromName(const ICoreString& text, Kind& out);
static constexpr int formatMajorVersion = 1;
bool operator==(const ICoreUserBlockDefinition& other) const;
bool operator!=(const ICoreUserBlockDefinition& other) const;
};
};
ICoreUserBlockLibrary.h#
src/ICoreSDK/ICoreBlockLibrary/UserBlocks/ICoreUserBlockLibrary.h
ICoreUserBlockLibrary#
ICoreUserBlockLibrary.h:37 · class · nested SkippedFile · 13 declaration(s)
The user's per-app library of .iblock definitions: one folder tree under the application home, scanned off disk, never cached across calls.
class ICoreUserBlockLibrary {
public:
// One unreadable file from the last scan, and why. The navigator's manage
// dialog lists these — a silently absent block reads as "the app lost my
// work", which is worse than any error message.
struct SkippedFile {
ICoreString path;
ICoreString reason;
};
// Every definition on disk right now, family folders in name order, files
// in name order inside each. Rescans on every call (the set is small, and
// a cache would go stale the moment a user drops a file in with the app
// running — the same reasoning as ICoreTemplateLibrary::all()).
static ICoreList<ICoreUserBlockDefinition> all();
// What the most recent scan could not read. Refreshed by all() and by the
// mutating calls below (each rescans to validate its inputs).
static ICoreList<SkippedFile> skippedInLastScan();
// Lookups over a fresh scan. False leaves `out` untouched.
static bool findByUuid(const ICoreString& uuid, ICoreUserBlockDefinition& out);
static bool findByPseudoType(const ICoreString& pseudoType, ICoreUserBlockDefinition& out);
// Family folder names (sorted, may include empty families) — the wizard's
// family combo lists these.
static ICoreStringList families();
// Write `def` into the library at pathFor(def). Collisions:
// * target file exists with the SAME uuid -> update in place;
// * target file exists with a DIFFERENT uuid -> refused unless
// `overwrite` (the wizard asks the user first);
// * same uuid already lives at a DIFFERENT path -> treated as a
// rename/move: the old file is removed after the new one is written.
// False leaves `err` filled and the library unchanged.
static bool save(const ICoreUserBlockDefinition& def, bool overwrite, ICoreString& err);
// Bring an external .iblock into the library: parse + validate `source`,
// then save() it where its own header says it belongs. `imported` receives
// the definition on success (the caller wants the name for its "Imported
// <block>" message). The source file is never modified.
static bool importFile(const std::filesystem::path& source, bool overwrite,
ICoreUserBlockDefinition& imported, ICoreString& err);
// Copy the block's library file to `destination`, byte for byte. Refuses
// to overwrite an existing destination — the caller's file dialog owns
// that conversation.
static bool exportTo(const ICoreString& uuid, const std::filesystem::path& destination,
ICoreString& err);
// Delete the block's file; prunes its family folder if that leaves it
// empty. False when no such uuid or the delete failed.
static bool remove(const ICoreString& uuid, ICoreString& err);
// "<application home>/Blocks". Created on first look, like the user
// templates folder, so there is always somewhere to drop a file.
static std::filesystem::path userBlocksFolderPath();
// TEST SEAM. The regression sandbox repoints the DOCUMENTS folder but the
// application home is deliberately assigned once and never moves — so a
// sandboxed case points this library at a scratch tree instead. An empty
// path restores the real app home. Never called outside the test suite.
static void setRootOverrideForTests(const std::filesystem::path& root);
// "<root>/<family>/<name>.iblock" for this definition.
static std::filesystem::path pathFor(const ICoreUserBlockDefinition& def);
// Change notification, toolkit-free: save/import/remove fire every
// subscriber after the library has changed on disk. The navigator's
// rebuild hangs off this. Subscribers run on the caller's thread.
static int subscribeToChanges(std::function<void()> onChanged);
static void unsubscribeFromChanges(int token);
// The drag-and-drop format a user-block navigator entry carries and the
// canvas accepts; the payload is a definition's uuid. Declared here next
// to the uuids it quotes, for the same no-drift reason as
// ICoreTemplateLibrary::dragMimeType().
static const char* dragMimeType();
};
};
ICoreUserBlockMaterializer.h#
src/ICoreSDK/ICoreBlockLibrary/UserBlocks/ICoreUserBlockMaterializer.h
ICoreUserBlockMaterializer#
ICoreUserBlockMaterializer.h:33 · class · 0 declaration(s)
Stamps a user block definition into a live diagram (USER_BLOCK_WIZARD.md §7).
class ICoreUserBlockMaterializer {
public:
// Stamp `def` into `parent` at `position` (origin-anchor coordinates,
// +y up, exactly like move()). `createdName` receives the name the
// instance actually got — a sibling clash gets a numbered name instead.
static ICoreRecipeFileTransfer::Result stamp(ICoreSubsystemTreeNode* parent,
const ICoreUserBlockDefinition& def,
const ICorePoint& position,
ICoreString* createdName = nullptr);
// The drop handler's form: resolve `uuid` in ICoreUserBlockLibrary, then
// stamp. Fails with a user-readable reason when the uuid is not in the
// library (e.g. the file was deleted while the navigator still showed it).
static ICoreRecipeFileTransfer::Result stampByUuid(ICoreSubsystemTreeNode* parent,
const ICoreString& uuid,
const ICorePoint& position,
ICoreString* createdName = nullptr);
};
};