Implement a JSON API friendly notification system

This should bit by bit substitute RsNotify which would be very difficult
  to support properly in JSON API.
The new system is much simpler to use also from the C++ side of the
  moon.
BroadcastDiscovery take advantage of the new system to notify about new
  non friend peer discovered, tested successfully also in JSON API.
This commit is contained in:
Gioacchino Mazzurco 2019-04-15 00:12:29 +02:00
parent 9c7a8d479f
commit 7dab487bde
No known key found for this signature in database
GPG key ID: A1FBCA3872E87051
9 changed files with 503 additions and 84 deletions

View file

@ -30,6 +30,7 @@
#include "util/rstime.h"
#include "util/rsurl.h"
#include "util/rsmemory.h"
#include "retroshare/rsevents.h"
class RsBroadcastDiscovery;
@ -46,6 +47,7 @@ struct RsBroadcastDiscoveryResult : RsSerializable
std::string mProfileName;
RsUrl locator;
/// @see RsSerializable
void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx) override
{
@ -56,11 +58,34 @@ struct RsBroadcastDiscoveryResult : RsSerializable
}
};
struct RsBroadcastDiscoveryPeerFoundEvent : RsEvent
{
RsBroadcastDiscoveryPeerFoundEvent(
const RsBroadcastDiscoveryResult& eventData ) :
RsEvent(RsEventType::BROADCAST_DISCOVERY_PEER_FOUND), mData(eventData) {}
RsBroadcastDiscoveryResult mData;
/// @see RsSerializable
void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx) override
{
RsEvent::serial_process(j, ctx);
RS_SERIAL_PROCESS(mData);
}
~RsBroadcastDiscoveryPeerFoundEvent();
};
/**
* Announce own RetroShare instace and look friends and peers in own broadcast
* domain (aka LAN).
* Emit event @see RsBroadcastDiscoveryPeerFoundEvent when a new peer (not
* friend yet) is found.
*/
class RsBroadcastDiscovery
{
public:
virtual ~RsBroadcastDiscovery();
/**
* @brief Get potential peers that have been discovered up until now
* @jsonapi{development}
@ -68,20 +93,5 @@ public:
*/
virtual std::vector<RsBroadcastDiscoveryResult> getDiscoveredPeers() = 0;
/**
* @brief registerPeersDiscoveredEventHandler
* @jsonapi{development}
* @param multiCallback function that will be called each time a potential
* peer is discovered
* @param[in] maxWait maximum wait time in seconds for discovery results,
* passing std::numeric_limits<rstime_t>::max() means wait forever.
* @param[out] errorMessage Optional storage for error message, meaningful
* only on failure.
* @return false on error, true otherwise
*/
virtual bool registerPeersDiscoveredEventHandler(
const std::function<void (const RsBroadcastDiscoveryResult& result)>&
multiCallback,
rstime_t maxWait = 300,
std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string) ) = 0;
virtual ~RsBroadcastDiscovery();
};

View file

@ -0,0 +1,147 @@
/*******************************************************************************
* Retroshare events service *
* *
* libretroshare: retroshare core library *
* *
* Copyright (C) 2019 Gioacchino Mazzurco <gio@eigenlab.org> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#pragma once
#include <memory>
#include <cstdint>
#include "util/rsmemory.h"
#include "serialiser/rsserializable.h"
#include "serialiser/rstypeserializer.h"
class RsEvents;
/**
* Pointer to global instance of RsEvents service implementation
* @jsonapi{development}
*/
extern std::shared_ptr<RsEvents> rsEvents;
/**
* @brief Events types.
* When creating a new type of event, add a new type here and use that to
* initialize mType in the constructor of your derivative of @see RsEvent
*/
enum class RsEventType : uint32_t
{
NONE = 0, /// Used to detect uninitialized event
BROADCAST_DISCOVERY_PEER_FOUND = 1, /// @see RsBroadcastDiscovery
MAX /// Used to detect invalid event type passed
};
/**
* This struct is not meant to be used directly, you should create events type
* deriving from it.
*/
struct RsEvent : RsSerializable
{
RsEvent() = delete;
RsEvent(RsEventType type) :
mType(type), mTimePoint(std::chrono::system_clock::now()) {}
virtual ~RsEvent();
RsEventType mType;
std::chrono::system_clock::time_point mTimePoint;
/**
* Derived types must call this method at beginning of their implementation
* of serial_process
* @see RsSerializable
*/
virtual void serial_process(RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx)
{
RS_SERIAL_PROCESS(mType);
rstime_t mTime = std::chrono::system_clock::to_time_t(mTimePoint);
RS_SERIAL_PROCESS(mTime);
mTimePoint = std::chrono::system_clock::from_time_t(mTime);
}
};
typedef uint32_t RsEventsHandlerId_t;
class RsEvents
{
public:
/**
* @brief Post event to the event queue.
* @param[in] event
* @param[out] errorMessage Optional storage for error messsage, meaningful
* only on failure.
* @return False on error, true otherwise.
*/
virtual bool postEvent(
std::unique_ptr<RsEvent> event,
std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string)
) = 0;
/**
* @brief Send event directly to handlers. Blocking API
* The handlers get exectuded on the caller thread, ensuring the function
* returns only after the event has been handled.
* @param[in] event
* @param[out] errorMessage Optional storage for error messsage, meaningful
* only on failure.
* @return False on error, true otherwise.
*/
virtual bool sendEvent(
const RsEvent& event,
std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string)
) = 0;
/**
* @brief Generate unique handler identifier
* @return generate Id
*/
virtual RsEventsHandlerId_t generateUniqueHandlerId() = 0;
/**
* @brief Register events handler
* Every time an event is dispatced the registered events handlers will get
* their method handleEvent called with the event passed as paramether.
* @jsonapi{development,manualwrapper}
* @param multiCallback Function that will be called each time an event
* is dispatched.
* @param[inout] hId Optional storage for handler id, useful to
* eventually unregister the handler later. The
* value may be provided to the function call but
* must habe been generated with
* @see generateUniqueHandlerId()
* @return False on error, true otherwise.
*/
virtual bool registerEventsHandler(
std::function<void(const RsEvent&)> multiCallback,
RsEventsHandlerId_t& hId = RS_DEFAULT_STORAGE_PARAM(RsEventsHandlerId_t, 0)
) = 0;
/**
* @brief Unregister event handler
* @param[in] hId Id of the event handler to unregister
* @return True if the handler id has been found, false otherwise.
*/
virtual bool unregisterEventsHandler(RsEventsHandlerId_t hId) = 0;
virtual ~RsEvents();
};