[DOC] write 80% of the documentation

This commit is contained in:
Edouard DUPIN 2017-06-13 13:27:52 +02:00
parent 56072e960e
commit a57925d535
22 changed files with 608 additions and 338 deletions

View File

@ -119,12 +119,14 @@ static int32_t nextP2(int32_t _value) {
} }
void appl::MessageElementVideo::setSize(const ivec2& _size) { void appl::MessageElementVideo::setSize(const ivec2& _size) {
if (m_imagerealSize != _size) { if (m_imageRealSize != _size) {
// Resize the buffer: // Resize the buffer:
m_imagerealSize = _size; m_imageRealSize = _size;
m_image.resize(ivec2(nextP2(_size.x()), nextP2(_size.y()))); m_imagePow2Size = ivec2(nextP2(_size.x()), nextP2(_size.y()));
m_lineSize = m_image.getSize().x() * 3; // 3 is for RGBA m_lineSize = m_imagePow2Size.x() * 3;
//m_image.getSize(); }
if (m_image.getSize() != m_imagePow2Size) {
m_image.resize(m_imagePow2Size);
} }
} }
void appl::MessageElementAudio::configure(audio::format _format, uint32_t _sampleRate, int32_t _nbChannel, int32_t _nbSample) { void appl::MessageElementAudio::configure(audio::format _format, uint32_t _sampleRate, int32_t _nbChannel, int32_t _nbSample) {
@ -340,7 +342,8 @@ int appl::MediaDecoder::open_codec_context(int *_streamId, AVFormatContext *_for
} }
// Init the decoders, with or without reference counting // Init the decoders, with or without reference counting
av_dict_set(&opts, "refcounted_frames", "0", 0); av_dict_set(&opts, "refcounted_frames", "0", 0);
av_dict_set(&opts, "threads", "auto", 0); //av_dict_set(&opts, "threads", "auto", 0);
av_dict_set(&opts, "threads", "4", 0);
if ((ret = avcodec_open2(dec_ctx, dec, &opts)) < 0) { if ((ret = avcodec_open2(dec_ctx, dec, &opts)) < 0) {
APPL_ERROR("Failed to open " << av_get_media_type_string(_type) << " codec"); APPL_ERROR("Failed to open " << av_get_media_type_string(_type) << " codec");
return ret; return ret;

View File

@ -40,11 +40,14 @@ namespace appl {
class MessageElementVideo : public appl::MessageElement { class MessageElementVideo : public appl::MessageElement {
public: public:
egami::Image m_image; //!< Image to manage internal data egami::Image m_image; //!< Image to manage internal data
ivec2 m_imagerealSize; //!< Real size of the image, in OpenGL we need power of 2 border size. ivec2 m_imageRealSize; //!< Real size of the image, in OpenGL we need power of 2 border size.
ivec2 m_imagePow2Size;
int32_t m_lineSize; //!< Size of a single line (in byte) int32_t m_lineSize; //!< Size of a single line (in byte)
void setSize(const ivec2& _newSize); void setSize(const ivec2& _newSize);
MessageElementVideo(): MessageElementVideo():
m_image(ivec2(32,32), egami::colorType::RGB8) { m_image(ivec2(32,32), egami::colorType::RGB8),
m_imageRealSize(32,32),
m_imagePow2Size(32,32) {
} }
}; };

View File

@ -43,14 +43,18 @@ void appl::widget::VideoDisplay::init() {
loadProgram(); loadProgram();
m_matrixApply.identity(); m_matrixApply.identity();
// By default we load a graphic resource ... // By default we load a graphic resource ...
if (m_resource == nullptr) {
m_resource = ewol::resource::Texture::create(); m_useElement = 0;
if (m_resource == nullptr) { for (int32_t iii=0; iii<ZEUS_VIDEO_PLAYER_MULTIPLE_BUFFER; ++iii) {
if (m_resource[iii] == nullptr) {
m_resource[iii] = ewol::resource::Texture::create();
if (m_resource[iii] == nullptr) {
EWOL_ERROR("Can not CREATE Image resource"); EWOL_ERROR("Can not CREATE Image resource");
return; return;
} }
// All time need to configure in RGB, By default it is in RGBA ... // All time need to configure in RGB, By default it is in RGBA ...
m_resource->get().configure(ivec2(128,128), egami::colorType::RGB8); m_resource[iii]->get().configure(ivec2(128,128), egami::colorType::RGB8);
}
} }
// Create the River manager for tha application or part of the application. // Create the River manager for tha application or part of the application.
m_audioManager = audio::river::Manager::create("zeus-video-player"); m_audioManager = audio::river::Manager::create("zeus-video-player");
@ -173,10 +177,13 @@ void appl::widget::VideoDisplay::onDraw() {
APPL_WARNING("Nothink to draw..."); APPL_WARNING("Nothink to draw...");
return; return;
} }
if (m_resource == nullptr) { /*
if ( m_resource[iii] == nullptr
|| m_resource2 == nullptr) {
// this is a normale case ... the user can choice to have no image ... // this is a normale case ... the user can choice to have no image ...
return; return;
} }
*/
if (m_GLprogram == nullptr) { if (m_GLprogram == nullptr) {
APPL_ERROR("No shader ..."); APPL_ERROR("No shader ...");
return; return;
@ -186,8 +193,9 @@ void appl::widget::VideoDisplay::onDraw() {
m_GLprogram->use(); m_GLprogram->use();
m_GLprogram->uniformMatrix(m_GLMatrix, tmpMatrix); m_GLprogram->uniformMatrix(m_GLMatrix, tmpMatrix);
// TextureID // TextureID
if (m_resource != nullptr) {
m_GLprogram->setTexture0(m_GLtexID, m_resource->getRendererId()); if (m_resource[m_useElement] != nullptr) {
m_GLprogram->setTexture0(m_GLtexID, m_resource[m_useElement]->getRendererId());
} }
// position: // position:
m_GLprogram->sendAttributePointer(m_GLPosition, m_VBO, m_vboIdCoord); m_GLprogram->sendAttributePointer(m_GLPosition, m_VBO, m_vboIdCoord);
@ -302,6 +310,8 @@ void appl::widget::VideoDisplay::periodicEvent(const ewol::event::Time& _event)
} }
// SET AUDIO: // SET AUDIO:
bool getSomething = false; bool getSomething = false;
bool cleaning = true;
while (cleaning == true) {
int32_t idSlot = m_decoder->audioGetOlderSlot(); int32_t idSlot = m_decoder->audioGetOlderSlot();
if ( idSlot != -1 if ( idSlot != -1
&& m_currentTime > m_decoder->m_audioPool[idSlot].m_time) { && m_currentTime > m_decoder->m_audioPool[idSlot].m_time) {
@ -331,22 +341,38 @@ void appl::widget::VideoDisplay::periodicEvent(const ewol::event::Time& _event)
} }
m_decoder->m_audioPool[idSlot].m_isUsed = false; m_decoder->m_audioPool[idSlot].m_isUsed = false;
getSomething = true; getSomething = true;
} else {
cleaning = false;
}
} }
// SET VIDEO: // SET VIDEO:
idSlot = m_decoder->videoGetOlderSlot(); cleaning = true;
int32_t nbDumpFrame = 0;
while (cleaning == true) {
int32_t idSlot = m_decoder->videoGetOlderSlot();
// check the slot is valid and check display time of the element: // check the slot is valid and check display time of the element:
if ( idSlot != -1 if ( idSlot != -1
&& m_currentTime > m_decoder->m_videoPool[idSlot].m_time) { && m_currentTime > m_decoder->m_videoPool[idSlot].m_time) {
APPL_VERBOSE("Get Slot VIDEO " << m_currentTime << " > " << m_decoder->m_audioPool[idSlot].m_time); APPL_VERBOSE("Get Slot VIDEO " << m_currentTime << " > " << m_decoder->m_audioPool[idSlot].m_time);
m_resource->get().swap(m_decoder->m_videoPool[idSlot].m_image); m_resource[m_useElement]->get().swap(m_decoder->m_videoPool[idSlot].m_image);
m_imageSize = m_resource->get().getSize(); m_resource[m_useElement]->flush();
ivec2 tmpSize = m_decoder->m_videoPool[idSlot].m_imagerealSize; m_useElement++;
m_decoder->m_videoPool[idSlot].m_imagerealSize = m_videoSize; if (m_useElement == ZEUS_VIDEO_PLAYER_MULTIPLE_BUFFER) {
m_useElement = 0;
}
m_imageSize = m_resource[m_useElement]->get().getSize();
ivec2 tmpSize = m_decoder->m_videoPool[idSlot].m_imageRealSize;
m_decoder->m_videoPool[idSlot].m_imageRealSize = m_videoSize;
m_videoSize = tmpSize; m_videoSize = tmpSize;
m_decoder->m_videoPool[idSlot].m_isUsed = false; m_decoder->m_videoPool[idSlot].m_isUsed = false;
m_resource->flush(); nbDumpFrame++;
m_nbFramePushed++;
getSomething = true; getSomething = true;
} else {
cleaning = false;
}
}
if (nbDumpFrame != 0) {
m_nbFramePushed++;
} }
// Display FPS ... // Display FPS ...
m_LastResetCounter += _event.getDeltaCallDuration(); m_LastResetCounter += _event.getDeltaCallDuration();

View File

@ -19,6 +19,8 @@
#include <appl/MediaDecoder.hpp> #include <appl/MediaDecoder.hpp>
#include <appl/widget/ListViewer.hpp> #include <appl/widget/ListViewer.hpp>
#define ZEUS_VIDEO_PLAYER_MULTIPLE_BUFFER (4)
namespace appl { namespace appl {
namespace widget { namespace widget {
class VideoDisplay : public ewol::Widget { class VideoDisplay : public ewol::Widget {
@ -44,7 +46,8 @@ namespace appl {
int32_t m_GLtexture; //!< openGL id on the element (Texture position) int32_t m_GLtexture; //!< openGL id on the element (Texture position)
int32_t m_GLtexID; //!< openGL id on the element (texture ID) int32_t m_GLtexID; //!< openGL id on the element (texture ID)
protected: protected:
ememory::SharedPtr<ewol::resource::Texture> m_resource; //!< texture resources int32_t m_useElement;
ememory::SharedPtr<ewol::resource::Texture> m_resource[ZEUS_VIDEO_PLAYER_MULTIPLE_BUFFER]; //!< texture resources
protected: protected:
static const int32_t m_vboIdCoord; static const int32_t m_vboIdCoord;
static const int32_t m_vboIdCoordTex; static const int32_t m_vboIdCoordTex;

View File

@ -1,6 +1,6 @@
#elem-brief: picture interface management #elem-brief: picture interface management
#elem-version: 1.0 #elem-version: 1.0
#elem-type:PICTURE #elem-type:VIDEO
#elem-author:Heero Yui<yui.heero@gmail.com #elem-author:Heero Yui<yui.heero@gmail.com
import zeus-File import zeus-File

View File

@ -29,25 +29,30 @@ namespace zeus {
ememory::SharedPtr<zeus::WebServer> m_interfaceWeb; //!< Interface on the Websocket interface ememory::SharedPtr<zeus::WebServer> m_interfaceWeb; //!< Interface on the Websocket interface
std::vector<ememory::WeakPtr<zeus::ObjectRemoteBase>> m_listConnectedService; //!< Connect only one time on each service, not needed more. std::vector<ememory::WeakPtr<zeus::ObjectRemoteBase>> m_listConnectedService; //!< Connect only one time on each service, not needed more.
public: public:
/**
* @brief answer a protocol error on the websocket ==> this stop the communication
* @param[in] _transactionId The tansation ID that have an error
* @param[in] _errorHelp Help developper/user to understand where the problem come from.
*/
void answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp); void answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp);
/**
* @brief Get the client web interface
* @return A shared pointer on the client server
*/
ememory::SharedPtr<zeus::WebServer> getWebInterface() { ememory::SharedPtr<zeus::WebServer> getWebInterface() {
return m_interfaceWeb; return m_interfaceWeb;
} }
/** /**
* @brief * @brief Contructor of a client
* @param[in]
* @return
*/ */
Client(); Client();
/** /**
* @brief * @brief Destructor of a client
* @param[in]
* @return
*/ */
virtual ~Client(); virtual ~Client();
protected: protected:
/** /**
* @brief Connetc to a remote extern server * @brief Connect to a remote extern server
* @param[in] _address Address of the user: "ABCD.efgh~atria-soft.com:1993" * @param[in] _address Address of the user: "ABCD.efgh~atria-soft.com:1993"
* @param[in] _timeOut duration that we are waiting the server answer * @param[in] _timeOut duration that we are waiting the server answer
*/ */
@ -91,9 +96,10 @@ namespace zeus {
* @return Pointer on an interface of remote service * @return Pointer on an interface of remote service
*/ */
zeus::ObjectRemote getService(const std::string& _serviceName); zeus::ObjectRemote getService(const std::string& _serviceName);
using factoryService = std::function<void(uint32_t, ememory::SharedPtr<zeus::WebServer>& _iface, uint32_t _destination)>; // call this function anser to the callter the requested Object
std::map<std::string,factoryService> m_listServicesAvaillable; //!< list of all factory availlable using factoryService = std::function<void(uint32_t, ememory::SharedPtr<zeus::WebServer>& _iface, uint32_t _destination)>; //!< call this function anser to the caller the requested Object
std::map<std::string,factoryService> m_listServicesAvaillable; //!< list of all factory availlable (to create new services)
/** /**
* @brief Provide a service with a specific name * @brief Provide a service with a specific name
* @param[in] _serviceName Name of the service * @param[in] _serviceName Name of the service
@ -101,6 +107,11 @@ namespace zeus {
* @return true if the service is acepted or false if not * @return true if the service is acepted or false if not
*/ */
bool serviceAdd(const std::string& _serviceName, factoryService _factory); bool serviceAdd(const std::string& _serviceName, factoryService _factory);
/**
* @brief Revmove a service from the list of availlable services
* @param[in] _serviceName Name of the service to remove
* @return true The service has been removed, false otherwise.
*/
bool serviceRemove(const std::string& _serviceName); bool serviceRemove(const std::string& _serviceName);
private: private:
/** /**
@ -142,15 +153,14 @@ namespace zeus {
void onPropertyChangePort(); void onPropertyChangePort();
public: public:
/** /**
* @brief * @brief Send a ping to prevent the protocol time-out (no transmission)
* @param[in] * @note let the system use this function.
* @return
*/ */
void pingIsAlive(); void pingIsAlive();
/** /**
* @brief * @brief Check if the server/connection is alive
* @param[in] * @return true The connection is alive
* @return * @return false The connection is dead
*/ */
bool isAlive(); bool isAlive();
/** /**
@ -162,9 +172,25 @@ namespace zeus {
*/ */
void cleanDeadObject(); void cleanDeadObject();
public: public:
// TODO: Remove this from here ... ==> create a proxy to gateway (service manager)
/**
* @brief Get the number of services.
* @return Future on the services count.
*/
zeus::Future<int32_t> getServiceCount(); zeus::Future<int32_t> getServiceCount();
/**
* @brief Get the whole list of services availlable
* @return Future on the list of service (names)
*/
zeus::Future<std::vector<std::string>> getServiceList(); zeus::Future<std::vector<std::string>> getServiceList();
// TODO : This is an active waiting ==> this is bad ... ==> use future, it will be better // TODO : This is an active waiting ==> this is bad ... ==> use future, it will be better
/**
* @brief Wait for a service wake up (and be availlable)
* @param[in] _serviceName Name of the service to wait.
* @param[in] _delta Duration to wait the service
* @return true The service is availlable
* @return false The service is not availlable.
*/
bool waitForService(const std::string& _serviceName, echrono::Duration _delta = echrono::seconds(1)); bool waitForService(const std::string& _serviceName, echrono::Duration _delta = echrono::seconds(1));
}; };
} }

View File

@ -17,45 +17,33 @@ zeus::Object::Object(const ememory::SharedPtr<zeus::WebServer>& _iface, uint16_t
} }
zeus::Object::~Object() {
}
void zeus::Object::receive(ememory::SharedPtr<zeus::Message> _value) { void zeus::Object::receive(ememory::SharedPtr<zeus::Message> _value) {
if (_value == nullptr) { if (_value == nullptr) {
return; return;
} }
uint32_t tmpID = _value->getTransactionId(); if (_value->getPartFinish() == false) {
uint32_t source = _value->getSource(); ZEUS_ERROR("call a receive function with a not finished message ...");
zeus::FutureBase futData(tmpID, _value, source);
if (futData.isFinished() == true) {
callBinary(futData.getRaw());
} else {
m_callMultiData.push_back(futData);
}
}
void zeus::Object::callBinary(ememory::SharedPtr<zeus::Message> _obj) {
if (_obj == nullptr) {
return; return;
} }
if (_obj->getType() == zeus::message::type::event) { if (_value->getType() == zeus::message::type::event) {
ZEUS_ERROR("Unknow event: '...'"); ZEUS_ERROR("Unknow event: '...'");
return; return;
} }
if (_obj->getType() == zeus::message::type::answer) { if (_value->getType() == zeus::message::type::answer) {
ZEUS_ERROR("Local Answer: '...'"); ZEUS_ERROR("Local Answer: '...'");
return; return;
} }
if (_obj->getType() == zeus::message::type::call) { if (_value->getType() == zeus::message::type::data) {
ememory::SharedPtr<zeus::message::Call> callObj = ememory::staticPointerCast<zeus::message::Call>(_obj); ZEUS_ERROR("Local DATA: '...'");
return;
}
if (_value->getType() == zeus::message::type::call) {
ememory::SharedPtr<zeus::message::Call> callObj = ememory::staticPointerCast<zeus::message::Call>(_value);
uint32_t source = callObj->getSource(); uint32_t source = callObj->getSource();
uint32_t sourceId = callObj->getSourceId(); uint32_t sourceId = callObj->getSourceId();
std::string callFunction = callObj->getCall(); std::string callFunction = callObj->getCall();
if (isFunctionAuthorized(sourceId, callFunction) == true) { if (isFunctionAuthorized(sourceId, callFunction) == true) {
callBinary2(callFunction, callObj); callBinary(callFunction, callObj);
return; return;
} else { } else {
m_interfaceWeb->answerError(callObj->getTransactionId(), getFullId(), source, "NOT-AUTHORIZED-FUNCTION", ""); m_interfaceWeb->answerError(callObj->getTransactionId(), getFullId(), source, "NOT-AUTHORIZED-FUNCTION", "");
@ -63,5 +51,3 @@ void zeus::Object::callBinary(ememory::SharedPtr<zeus::Message> _obj) {
} }
} }
} }

View File

@ -20,49 +20,46 @@
namespace zeus { namespace zeus {
class Client; class Client;
/** /**
* @brief * @brief An object is an element callable from the remote.
* @param[in]
* @return
*/ */
class Object : public zeus::RemoteProcessCall { class Object : public zeus::RemoteProcessCall {
protected:
std::mutex m_mutex;
protected:
std::vector<zeus::FutureBase> m_callMultiData;
public: public:
uint16_t getObjectId() { return m_objectId; }
/** /**
* @brief * @brief Get the current object local unique ID
* @param[in] * @return The unique Object id
* @return */
uint16_t getObjectId() {
return m_objectId;
}
/**
* @brief Contruct a new callable object
* @param[in] _iface Network interface
* @param[in] _objectId Unique Id of the object
*/ */
Object(const ememory::SharedPtr<zeus::WebServer>& _iface, uint16_t _objectId); Object(const ememory::SharedPtr<zeus::WebServer>& _iface, uint16_t _objectId);
/** /**
* @brief * @brief generic destructor
* @param[in]
* @return
*/ */
virtual ~Object(); virtual ~Object() = default;
public: public:
/**
* @brief Receive message to parse and execute
* @param[in] _value Message to process
*/
void receive(ememory::SharedPtr<zeus::Message> _value); void receive(ememory::SharedPtr<zeus::Message> _value);
private: private:
/** /**
* @brief * @brief Specific call depending of the type of the object.
* @param[in] * @param[in] _call Name of the function that is called.
* @return * @param[in] _value Message to process.
*/ */
void callBinary(ememory::SharedPtr<zeus::Message> _obj); virtual void callBinary(const std::string& _call, ememory::SharedPtr<zeus::message::Call> _value) = 0;
/**
* @brief
* @param[in]
* @return
*/
virtual void callBinary2(const std::string& _call, ememory::SharedPtr<zeus::message::Call> _obj) = 0;
public: public:
/** /**
* @brief * @brief Advertise a new function in the service/object ==> it is force the start with "obj.".
* @param[in] * @param[in] _name Name of the function
* @return * @param[in] _func pointer on the function that might be used to call it.
* @return an handle on an abstract function that can be called.
*/ */
// Add Local fuction (depend on this class) // Add Local fuction (depend on this class)
template<class ZEUS_RETURN_VALUE, template<class ZEUS_RETURN_VALUE,
@ -70,7 +67,7 @@ namespace zeus {
class... ZEUS_FUNC_ARGS_TYPE> class... ZEUS_FUNC_ARGS_TYPE>
zeus::AbstractFunction* advertise(std::string _name, zeus::AbstractFunction* advertise(std::string _name,
ZEUS_RETURN_VALUE (ZEUS_CLASS_TYPE::*_func)(ZEUS_FUNC_ARGS_TYPE... _args)) { ZEUS_RETURN_VALUE (ZEUS_CLASS_TYPE::*_func)(ZEUS_FUNC_ARGS_TYPE... _args)) {
_name = "srv." + _name; _name = "obj." + _name;
for (auto &it : m_listFunction) { for (auto &it : m_listFunction) {
if (it == nullptr) { if (it == nullptr) {
continue; continue;
@ -91,18 +88,15 @@ namespace zeus {
return tmp; return tmp;
} }
}; };
/**
* @brief The object is all time different, and we need to called it corectly and keep it alive while the remote user need it.
* The this class permit to have a a pointer on the temporary object.
*/
template<class ZEUS_TYPE_OBJECT> template<class ZEUS_TYPE_OBJECT>
class ObjectType : public zeus::Object { class ObjectType : public zeus::Object {
private: private:
ememory::SharedPtr<ZEUS_TYPE_OBJECT> m_interface; // direct handle on the data; ememory::SharedPtr<ZEUS_TYPE_OBJECT> m_interface; //!< handle on the object that might be called.
public: public:
/*
ObjectType(zeus::Client* _client, uint16_t _objectId, uint16_t _clientId) :
Object(_client, _objectId) {
m_interface = ememory::makeShared<ZEUS_TYPE_OBJECT>(/ *_clientId* /);
}
*/
ObjectType(const ememory::SharedPtr<zeus::WebServer>& _iface, uint16_t _objectId, const ememory::SharedPtr<ZEUS_TYPE_OBJECT>& _element) : ObjectType(const ememory::SharedPtr<zeus::WebServer>& _iface, uint16_t _objectId, const ememory::SharedPtr<ZEUS_TYPE_OBJECT>& _element) :
Object(_iface, _objectId), Object(_iface, _objectId),
m_interface(_element) { m_interface(_element) {
@ -180,12 +174,7 @@ namespace zeus {
m_listFunction.push_back(tmp); m_listFunction.push_back(tmp);
return tmp; return tmp;
} }
/** bool isFunctionAuthorized(uint64_t _clientId, const std::string& _funcName) override {
* @brief
* @param[in]
* @return
*/
bool isFunctionAuthorized(uint64_t _clientId, const std::string& _funcName) {
/* /*
auto it = m_interface.find(_clientId); auto it = m_interface.find(_clientId);
if (it == m_interface.end()) { if (it == m_interface.end()) {
@ -197,11 +186,11 @@ namespace zeus {
return true; return true;
} }
/** /**
* @brief * @brief Find and call the functionwith a specific name
* @param[in] * @param[in] _call Function name to call
* @return * @param[in] _value Message to process.
*/ */
void callBinary2(const std::string& _call, ememory::SharedPtr<zeus::message::Call> _obj) { void callBinary(const std::string& _call, ememory::SharedPtr<zeus::message::Call> _value) {
for (auto &it2 : m_listFunction) { for (auto &it2 : m_listFunction) {
if (it2 == nullptr) { if (it2 == nullptr) {
continue; continue;
@ -209,22 +198,24 @@ namespace zeus {
if (it2->getName() != _call) { if (it2->getName() != _call) {
continue; continue;
} }
// TODO: Check if client is athorized ...
// depending on where the function is defined, the call is not the same ...
switch (it2->getType()) { switch (it2->getType()) {
case zeus::AbstractFunction::type::object: { case zeus::AbstractFunction::type::object: {
ZEUS_TYPE_OBJECT* elem = m_interface.get(); ZEUS_TYPE_OBJECT* elem = m_interface.get();
it2->execute(m_interfaceWeb, _obj, (void*)elem); it2->execute(m_interfaceWeb, _value, (void*)elem);
return; return;
} }
case zeus::AbstractFunction::type::local: { case zeus::AbstractFunction::type::local: {
it2->execute(m_interfaceWeb, _obj, (void*)((RemoteProcessCall*)this)); it2->execute(m_interfaceWeb, _value, (void*)((RemoteProcessCall*)this));
return; return;
} }
case zeus::AbstractFunction::type::service: { case zeus::AbstractFunction::type::service: {
it2->execute(m_interfaceWeb, _obj, (void*)this); it2->execute(m_interfaceWeb, _value, (void*)this);
return; return;
} }
case zeus::AbstractFunction::type::global: { case zeus::AbstractFunction::type::global: {
it2->execute(m_interfaceWeb, _obj, nullptr); it2->execute(m_interfaceWeb, _value, nullptr);
return; return;
} }
case zeus::AbstractFunction::type::unknow: case zeus::AbstractFunction::type::unknow:
@ -232,8 +223,11 @@ namespace zeus {
break; break;
} }
} }
m_interfaceWeb->answerError(_obj->getTransactionId(), _obj->getDestination(), _obj->getSource(), "FUNCTION-UNKNOW", "not find function name: '" + _call + "'"); m_interfaceWeb->answerError(_value->getTransactionId(),
return; _value->getDestination(),
_value->getSource(),
"FUNCTION-UNKNOW",
"not find function name: '" + _call + "'");
} }
}; };
} }

View File

@ -6,40 +6,40 @@
#include <zeus/ObjectIntrospect.hpp> #include <zeus/ObjectIntrospect.hpp>
zeus::ObjectIntrospect::ObjectIntrospect(zeus::ObjectRemote& _srv): zeus::ObjectIntrospect::ObjectIntrospect(zeus::ObjectRemote& _obj):
m_srv(_srv) { m_obj(_obj) {
} }
zeus::Future<std::string> zeus::ObjectIntrospect::getDescription() { zeus::Future<std::string> zeus::ObjectIntrospect::getDescription() {
return m_srv.call("sys.getDescription"); return m_obj.call("obj.getDescription");
} }
zeus::Future<std::string> zeus::ObjectIntrospect::getVersion() { zeus::Future<std::string> zeus::ObjectIntrospect::getVersion() {
return m_srv.call("sys.getVersion"); return m_obj.call("obj.getVersion");
} }
zeus::Future<std::string> zeus::ObjectIntrospect::getType() { zeus::Future<std::string> zeus::ObjectIntrospect::getType() {
return m_srv.call("sys.getType"); return m_obj.call("obj.getType");
} }
zeus::Future<std::vector<std::string>> zeus::ObjectIntrospect::getExtention() { zeus::Future<std::vector<std::string>> zeus::ObjectIntrospect::getExtention() {
return m_srv.call("sys.getExtention"); return m_obj.call("obj.getExtention");
} }
zeus::Future<std::vector<std::string>> zeus::ObjectIntrospect::getAuthors() { zeus::Future<std::vector<std::string>> zeus::ObjectIntrospect::getAuthors() {
return m_srv.call("sys.getAuthors"); return m_obj.call("obj.getAuthors");
} }
zeus::Future<std::vector<std::string>> zeus::ObjectIntrospect::getFunctions() { zeus::Future<std::vector<std::string>> zeus::ObjectIntrospect::getFunctions() {
return m_srv.call("sys.getFunctions"); return m_obj.call("obj.getFunctions");
} }
zeus::Future<std::string> zeus::ObjectIntrospect::getFunctionPrototype(std::string _functionName) { zeus::Future<std::string> zeus::ObjectIntrospect::getFunctionPrototype(std::string _functionName) {
return m_srv.call("sys.getFunctionPrototype", _functionName); return m_obj.call("obj.getFunctionPrototype", _functionName);
} }
zeus::Future<std::string> zeus::ObjectIntrospect::getFunctionDescription(std::string _functionName) { zeus::Future<std::string> zeus::ObjectIntrospect::getFunctionDescription(std::string _functionName) {
return m_srv.call("sys.getFunctionDescription", _functionName); return m_obj.call("obj.getFunctionDescription", _functionName);
} }

View File

@ -8,19 +8,59 @@
#include <zeus/ObjectRemote.hpp> #include <zeus/ObjectRemote.hpp>
namespace zeus { namespace zeus {
/**
* @brief This object permit to simplify the acces of the introspection propoerty of a remote service.
*/
class ObjectIntrospect { class ObjectIntrospect {
protected: protected:
zeus::ObjectRemote& m_srv; //!< Service instance handle zeus::ObjectRemote& m_obj; //!< Service instance handle
public: public:
ObjectIntrospect(zeus::ObjectRemote& _srv); /**
* @brief Contructor on the object introspection element.
* @param[in] _obj Object to introspect.
*/
ObjectIntrospect(zeus::ObjectRemote& _obj);
/**
* @brief Get the service/ object description
* @return A future of the description
*/
zeus::Future<std::string> getDescription(); zeus::Future<std::string> getDescription();
/**
* @brief Get the version of the service/Object
* @return A future of the string version
*/
zeus::Future<std::string> getVersion(); zeus::Future<std::string> getVersion();
/**
* @brief Get the Type of the service/object. ex: VIDEO, PICTURE, FILE
* @return A future of the string type
*/
zeus::Future<std::string> getType(); zeus::Future<std::string> getType();
/**
* @brief Get the list of extention availlable of the object (more specific of the service)
* @return A future on all extention availlable. Format: "typeExtention:xx.yy.zz"
*/
zeus::Future<std::vector<std::string>> getExtention(); zeus::Future<std::vector<std::string>> getExtention();
/**
* @brief get the list of all authors of the objects
* @return A future on the list of authors. Format: "NAME surname <email@someware.xxx>"
*/
zeus::Future<std::vector<std::string>> getAuthors(); zeus::Future<std::vector<std::string>> getAuthors();
/**
* @brief get all the function names
* @return Future on a list of function names
*/
zeus::Future<std::vector<std::string>> getFunctions(); zeus::Future<std::vector<std::string>> getFunctions();
/**
* @brief Get the fonction prototype (same as IDL)
* @param[in] _functionName Name of the function
* @return a future on the function prototype
*/
zeus::Future<std::string> getFunctionPrototype(std::string _functionName); zeus::Future<std::string> getFunctionPrototype(std::string _functionName);
/**
* @brief Det a fonction specific description
* @param[in] _functionName Name of the function
* @return a future on the function description
*/
zeus::Future<std::string> getFunctionDescription(std::string _functionName); zeus::Future<std::string> getFunctionDescription(std::string _functionName);
}; };
} }

View File

@ -54,10 +54,6 @@ zeus::ObjectRemote::ObjectRemote(ememory::SharedPtr<zeus::ObjectRemoteBase> _int
} }
} }
zeus::ObjectRemote::~ObjectRemote() {
}
bool zeus::ObjectRemote::exist() const { bool zeus::ObjectRemote::exist() const {
if (m_interface == nullptr) { if (m_interface == nullptr) {
return false; return false;

View File

@ -17,48 +17,48 @@ namespace zeus {
//class Client; //class Client;
class ObjectRemote; class ObjectRemote;
/** /**
* @brief * @brief Basic element of a remote element access.
* @param[in]
* @return
*/ */
class ObjectRemoteBase : public zeus::WebObj { class ObjectRemoteBase : public zeus::WebObj {
friend class ObjectRemote; friend class ObjectRemote;
private: private:
std::string m_type; std::string m_type; //!< name of the remote object
uint32_t m_remoteAddress; uint32_t m_remoteAddress; //!< remote adress of the object
bool m_isLinked; bool m_isLinked; //!< link status of the object
public: public:
/** /**
* @brief * @brief Contructor of the remote object
* @param[in]
* @return
*/ */
ObjectRemoteBase(): ObjectRemoteBase():
zeus::WebObj(nullptr, 0, 0) { zeus::WebObj(nullptr, 0, 0) {
ZEUS_INFO("[XX/YY] Create"); ZEUS_INFO("[XX/YY] Create");
} }
/** /**
* @brief * @brief Contuctor of the remote object accessor
* @param[in] * @param[in] _iface Web interface of the Object
* @return * @param[in] _localId Current Web interface Id
* @param[in] _localObjectId Current object Id (local)
* @param[in] _address Remote object Address
* @param[in] _type Type of the remote object
*/ */
ObjectRemoteBase(const ememory::SharedPtr<zeus::WebServer>& _iface, uint16_t _localId, uint16_t _localObjectId, uint32_t _address, const std::string& _type); ObjectRemoteBase(const ememory::SharedPtr<zeus::WebServer>& _iface,
uint16_t _localId,
uint16_t _localObjectId,
uint32_t _address,
const std::string& _type);
/** /**
* @brief * @brief Generic destructor
* @param[in]
* @return
*/ */
~ObjectRemoteBase(); ~ObjectRemoteBase();
/** /**
* @brief * @brief permit to check if the remote hs been corectly created
* @param[in] * @return true The object exist
* @return * @return false The object is NOT accessible
*/ */
bool exist() const; bool exist() const;
/** /**
* @brief * @brief Get the name of the object (use in client service check name)
* @param[in] * @TODO: Remove this API
* @return
*/ */
const std::string& getName() const; const std::string& getName() const;
/** /**
@ -76,6 +76,9 @@ namespace zeus {
m_isLinked = false; m_isLinked = false;
m_remoteAddress = 0; m_remoteAddress = 0;
} }
/**
* @breif Display property of the service
*/
void display(); void display();
}; };
/** /**
@ -85,24 +88,17 @@ namespace zeus {
*/ */
class ObjectRemote { class ObjectRemote {
private: private:
mutable ememory::SharedPtr<zeus::ObjectRemoteBase> m_interface; mutable ememory::SharedPtr<zeus::ObjectRemoteBase> m_interface; //!< Remote interface access (use sharedPtr to prevent multiple link with a simgle service is a single client)
public: public:
/** /**
* @brief * @brief Contructor of a remote Object
* @param[in] * @param[in] _interface Interface of the object
* @return
*/ */
ObjectRemote(ememory::SharedPtr<zeus::ObjectRemoteBase> _interface = nullptr); ObjectRemote(ememory::SharedPtr<zeus::ObjectRemoteBase> _interface = nullptr);
/** /**
* @brief * @brief permit to check if the remote hs been corectly created
* @param[in] * @return true The object exist
* @return * @return false The object is NOT accessible
*/
~ObjectRemote();
/**
* @brief
* @param[in]
* @return
*/ */
bool exist() const; bool exist() const;
public: public:
@ -128,9 +124,10 @@ namespace zeus {
_args...); _args...);
} }
/** /**
* @brief * @brief Specific case for action call. This permit to check if user does not wait on event on something that is not an action.
* @param[in] * @param[in] _functionName Name of the function
* @return * @param[in] _args All argument function needed by the remote to process the function
* @return A generic future with all datas
*/ */
template<class... _ARGS> template<class... _ARGS>
zeus::FutureBase callAction(const std::string& _functionName, _ARGS&&... _args) const { zeus::FutureBase callAction(const std::string& _functionName, _ARGS&&... _args) const {

View File

@ -17,7 +17,7 @@
namespace zeus { namespace zeus {
class FutureBase; class FutureBase;
/** /**
* @brief Data interface of the future (the future can be copied, but the data need to stay... * @brief Data interface of the future (the future can be copied, but the data need to stay...)
*/ */
class Promise : public ememory::EnableSharedFromThis<zeus::Promise> { class Promise : public ememory::EnableSharedFromThis<zeus::Promise> {
public: public:

View File

@ -14,14 +14,35 @@ namespace zeus {
*/ */
class Proxy { class Proxy {
protected: protected:
zeus::ObjectRemote m_obj; //!< Service instance handle zeus::ObjectRemote m_obj; //!< Object instance handle
public: public:
zeus::ObjectIntrospect sys; zeus::ObjectIntrospect sys; //!< publish introspection function call
public: public:
const Proxy& operator= (const zeus::ObjectRemote& _srv); /**
* @brief a simple proxy constructor
*/
Proxy(); Proxy();
/**
* @brief Contructor of a proxy
* @param[in] _obj an the object remote handle
*/
Proxy(const zeus::ObjectRemote& _obj);
/**
* @brief Set operator
* @param[in] _obj an other service remote
* @return A reference on this proxy.
*/
const Proxy& operator= (const zeus::ObjectRemote& _obj);
/**
* @brief set destructor VIRTUAL
*/
virtual ~Proxy() = default; virtual ~Proxy() = default;
Proxy(const zeus::ObjectRemote& _srv); /**
* @brief Permit to check if the remote hss been corectly created
* @return true The object exist
* @return false The object is NOT accessible
*/
bool exist() const; bool exist() const;
}; };
} }

View File

@ -29,11 +29,6 @@ zeus::Raw::Raw(uint32_t _size, const uint8_t* _data) :
} }
zeus::Raw::~Raw() {
}
uint32_t zeus::Raw::size() const { uint32_t zeus::Raw::size() const {
return m_size; return m_size;
} }

View File

@ -13,9 +13,9 @@ namespace zeus {
*/ */
class Raw { class Raw {
private: private:
uint32_t m_size; uint32_t m_size; //!< Size of the DATA
const uint8_t* m_dataExternal; const uint8_t* m_dataExternal; //!< The raw buffer is contituated with ecternal static data
std::vector<uint8_t> m_dataInternal; std::vector<uint8_t> m_dataInternal; //!< the data is allocated in local.
public: public:
/** /**
* @brief generic constructor * @brief generic constructor
@ -23,18 +23,29 @@ namespace zeus {
Raw(); Raw();
/** /**
* @brief generic constructor * @brief generic constructor
* @param[in] _size Data size that might be allocated by default
*/ */
Raw(uint32_t _size); Raw(uint32_t _size);
/**
* @brief generic constructor (ecternal data)
* @param[in] _size Data size of the external data
* @param[in] _data Pointer of the externaldata
*/
Raw(uint32_t _size, const uint8_t* _data); Raw(uint32_t _size, const uint8_t* _data);
/**
~Raw(); * @breif Get size of the data
* @return the size of the data >=0
*/
uint32_t size() const; uint32_t size() const;
/**
* @brief Get a pointer on the data
* @return a pointer on the data (or nullptr)
*/
const uint8_t* data() const; const uint8_t* data() const;
/**
* @brief Get a writable pointer on the data
* @return a pointer on the data (or nullptr)
*/
uint8_t* writeData(); uint8_t* writeData();
}; };
} }

View File

@ -19,6 +19,9 @@ namespace zeus {
public: public:
/** /**
* @brief Basic constructor * @brief Basic constructor
* @param[in] _iface web interface to interact network
* @param[in] _id Id of the service interface
* @param[in] _objectId Local object interface
*/ */
RemoteProcessCall(const ememory::SharedPtr<zeus::WebServer>& _iface, uint16_t _id, uint16_t _objectId); RemoteProcessCall(const ememory::SharedPtr<zeus::WebServer>& _iface, uint16_t _id, uint16_t _objectId);
protected: protected:
@ -85,46 +88,61 @@ namespace zeus {
std::string m_type; //!< Generic type of the service std::string m_type; //!< Generic type of the service
public: public:
/** /**
* @brief * @brief Get type of this object
* @param[in] * @return Type of this object in string
* @return
*/ */
std::string getType(); std::string getType();
/** /**
* @brief * @brief Set the type of this object
* @param[in] * @param[in] _type New type of this object
* @return
*/ */
void setType(const std::string& _type); void setType(const std::string& _type);
public: public:
/** /**
* @brief * @brief Get list of fucntion aaillable in this object
* @param[in] * @return List of function name
* @return
*/ */
std::vector<std::string> getFunctions(); std::vector<std::string> getFunctions();
/** /**
* @brief * @brief Get the AbstractFunction of a function with a specific name
* @param[in] * @param[in] _funcName Name of the function
* @return * @return Pointer on the function
*/ */
AbstractFunction* getFunction(std::string _funcName); AbstractFunction* getFunction(std::string _funcName);
private: private:
/**
* @brief Get the signature of a function with a specific name
* @param[in] _funcName Name of the function
* @return IDL function signature
*/
std::vector<std::string> getFunctionSignature(std::string _funcName); std::vector<std::string> getFunctionSignature(std::string _funcName);
/**
* @brief Get the signature of a function with a specific name
* @param[in] _funcName Name of the function
* @return IDL function prototype
*/
std::string getFunctionPrototype(std::string _funcName); std::string getFunctionPrototype(std::string _funcName);
/**
* @brief Get the descriptyion of a function with a specific name
* @param[in] _funcName Name of the function
* @return Description of this function
*/
std::string getFunctionDescription(std::string _funcName); std::string getFunctionDescription(std::string _funcName);
protected: protected:
/** /**
* @brief * @brief Check if the function is accessible for a specific user
* @param[in] * @param[in] _clientId User unique ID
* @return * @param[in] _funcName Function name that the user is calling
* @return true The function is authorized
* @return false The function is NOT authorized
*/ */
virtual bool isFunctionAuthorized(uint64_t _clientSessionID, const std::string& _funcName); virtual bool isFunctionAuthorized(uint64_t _clientSessionID, const std::string& _funcName);
public: public:
/** /**
* @brief * @brief Advertise a new function in the service/object.
* @param[in] * @param[in] _name Name of the function
* @return * @param[in] _func pointer on the function that might be used to call it.
* @return an handle on an abstract function that can be called.
*/ */
// Add global fuction (no link with this class) // Add global fuction (no link with this class)
template<class ZEUS_RETURN_VALUE, template<class ZEUS_RETURN_VALUE,
@ -151,9 +169,10 @@ namespace zeus {
return tmp; return tmp;
} }
/** /**
* @brief * @brief Advertise a new function in the service/object.
* @param[in] * @param[in] _name Name of the function
* @return * @param[in] _func pointer on the function that might be used to call it.
* @return an handle on an abstract function that can be called.
*/ */
// Add Local fuction (depend on this class) // Add Local fuction (depend on this class)
template<class ZEUS_RETURN_VALUE, template<class ZEUS_RETURN_VALUE,

View File

@ -18,8 +18,8 @@ namespace zeus {
template<typename ZEUS_TYPE_PROPERTY> template<typename ZEUS_TYPE_PROPERTY>
class RemoteProperty { class RemoteProperty {
private: private:
zeus::ObjectRemote& m_remoteObject; zeus::ObjectRemote& m_remoteObject; //!< Remote ofject interface
std::string m_name; std::string m_name; //!< Name of the property to call.
public: public:
/** /**
* @brief generic constructor * @brief generic constructor

56
zeus/RemoteSignal.hpp Normal file
View File

@ -0,0 +1,56 @@
/** @file
* @author Edouard DUPIN
* @copyright 2016, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#pragma once
#include <zeus/WebServer.hpp>
#include <zeus/AbstractFunctionTypeDirect.hpp>
#include <zeus/AbstractFunctionTypeClass.hpp>
#include <zeus/debug.hpp>
#include <zeus/WebObj.hpp>
namespace zeus {
/**
* @brief Remote inteface of a property:
*/
template<typename ZEUS_TYPE_SIGNAL>
class RemoteSignal : public esignal::Signal<ZEUS_TYPE_SIGNAL> {
private:
zeus::ObjectRemote& m_remoteObject; //!< Remote ofject interface
zeus::Future<ZEUS_TYPE_SIGNAL> m_handleSignal;
public:
/**
* @brief generic constructor
*/
RemoteProperty(zeus::ObjectRemote& _remoteObject, const std::string& _name) :
esignal::Signal<ZEUS_TYPE_SIGNAL>(&zeus::RemoteSignal<ZEUS_TYPE_SIGNAL>::countConnection, _name),
m_remoteObject(_remoteObject),
m_name(_name) {
}
private:
/**
* @brief local function that is called every time someone connect on the local signal or disconnect
* @param[in] _numberConnected Nomber of connected users.
*/
void countConnection(size_t _numberConnected) {
if (_numberConnected == 1) {
m_handleSignal = m_remoteObject.call(getName() + ".connect");
m_handleSignal.onSignal(&zeus::RemoteSignal<ZEUS_TYPE_SIGNAL>::onSignal);
} else if (_numberConnected == 0) {
// stop the connection on the signalling
m_handleSignal.abort();
}
}
/**
* @brief When remote process emit a signal, it will arrive here, and be retansmit in generic esignal methode
* @param[in] _value Data receive from remote user.
*/
void onSignal(ZEUS_TYPE_SIGNAL _value) {
emit(_value);
}
};
}

View File

@ -5,31 +5,88 @@
*/ */
#pragma once #pragma once
//#include <zeus/WebServer.hpp>
#include <etk/types.hpp> #include <etk/types.hpp>
#include <ememory/memory.hpp> #include <ememory/memory.hpp>
#include <zeus/message/Message.hpp> #include <zeus/message/Message.hpp>
namespace zeus { namespace zeus {
class WebServer; class WebServer;
/**
* @brief generic handle for remote object
*/
class WebObj : public ememory::EnableSharedFromThis<zeus::WebObj> { class WebObj : public ememory::EnableSharedFromThis<zeus::WebObj> {
protected: protected:
ememory::SharedPtr<zeus::WebServer> m_interfaceWeb; ememory::SharedPtr<zeus::WebServer> m_interfaceWeb; //!< web interface
uint16_t m_id; uint16_t m_id; //!< Id Of the local interface
uint16_t m_objectId; uint16_t m_objectId; //!< Local Object Id
std::vector<uint32_t> m_listRemoteConnected; std::vector<uint32_t> m_listRemoteConnected; //!< Number of service connected
public: public:
/**
* @brief Contructor
* @param[in] _iface Network interface to interact
* @param[in] _id Local user ID
* @param[in] _objectId This object unique ID
*/
WebObj(const ememory::SharedPtr<zeus::WebServer>& _iface, uint16_t _id, uint16_t _objectId); WebObj(const ememory::SharedPtr<zeus::WebServer>& _iface, uint16_t _id, uint16_t _objectId);
/**
* @brief Descructor
*/
virtual ~WebObj(); virtual ~WebObj();
/**
* @brief Get the local client ID
* @return Local client ID
*/
uint16_t getInterfaceId(); uint16_t getInterfaceId();
/**
* @brief Get the local Object ID
* @return Unique local object ID
*/
uint16_t getObjectId(); uint16_t getObjectId();
/**
* @brief Get the full ID of the object (IFaceId<<16+ObjectId)
* @return the Full object ID
*/
uint32_t getFullId(); uint32_t getFullId();
/**
* @brief Something send a message to the Object
* @param[in] _value Value to process
*/
virtual void receive(ememory::SharedPtr<zeus::Message> _value); virtual void receive(ememory::SharedPtr<zeus::Message> _value);
/**
* @brief Display object properties
*/
virtual void display(); virtual void display();
/**
* @brief Add a remote Object link on this one
* @param[in] _id Id of the remote object
*/
void addRemote(uint32_t _id); void addRemote(uint32_t _id);
/**
* @brief Remove a remote object link on this one
* @param[in] _id Id of the remote object
* @return true The owner has been fined and remove
* @return false other bad case ...
*/
bool removeOwnership(uint32_t _id); bool removeOwnership(uint32_t _id);
/**
* @brief A client interface has been removed ==> need to call this function for every object.
* @param[in] _id Id of the interface that is down
*/
void rmRemoteInterface(uint16_t _id); void rmRemoteInterface(uint16_t _id);
/**
* @brief Check if someone request a link on this object
* @return true Someone is connected
* @return false standalone object
*/
bool haveRemoteConnected() const; bool haveRemoteConnected() const;
/**
* @brief Transfer the onership from an object address to an other object address
* @param[in] _sourceAddress Object address to change
* @param[in] _destinataireAddress New Object address to set
* @return true Onership has change
* @return false An error occured
* @note Why we need the onership transfer? when you request a new service, this is the client GW that id doing it, then the remote addreess is not the good one, then we update the address to imply the good one
*/
bool transferOwnership(uint32_t _sourceAddress, uint32_t _destinataireAddress); bool transferOwnership(uint32_t _sourceAddress, uint32_t _destinataireAddress);
}; };

View File

@ -183,7 +183,6 @@ void zeus::WebServer::connect(bool _async){
ZEUS_ERROR("creating async sender thread!"); ZEUS_ERROR("creating async sender thread!");
return; return;
} }
while ( _async == false while ( _async == false
&& m_threadAsyncRunning == true && m_threadAsyncRunning == true
&& m_connection.isAlive() != true) { && m_connection.isAlive() != true) {
@ -630,16 +629,14 @@ void zeus::WebServer::threadAsyncCallback() {
} }
zeus::FutureBase zeus::WebServer::callBinary(uint64_t _transactionId, zeus::FutureBase zeus::WebServer::callBinary(ememory::SharedPtr<zeus::Message> _obj) {
ememory::SharedPtr<zeus::Message> _obj,
const uint32_t& _destination) {
if (isActive() == false) { if (isActive() == false) {
ZEUS_ERROR("Send [STOP] ==> not connected (no TCP)"); ZEUS_ERROR("Send [STOP] ==> not connected (no TCP)");
ememory::SharedPtr<zeus::message::Answer> obj = zeus::message::Answer::create(sharedFromThis()); ememory::SharedPtr<zeus::message::Answer> obj = zeus::message::Answer::create(sharedFromThis());
obj->addError("NOT-CONNECTED", "Client interface not connected (no TCP)"); obj->addError("NOT-CONNECTED", "Client interface not connected (no TCP)");
return zeus::FutureBase(_transactionId, obj); return zeus::FutureBase(_obj->getTransactionId(), obj);
} }
zeus::FutureBase tmpFuture(_transactionId); zeus::FutureBase tmpFuture(_obj->getTransactionId());
{ {
std::unique_lock<std::mutex> lock(m_pendingCallMutex); std::unique_lock<std::mutex> lock(m_pendingCallMutex);
m_pendingCall.push_back(std::make_pair(uint64_t(0), tmpFuture)); m_pendingCall.push_back(std::make_pair(uint64_t(0), tmpFuture));

View File

@ -119,35 +119,63 @@ namespace zeus {
uint16_t m_localAddress; //!< Local client address. uint16_t m_localAddress; //!< Local client address.
uint16_t m_localIdObjectIncrement; //!< attribute an unique ID for an object. uint16_t m_localIdObjectIncrement; //!< attribute an unique ID for an object.
public: public:
/**
* @brief Get the unique ID of the client
* @return the client Mai address
*/
uint16_t getAddress() const { uint16_t getAddress() const {
return m_localAddress; return m_localAddress;
} }
/**
* @brief Set the new wlient address
* @param[in] _address Address of the client
*/
void setAddress(uint16_t _address) { void setAddress(uint16_t _address) {
m_localAddress = _address; m_localAddress = _address;
} }
/**
* @brief Get a new unique object ID
* @return a new single object ID
*/
uint16_t getNewObjectId() { uint16_t getNewObjectId() {
std::unique_lock<std::mutex> lock(m_mutex);
return m_localIdObjectIncrement++; return m_localIdObjectIncrement++;
} }
private: private:
std::vector<ememory::SharedPtr<zeus::WebObj>> m_listObject; //!< List of all local object that is reference in the system. std::vector<ememory::SharedPtr<zeus::WebObj>> m_listObject; //!< List of all local object that is reference in the system.
std::vector<ememory::WeakPtr<zeus::ObjectRemoteBase>> m_listRemoteObject; //!< List of all object that we have a reference in the local interface. std::vector<ememory::WeakPtr<zeus::ObjectRemoteBase>> m_listRemoteObject; //!< List of all object that we have a reference in the local interface.
public: public:
/**
* @brief Add a local WebObject to maage all his callback
* @param[in] _obj Object to add
*/
void addWebObj(ememory::SharedPtr<zeus::WebObj> _obj); void addWebObj(ememory::SharedPtr<zeus::WebObj> _obj);
/**
* @brief Add a REMOTE WebObject to maage all his callback
* @param[in] _obj Object to add
*/
void addWebObjRemote(ememory::SharedPtr<zeus::ObjectRemoteBase> _obj); void addWebObjRemote(ememory::SharedPtr<zeus::ObjectRemoteBase> _obj);
/**
* @brief Clear all Object that have no more remote user.
*/
void cleanDeadObject(); void cleanDeadObject();
/** /**
* @brief Set the list of interface that has been removed ... * @brief Set the list of interface that has been removed ...
*/ */
void interfaceRemoved(std::vector<uint16_t> _list); void interfaceRemoved(std::vector<uint16_t> _list);
private: private:
uint32_t m_interfaceId; uint32_t m_interfaceId; //!< local client interface ID
uint16_t m_transmissionId; uint16_t m_transmissionId; //!< Unique Id of a transmission (it is != 0)
/**
* @brief Get a new transmission ID
* @return Unique ID of the transmision
*/
uint16_t getId(); uint16_t getId();
std::mutex m_pendingCallMutex; std::mutex m_pendingCallMutex; //!< local call of a pendinc call venctor update
std::vector<std::pair<uint64_t, zeus::FutureBase>> m_pendingCall; std::vector<std::pair<uint64_t, zeus::FutureBase>> m_pendingCall; //!< List of pending call interface
public: public:
using Observer = std::function<void(ememory::SharedPtr<zeus::Message>)>; //!< Define an Observer: function pointer using Observer = std::function<void(ememory::SharedPtr<zeus::Message>)>; //!< Define an Observer: function pointer
Observer m_observerElement; Observer m_observerElement; //!< Observer on a new message arriving
/** /**
* @brief Connect an function member on the signal with the shared_ptr object. * @brief Connect an function member on the signal with the shared_ptr object.
* @param[in] _class shared_ptr Object on whe we need to call ==> the object is get in keeped in weak_ptr. * @param[in] _class shared_ptr Object on whe we need to call ==> the object is get in keeped in weak_ptr.
@ -162,7 +190,7 @@ namespace zeus {
public: public:
using ObserverRequestUri = std::function<bool(const std::string&)>; //!< Define an Observer on the specific URI requested callback: function pointer (return true if the connection is accepted or not) using ObserverRequestUri = std::function<bool(const std::string&)>; //!< Define an Observer on the specific URI requested callback: function pointer (return true if the connection is accepted or not)
protected: protected:
ObserverRequestUri m_observerRequestUri; ObserverRequestUri m_observerRequestUri; //!< Observer on a requesting URI connection
public: public:
/** /**
* @brief Connect on the URI requested. * @brief Connect on the URI requested.
@ -175,147 +203,141 @@ namespace zeus {
return (*_class.*_func)(_value); return (*_class.*_func)(_value);
}; };
} }
/**
* @brief Set the Observer on URI requesting
* @param[in] _func Observer function
*/
void connectUri(WebServer::ObserverRequestUri _func) { void connectUri(WebServer::ObserverRequestUri _func) {
m_observerRequestUri = _func; m_observerRequestUri = _func;
} }
public: public:
/** /**
* @brief * @brief Webserver contructor
* @param[in]
* @return
*/ */
WebServer(); // TODO : Set it in a factory to force the use of sharedPtr WebServer(); // TODO : Set it in a factory to force the use of sharedPtr
/** /**
* @brief * @brief Webserver contructor
* @param[in] * @param[in] _connection TCP connection interface
* @return * @param[in] _isServer Set it true if the local interface in a server
*/ */
WebServer(enet::Tcp _connection, bool _isServer); WebServer(enet::Tcp _connection, bool _isServer);
/** /**
* @brief * @brief Destructor
* @param[in]
* @return
*/ */
virtual ~WebServer(); virtual ~WebServer();
/** /**
* @brief * @brief Set the low level network interface
* @param[in] * @param[in] _connection TCP connection interface
* @param[in] _isServer Set it true if the local interface in a server
* @param[in] _userName Name on the user connected
* @return * @return
*/ */
void setInterface(enet::Tcp _connection, bool _isServer, const std::string& _userName=""); void setInterface(enet::Tcp _connection, bool _isServer, const std::string& _userName="");
/** /**
* @brief * @brief Connect on the remote interface
* @param[in] * @param[in] _async if true, the cunnection does not wait all the connection process is done to return
* @return
*/ */
void connect(bool _async = false); void connect(bool _async = false);
/** /**
* @brief * @brief Disconnect from the remote
* @param[in] * @param[in] _inThreadStop The call is done in the thread processing the input message
* @return
*/ */
void disconnect(bool _inThreadStop = false); void disconnect(bool _inThreadStop = false);
/** /**
* @brief * @brief Check if the link is alive
* @param[in] * @return true The connection is alive
* @return * @return false THe connection is dead
*/ */
bool isActive() const; bool isActive() const;
/** /**
* @brief * @brief set the interface name
* @param[in] * @param[in] _name Ne name of the interface
* @return
*/ */
void setInterfaceName(const std::string& _name); void setInterfaceName(const std::string& _name);
/** /**
* @brief * @brief Write a message preformated
* @param[in] * @param[in] _data Message to write
* @return * @return Number of byte written
*/ */
int32_t writeBinary(ememory::SharedPtr<zeus::Message> _data); int32_t writeBinary(ememory::SharedPtr<zeus::Message> _data);
/** /**
* @brief * @brief Send a ping to the remote connection
* @param[in]
* @return
*/ */
void ping(); void ping();
/** /**
* @brief * @brief Called by the underprotocol for a new URI connection
* @param[in] * @param[in] _uri URI connection (GET)
* @return * @param[in] _protocols Protocol requested in the URI (ZEUS:1.0/ZEUS:0.8)
* @return true the connection is accepted
* @return false the connection is rejected
*/ */
bool onReceiveUri(const std::string& _uri, const std::vector<std::string>& _protocols); bool onReceiveUri(const std::string& _uri, const std::vector<std::string>& _protocols);
/** /**
* @brief * @brief The Zeus protocol is based on a webSocket, then the connection can send full fragment (it call newMessage when data is parsed
* @param[in] * @param[in] _frame A frame that has been just received
* @return * @param[in] _isBinary the frame is binary if true, it is a string id false
*/ */
void onReceiveData(std::vector<uint8_t>& _frame, bool _isBinary); void onReceiveData(std::vector<uint8_t>& _frame, bool _isBinary);
/** /**
* @brief * @brief Receive a message to parse
* @param[in] * @param[in] _buffer Message to interprete
* @return
*/ */
void newMessage(ememory::SharedPtr<zeus::Message> _buffer); void newMessage(ememory::SharedPtr<zeus::Message> _buffer);
public: public:
/** /**
* @brief * @brief Get the last time a transmission has been done on the websocket (RECEIVE)
* @param[in] * @return Steady Time of the last transmission
* @return
*/ */
const echrono::Steady& getLastTimeReceive() { const echrono::Steady& getLastTimeReceive() {
return m_connection.getLastTimeReceive(); return m_connection.getLastTimeReceive();
} }
/** /**
* @brief * @brief Get the last time a transmission has been done on the websocket (EMIT)
* @param[in] * @return Steady Time of the last transmission
* @return
*/ */
const echrono::Steady& getLastTimeSend() { const echrono::Steady& getLastTimeSend() {
return m_connection.getLastTimeSend(); return m_connection.getLastTimeSend();
} }
private: private:
using ActionAsync = std::function<bool(WebServer* _interface)>; using ActionAsync = std::function<bool(WebServer* _interface)>; //!< type of the action for sending big data on the websocket
std::mutex m_threadAsyncMutex; std::mutex m_threadAsyncMutex; //!< Mutex fot the thread to send async data
std::thread* m_threadAsync; std::thread* m_threadAsync; //!< sending async data thread. TODO: Set it in a thread pool ...
bool m_threadAsyncRunning; bool m_threadAsyncRunning; //!< Threa is running
std::vector<ActionAsync> m_threadAsyncList; std::vector<ActionAsync> m_threadAsyncList; //!< List of action to send (current)
std::vector<ActionAsync> m_threadAsyncList2; std::vector<ActionAsync> m_threadAsyncList2; //!< list of action to send whenwurrent is sending in progress
// TODO: Abord async sender ...
private: private:
/** /**
* @brief * @brief Thread callback to send data
* @param[in]
* @return
*/ */
void threadAsyncCallback(); void threadAsyncCallback();
public: public:
/** /**
* @brief * @brief Add an async data to send
* @param[in] * @param[in] _elem Action lambda to send data
* @return
*/ */
void addAsync(ActionAsync _elem); void addAsync(ActionAsync _elem);
private: private:
/** /**
* @brief * @brief Add a message in the list of data that might be sended
* @param[in] * @param[in] _obj Message to send
* @return * @return Future that will get the return values
*/ */
zeus::FutureBase callBinary(uint64_t _transactionId, zeus::FutureBase callBinary(ememory::SharedPtr<zeus::Message> _obj);
ememory::SharedPtr<zeus::Message> _obj,
const uint32_t& _service=0);
public: public:
/** /**
* @brief * @brief Create a call with specific parameteurs
* @param[in] * @param[in] _source Source Id of the sending value
* @return * @param[in] _destination Destinatio of the progression
* @param[in] _functionName Function name to call
* @param[in] _args... Argument to add on the current message
* @return Future that will get the return values
*/ */
template<class... _ARGS> template<class... _ARGS>
zeus::FutureBase call(const uint32_t& _source, const uint32_t& _destination, const std::string& _functionName, _ARGS&&... _args) { zeus::FutureBase call(const uint32_t& _source, const uint32_t& _destination, const std::string& _functionName, _ARGS&&... _args) {
uint16_t id = getId(); uint16_t id = getId();
ememory::SharedPtr<zeus::message::Call> callElem = zeus::createCall(sharedFromThis(), id, _source, _destination, _functionName, std::forward<_ARGS>(_args)...); ememory::SharedPtr<zeus::message::Call> callElem = zeus::createCall(sharedFromThis(), id, _source, _destination, _functionName, std::forward<_ARGS>(_args)...);
return callBinary(id, callElem); return callBinary(callElem);
} }
public: // Events ... public: // Events ...
/** /**
@ -336,9 +358,9 @@ namespace zeus {
} }
public: // answers ... public: // answers ...
/** /**
* @brief * @brief Create an ansers with PROTOCLL error and an help
* @param[in] * @param[in] _transactionId Current trasaction ID
* @return * @param[in] _errorHelp Help for the user to understand the error and correct it
*/ */
void answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp); void answerProtocolError(uint32_t _transactionId, const std::string& _errorHelp);
/** /**
@ -371,9 +393,27 @@ namespace zeus {
*/ */
void answerError(uint32_t _clientTransactionId, uint32_t _source, uint32_t _destination, const std::string& _errorValue, const std::string& _errorComment=""); void answerError(uint32_t _clientTransactionId, uint32_t _source, uint32_t _destination, const std::string& _errorValue, const std::string& _errorComment="");
public: public:
// for debug only: /**
* @brief Display list of all objects
* @note For debug only
*/
void listObjects(); void listObjects();
/**
* @brief Transfer the remote object onership from an adress to an other
* @param[in] _objectAddress Local interface object address (uID)
* @param[in] _sourceAddress Remote object to change the address
* @param[in] _destinataireAddress New adress that replace the _sourceAddress
* @return true The onership has been changed
* @return false An error apears
*/
bool transferRemoteObjectOwnership(uint16_t _objectAddress, uint32_t _sourceAddress, uint32_t _destinataireAddress); bool transferRemoteObjectOwnership(uint16_t _objectAddress, uint32_t _sourceAddress, uint32_t _destinataireAddress);
/**
* @brief Remove a local object dependence on a remote object ==> permit to the server to remove it
* @param[in] _objectAddress Local interface object address (uID)
* @param[in] _sourceAddress Remote object that the adress must be removed
* @return true The onership has been removed
* @return false An error apears
*/
bool removeObjectOwnership(uint16_t _objectAddress, uint32_t _sourceAddress); bool removeObjectOwnership(uint16_t _objectAddress, uint32_t _sourceAddress);
}; };
} }