Generated reference › API — include/icore
kind: generated#api#include-icore

API — include/icore

The public contract of 2 header(s) under include/icore — 2 class/struct definition(s), 23 declaration(s). Each section shows the header's banner and its public (and protected-virtual) surface exactly as the file writes it.

HeaderDefinesDeclarationsBases
Application.hApplication13
EditorWindow.hEditorWindow10

Application.h#

include/icore/Application.h

Application.h -- the ICoreBlocks SDK entry point.

icore::Application is a LIFETIME SCOPE, not a GUI-toolkit application object. It owns the event loop and it is the only factory for editor windows. Nothing else in the public surface can bring an editor window into being.

This header is part of include/icore/, which is toolkit-free by contract: the widget toolkit currently backing the implementation is scheduled for removal, so no type belonging to it may appear here -- not in a signature, not in a base class, not behind a "native handle" accessor. Everything the implementation needs lives behind Impl, which is declared here and defined only in the corresponding translation unit under src/.

Application#

Application.h:51 · class · pImpl · 13 declaration(s)

/ The process-wide lifetime scope for an ICoreBlocks session.

class Application {
public:
    /// Opens the session.
    ///
    /// @param argc  argument count, exactly as received by `main`.
    /// @param argv  argument vector, exactly as received by `main`.
    ///
    /// Both are consumed by reference internally and may be inspected or
    /// rewritten (recognised platform switches are removed). The storage
    /// they point at must outlive the Application -- passing `main`'s own
    /// argc/argv satisfies this; passing a local copy that goes out of
    /// scope does not.
    Application(int argc, char** argv);

    /// Closes the session and tears down the event loop.
    ///
    /// @pre Every EditorWindow created by this Application has already been
    ///      destroyed.
    ~Application();

    Application(const Application&) = delete;
    Application& operator=(const Application&) = delete;
    Application(Application&&) = delete;
    Application& operator=(Application&&) = delete;

    /// Creates a new editor window, owned by the caller.
    ///
    /// The window is created hidden; call EditorWindow::show() to put it on
    /// screen. This is the only way to obtain an EditorWindow -- its
    /// constructor is private and this class is its only friend.
    ///
    /// @return A handle to the new window. Never null; failure to create
    ///         the window throws rather than returning a null handle.
    /// @note   The returned window must not outlive this Application.
    [[nodiscard]] std::unique_ptr<EditorWindow> createEditorWindow();

    /// Runs the session to completion and returns the exit code `main` should
    /// return.
    ///
    /// A convenience only, and deliberately a thin one -- it is exactly
    /// `while (isRunning()) tick(); return exitCode();`. The loop below is the
    /// primitive; this is the two-line spelling of it for callers that have no
    /// work of their own to interleave.
    ///
    /// Blocks. Call once, from the thread that constructed the Application.
    int run();

    // --- the loop -----------------------------------------------------------
    //
    // THE CALLER OWNS THE LOOP. These three are what make that true: the
    // Application never blocks in a toolkit loop it controls, it advances one
    // slice at a time when asked, and it reports whether it should be asked
    // again. That is the whole inversion -- the UI toolkit is something this
    // process drives, not something this process is handed to.
    //
    // It is also what lets a host with its own clock -- a simulation stepper, a
    // frame loop, an embedder that already owns main() -- run an ICoreBlocks
    // editor without surrendering control of the process to it:
    //
    // @code
    // while (app.isRunning()) {
    //     app.tick();          // the UI gets a slice
    //     myScheduler.step();  // ...and so does everything else
    // }
    // return app.exitCode();
    // @endcode

    /// Advances the session by one slice: dispatches whatever UI and platform
    /// events are pending, then returns.
    ///
    /// @param waitMs  How long to wait for an event when none is pending, in
    ///                milliseconds. The default idles rather than spins, which
    ///                is what an editor wants -- an idle window costs no CPU.
    ///                Pass 0 for a non-blocking poll, which is what a caller
    ///                with its own frame budget wants instead.
    ///
    /// Call from the thread that constructed the Application.
    void tick(int waitMs = 16);

