//
// .NAME:
//  MvCallback
//
// .AUTHOR:
//  Gilberto Camara, Baudoin Raoult and Fernando Ii
//     ECMWF, December 1997
//
// .SUMMARY:
//  Describes the MvCallback class, a generic class
//  for handling METVIEW-type callbacks (which involve
//  requests)
//
//
// .CLIENTS:
//  GenAppService, MacroService
//
// .RESPONSABILITY:
//  This class will provide support for the handling
//  of callbacks associated to Metview requests
//
//  Each new object of this class will, on its constructor:
//  - store a copy of an object and a procedure to be called
//    when the "ExecuteCallback" method is used
//
//
// .COLLABORATORS:
//
//
// .ASCENDENT:
//
//
// .DESCENDENT:
//
//
// .REFERENCES:
//
//  The ideas of template callbacks implemented here is described
//  in the article "Callbacks in C++ Using Template Functors",
//  included in the "C++ Gems" book.
//  (see also the "XtCallback" class)


#pragma once

class MvRequest;

class MvCallbackBase
{
public:
    MvCallbackBase() = default;

    virtual ~MvCallbackBase() = default;

    virtual void ExecuteCallback(MvRequest&) = 0;
};


template <class T>
class MvCallback : public MvCallbackBase
{
    using Procedure = void (T::*)(MvRequest&);
    T& calledObject_;
    Procedure calledProc_;

public:
    // -- Constructors

    MvCallback<T>(T& object, Procedure proc) :
        calledObject_(object),
        calledProc_(proc) {}

    // -- Destructor
    ~MvCallback() override = default;

    // -- Methods

    // Perform a METVIEW-style callback
    void ExecuteCallback(MvRequest& replyRequest) override
    {
        (calledObject_.*calledProc_)(replyRequest);
    }
};
