Skip to content

file platform/flake/Object.h

Namespaces

Name
flake

Namespaces

Name
flake

Types

Name
classflake::Indication
Represents an incoming indication (server → client notification).
classflake::Confirmation
Represents the reply (confirmation) to a previously sent request.
classflake::IndicationSink
Callback interface for receiving Indication messages.
classflake::ConfirmationSink
Callback interface for receiving Confirmation messages.
classflake::ConnectedObject
An object that is connected to the Flake bus and has an address.
classflake::Stream
Byte-oriented read/write stream associated with an Object property.
classflake::Object
Client-side proxy for a Flake object.
classflake::ObjectDelegate
Interface to be implemented by the application to expose a custom Flake object.

Defines

Name
EMPTY_ADDRSentinel address value indicating "no address".
TYPE_UUID_SERVICEUUID string that identifies the built-in service-discovery object type.
MAX_OBJECT_POOLMaximum number of ObjectImpl instances in the static pool.

Macros Documentation

define EMPTY_ADDR

cpp
#define EMPTY_ADDR UINT16_C(0xFFFFU)

Sentinel address value indicating "no address".

define TYPE_UUID_SERVICE

cpp
#define TYPE_UUID_SERVICE "00000000-0000-0000-0000-000000000000"

UUID string that identifies the built-in service-discovery object type.

define MAX_OBJECT_POOL

cpp
#define MAX_OBJECT_POOL (4UL)

Maximum number of ObjectImpl instances in the static pool.

Source code

cpp
/*******************************************************************************
 * @file      Object.h
 * @brief     Core object model: Indication, Confirmation, Object, Stream
 *            and their associated sink / delegate interfaces.
 * @details   In the Flake architecture every addressable entity is an Object.
 *            Objects have typed properties, can be subscribed to, and
 *            communicate via Indications (server → client) and Confirmations
 *            (client → server reply).
 *
 *            This header is part of the **public API**.  Implementers use
 *            ObjectDelegate to expose custom objects, and consumers use
 *            Object to interact with remote instances.
 *
 * @license   This file is part of the ImagineOn Flake software package
 *            licensed under the ImagineOn software-licensing terms available
 *            under https://www.imagineon.de/de/info/licensing-terms
 * @copyright Copyright (c) 2025 ImagineOn GmbH. www.imagineon.de.
 ******************************************************************************/

#ifndef FLAKE_OBJECT_H_
#define FLAKE_OBJECT_H_

#include "FlakeTypes.h"
#include <functional>

#define EMPTY_ADDR UINT16_C(0xFFFFU)

#define TYPE_UUID_SERVICE "00000000-0000-0000-0000-000000000000"

#define MAX_OBJECT_POOL (4UL)

namespace flake
{
    class Table;
    class ObjectImpl;

    /* ===================================================================
     *  Indication
     * =================================================================== */

    class Indication
    {
        Indication(const Indication&) = delete;
        Indication& operator=(const Indication&) = delete;
        Indication(Indication&&) = delete;
        Indication& operator=(Indication&&) = delete;

    public:
        Indication() = default;
        virtual ~Indication() noexcept = default;

        virtual uint8_t
        type() const = 0;

        virtual addr_t
        source() const = 0;

        virtual addr_t
        destination() const = 0;

        virtual const PropArray&
        getData() const = 0;

        virtual void
        ack(int8_t result, const PropArray& va = PropArray()) const = 0;

        virtual bool
        acknowledged() const = 0;
    };

    typedef uint16_t Token;

    /* ===================================================================
     *  Confirmation
     * =================================================================== */

    class Confirmation
    {
        Confirmation(const Confirmation&) = delete;
        Confirmation& operator=(const Confirmation&) = delete;
        Confirmation(Confirmation&&) = delete;
        Confirmation& operator=(Confirmation&&) = delete;

    public:
        Confirmation() = default;
        virtual ~Confirmation() noexcept = default;

        virtual uint8_t
        type() const = 0;

        virtual addr_t
        source() const = 0;

        virtual addr_t
        destination() const = 0;

        virtual const PropArray&
        getData() const = 0;

        virtual int8_t
        result() const = 0;

        virtual Token
        token() const = 0;
    };

    /* ===================================================================
     *  Sink Interfaces
     * =================================================================== */

    class IndicationSink
    {
        IndicationSink(const IndicationSink&) = delete;
        IndicationSink& operator=(const IndicationSink&) = delete;
        IndicationSink(IndicationSink&&) = delete;
        IndicationSink& operator=(IndicationSink&&) = delete;

    protected:
        IndicationSink() = default;
        ~IndicationSink() = default;

    public:
        virtual void
        onIndication(const Indication& indication) = 0;
    };

