Skip to content

File NodeCallback.h

File List > include > SpinGenApi > NodeCallback.h

Go to the documentation of this file

//=============================================================================
// Copyright (c) 2026 FLIR Integrated Imaging Solutions, Inc. All Rights Reserved.
//
// This software is the confidential and proprietary information of FLIR
// Integrated Imaging Solutions, Inc. ("Confidential Information"). You
// shall not disclose such Confidential Information and shall use it only in
// accordance with the terms of the license agreement you entered into
// with FLIR Integrated Imaging Solutions, Inc. (FLIR).
//
// FLIR MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
// SOFTWARE, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE, OR NON-INFRINGEMENT. FLIR SHALL NOT BE LIABLE FOR ANY DAMAGES
// SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
// THIS SOFTWARE OR ITS DERIVATIVES.
//=============================================================================

#ifndef SPINNAKER_GENAPI_NODECALLBACK_H
#define SPINNAKER_GENAPI_NODECALLBACK_H
#include "INode.h"
#include "../Exception.h"

namespace Spinnaker
{
    namespace GenApi
    {
        typedef enum _ECallbackType
        {
            cbPostInsideLock = 1, 
            cbPostOutsideLock = 2 
        } ECallbackType;

        class CNodeCallback
        {
          public:
            CNodeCallback(INode* pNode, ECallbackType CallbackType) : m_pNode(pNode), m_CallbackType(CallbackType)
            {
            }

            virtual ~CNodeCallback(){};

            virtual void operator()(ECallbackType CallbackType) const = 0;

            virtual void Destroy() = 0;

            INode* GetNode()
            {
                return m_pNode;
            }

            ECallbackType GetCallbackType()
            {
                return m_CallbackType;
            }

          protected:
            INode* m_pNode;

            ECallbackType m_CallbackType;
        };

        /***************************************************************************/
        // C Functions as callbacks
        /***************************************************************************/

        template <class Function> class Function_NodeCallback : public CNodeCallback
        {
          public:
            Function_NodeCallback(
                INode* pNode,
                const Function& function,
                ECallbackType CallbackType,
                bool fireOnValueChangedOnly = false)
                : CNodeCallback(pNode, CallbackType), m_pFunction(function),
                  m_fireOnValueChangedOnly(fireOnValueChangedOnly)
            {
            }

            virtual void operator()(ECallbackType CallbackType) const
            {
                if (m_pFunction && m_CallbackType == CallbackType)
                {
                    if (!m_fireOnValueChangedOnly)
                    {
                        m_pFunction(m_pNode);
                    }
                    else
                    {
                        try
                        {
                            CValuePtr valuePtr = m_pNode;
                            if (valuePtr->IsValueUpdated())
                            {
                                m_pFunction(m_pNode);
                            }
                        }
                        catch (...)
                        {
                            throw Spinnaker::Exception(
                                __LINE__,
                                __FILE__,
                                __FUNCTION__,
                                "Unable to trigger node callback.",
                                SPINNAKER_ERR_ERROR);
                        }
                    }
                }
            }

            virtual void Destroy()
            {
                delete this;
            }

          private:
            const Function m_pFunction;

            const bool m_fireOnValueChangedOnly;

            Function_NodeCallback& operator=(Function_NodeCallback&) = delete;
        };

        template <class Function>
        CNodeCallback* make_NodeCallback(
            INode* pNode,
            Function function,
            ECallbackType CallbackType,
            bool fireOnValueChangedOnly = false)
        {
            return static_cast<CNodeCallback*>(
                new Function_NodeCallback<Function>(pNode, function, CallbackType, fireOnValueChangedOnly));
        }

        template <class Function>
        intptr_t Register(
            INode* pNode,
            Function f,
            ECallbackType CallbackType = cbPostInsideLock,
            bool fireOnValueChangedOnly = false)
        {
            CNodeCallback* pCallback(make_NodeCallback(pNode, f, CallbackType, fireOnValueChangedOnly));
            return pNode->RegisterCallback(pCallback);
        }

        /***************************************************************************/
        // C++ Member functions as callbacks
        /***************************************************************************/

        template <class Client, class Member> class Member_NodeCallback : public CNodeCallback
        {
          public:
            typedef void (Client::*PMEMBERFUNC)(INode*);

            Member_NodeCallback(INode* pNode, Client& client, Member member, ECallbackType CallbackType)
                : CNodeCallback(pNode, CallbackType), m_Client(client), m_pMemberFunc(member)
            {
            }

            virtual void operator()(ECallbackType CallbackType) const
            {
                if (m_pMemberFunc && m_CallbackType == CallbackType)
                    (m_Client.*m_pMemberFunc)(m_pNode);
            }

            virtual void Destroy()
            {
                delete this;
            }

          private:
            Client& m_Client;

            PMEMBERFUNC m_pMemberFunc;

            Member_NodeCallback& operator=(Member_NodeCallback&) = delete;
        };

        template <class Client, class Member>
        CNodeCallback* make_NodeCallback(INode* pNode, Client& client, Member member, ECallbackType CallbackType)
        {
            return static_cast<CNodeCallback*>(
                new Member_NodeCallback<Client, Member>(pNode, client, member, CallbackType));
        }

        template <class Client, class Member>
        intptr_t Register(INode* pNode, Client& c, Member m, ECallbackType CallbackType = cbPostInsideLock)
        {
            CNodeCallback* pCallback(make_NodeCallback(pNode, c, m, CallbackType));
            return pNode->RegisterCallback(pCallback);
        }

        // definition in Node.cpp
        SPINNAKER_API void Deregister(GenApi::CallbackHandleType pCallbackInfo);

    } // namespace GenApi
} // namespace Spinnaker

#endif // SPINNAKER_GENAPI_NODECALLBACK_H