    /// Whether the session is still live -- i.e. whether to call tick() again.
    ///
    /// Becomes false once requestQuit() has been called, or once the last
    /// window has closed.
    [[nodiscard]] bool isRunning() const noexcept;

    /// Ends the session: isRunning() becomes false and the next tick() is the
    /// caller's last.
    ///
    /// Does not tear anything down by itself and does not return through the
    /// caller's loop early -- it sets the intent, and the loop the caller wrote
    /// is what observes it. Safe to call more than once; the first code wins,
    /// so a shutdown already under way is not relabelled by a later caller.
    void requestQuit(int exitCode = 0);

    /// The code passed to requestQuit(), or 0 if the session ended on its own.
    ///
    /// Meaningful once isRunning() is false.
    [[nodiscard]] int exitCode() const noexcept;

    /// The live Application, or null when this process has none.
    ///
    /// For code deep inside the implementation that has to end the session and
    /// has no path back to the object -- see ICoreStudioRegistry. Nullable on
    /// purpose: an embedder, or a test binary, may run parts of this codebase
    /// with no Application in scope at all, and such a caller needs to be able
    /// to ask without asserting.
    [[nodiscard]] static Application* liveInstance() noexcept;

private:
    class Impl;                    // the two-line residue; state lives here
    std::unique_ptr<Impl> impl;
};

EditorWindow.h#

include/icore/EditorWindow.h

EditorWindow.h -- a top-level ICoreBlocks editor window.

An EditorWindow is created only by icore::Application::createEditorWindow(). The constructor is private and Application is the sole friend, so a window cannot exist outside the lifetime scope that owns the event loop it needs.

This header is part of include/icore/, which is toolkit-free by contract. The widget toolkit currently backing the implementation is scheduled for removal, so none of its types appear here -- text crossing this boundary is UTF-8 std::string / std::string_view, and the widget itself stays behind Impl, declared here and defined only under src/.

See DEVELOPER_GUIDELINES.md.

EditorWindow#

EditorWindow.h:39 · class · pImpl · 10 declaration(s)

/ A top-level editor window.

class EditorWindow {
public:
    /// Closes the window and destroys it.
    ~EditorWindow();

    EditorWindow(const EditorWindow&) = delete;
    EditorWindow& operator=(const EditorWindow&) = delete;
    EditorWindow(EditorWindow&&) = delete;
    EditorWindow& operator=(EditorWindow&&) = delete;

    /// Sets the window title.
    ///
    /// @param title  UTF-8 text. Copied; the view need not outlive the call
    ///               and need not be null-terminated.
    void setTitle(std::string_view title);

    /// Puts the window on screen.
    ///
    /// Windows are created hidden, so this is what makes a newly created
    /// window visible. Calling it on an already-visible window raises and
    /// focuses it instead.
    void show();

    /// Closes the window, exactly as closing it from the window system does.
    ///
    /// Does NOT destroy it -- the handle still owns the window and show() puts
    /// it back on screen. Destroying the handle is what destroys the window.
    ///
    /// @note Closing the last open window of an Application ends that
    ///       Application's session, so run() returns after this.
    void close();

    /// Opens a project folder in this window.
    ///
    /// Takes the same path every other project switch in the editor takes, so
    /// it may raise the prompts that path raises -- save-before-switch, or
    /// "not a project folder" -- parented on this window.
    ///
    /// @param utf8Path  Absolute path to the project folder, UTF-8. Copied.
    /// @return true when this window is showing that project afterwards --
    ///         including when it already was. false when the switch was
    ///         cancelled or failed.
    [[nodiscard]] bool openProject(std::string_view utf8Path);

    /// Installs a handler to run when this window is closing.
    ///
    /// Fires for a close from the window system and for close() alike, while
    /// the window is still up. std::function rather than any toolkit's signal,
    /// which is what lets this cross the SDK boundary at all.
    ///
    /// One handler, replaced rather than accumulated -- pass an empty
    /// std::function to clear it. Installing one does not disturb the
    /// Application's own end-of-session bookkeeping; that is tracked
    /// separately and cannot be displaced from here.
    void onCloseRequested(std::function<void()> fn);

private:
    class Impl;                    // the two-line residue; state lives here
    std::unique_ptr<Impl> impl;
};