    class ConfirmationSink
    {
        ConfirmationSink(const ConfirmationSink&) = delete;
        ConfirmationSink& operator=(const ConfirmationSink&) = delete;
        ConfirmationSink(ConfirmationSink&&) = delete;
        ConfirmationSink& operator=(ConfirmationSink&&) = delete;

    protected:
        ConfirmationSink() = default;
        ~ConfirmationSink() = default;

    public:
        virtual void
        onConfirmation(const Confirmation& confirmation) = 0;
    };

    /* ===================================================================
     *  ConnectedObject
     * =================================================================== */

    class ConnectedObject : public IndicationSink, public ConfirmationSink
    {
        ConnectedObject(const ConnectedObject&) = delete;
        ConnectedObject& operator=(const ConnectedObject&) = delete;
        ConnectedObject(ConnectedObject&&) = delete;
        ConnectedObject& operator=(ConnectedObject&&) = delete;

    protected:
        ConnectedObject() = default;
        ~ConnectedObject() noexcept = default;

    public:

        virtual addr_t addr() const = 0;

        virtual addr_t broadcastAddr() const = 0;

        virtual addr_t parentAddr() const = 0;

    };

    /* ===================================================================
     *  Stream
     * =================================================================== */

    class Stream
    {
        Stream(const Stream&) = delete;
        Stream& operator=(const Stream&) = delete;
        Stream(Stream&&) = delete;
        Stream& operator=(Stream&&) = delete;

    protected:
        Stream() = default;
        ~Stream() noexcept = default;

    public:
        constexpr static uint8_t FLAG_LIVE = 0x01U;

        virtual int write(uint8_t data[], unsigned int len) = 0;

        virtual int read(uint8_t* data, unsigned int* len, unsigned int max_len) = 0;

        virtual int seek(unsigned int pos) = 0;

        virtual unsigned int pos() = 0;

        virtual int close() = 0;

        virtual uint32_t streamId() = 0;

    };

    /* ===================================================================
     *  Object (client-side proxy)
     * =================================================================== */

    class Object
    {
        friend class ConnectionImpl;

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

    protected:
        Object() = default;
        ~Object() noexcept = default;

        virtual ObjectImpl* impl() = 0;

    public:
        virtual int
        registered() = 0;

        virtual int
        invoke(const std::string& command, PropArray& params,
               bool blocking, PropArray& reply) = 0;

        virtual int
        broadcast(const std::string& command, PropArray& params) = 0;

        virtual int
        getProperties(PropArray& properties) = 0;

        virtual int
        setProperties(PropArray& properties) = 0;

        virtual int
        setProperty(const Property& property) = 0;

        virtual void
        getProperty(Property& property) = 0;

        virtual int
        openProperty(const uint32_t propTag, Stream** stream) = 0;

        virtual int
        subscribe(std::function<void (const Indication&)> f) = 0;   //NOLINT: MISRA 7-3-1 not detected right

        virtual void
        unsubscribe() = 0;

        virtual int
        sync(unsigned timeout_ms, bool block) = 0;

        virtual void
        defer() = 0;

        virtual int
        syncDeferred(unsigned timeout_ms, bool block) = 0;

        virtual bool
        hasDeferred() = 0;

        virtual void
        clear() = 0;

        virtual void
        ref() = 0;

        virtual void
        unref() = 0;

    };

    /* ===================================================================
     *  ObjectDelegate (server-side implementation interface)
     * =================================================================== */

    class ObjectDelegate
    {
        ObjectDelegate(const ObjectDelegate&) = delete;
        ObjectDelegate& operator=(const ObjectDelegate&) = delete;
        ObjectDelegate(ObjectDelegate&&) = delete;
        ObjectDelegate& operator=(ObjectDelegate&&) = delete;
    protected:
        ObjectDelegate() = default;
    public:

        virtual ~ObjectDelegate() = default;

        virtual Object* handle() = 0;

        virtual int8_t
        handleCustomMessage(std::string name, const PropArray& data, PropArray& outProps) = 0;

        virtual int8_t
        handleStreamOpen(Stream* s) = 0;

        virtual int8_t
        handleStreamClose(Stream* s) = 0;

        virtual int8_t
        handleStreamWrite(Stream* s, uint8_t* cb, uint16_t len) = 0;

        virtual int8_t
        handleStreamRead(Stream* s, uint8_t* cb, uint16_t* len, uint16_t max_len) = 0;

        virtual int
        setPropertyRequested(uint32_t tag, Property& value, const PropArray& transaction, bool internal) = 0;

        virtual int
        getPropertyRequested(uint32_t tag, Property& value) = 0;

        virtual void
        propertyChanged(const Property&) = 0;

        virtual void
        onInitialized() = 0;
    };
}

#endif /* FLAKE_OBJECT_H */