class LockGuard;
- typedef std::function < RCSGetResponse(const RCSRequest &,
- RCSResourceAttributes &) > GetRequestHandler;
- typedef std::function < RCSSetResponse(const RCSRequest &,
- RCSResourceAttributes &) > SetRequestHandler;
+ typedef std::function < RCSGetResponse(const RCSRequest&,
+ RCSResourceAttributes&) > GetRequestHandler;
+ typedef std::function < RCSSetResponse(const RCSRequest&,
+ RCSResourceAttributes&) > SetRequestHandler;
- typedef std::function < void(const RCSResourceAttributes::Value &,
+ typedef std::function < void(const RCSResourceAttributes::Value&,
const RCSResourceAttributes::Value &) > AttributeUpdatedListener;
public:
RCSResourceObject(RCSResourceObject&&) = delete;
- RCSResourceObject(const RCSResourceObject &) = delete;
+ RCSResourceObject(const RCSResourceObject&) = delete;
- RCSResourceObject &operator=(RCSResourceObject && ) = delete;
- RCSResourceObject &operator=(const RCSResourceObject &) = delete;
+ RCSResourceObject& operator=(RCSResourceObject&&) = delete;
+ RCSResourceObject& operator=(const RCSResourceObject&) = delete;
virtual ~RCSResourceObject();
*
* @note It is guaranteed thread-safety about attributes.
*/
- void setAttribute(const std::string &key, const RCSResourceAttributes::Value & value);
+ void setAttribute(const std::string& key, const RCSResourceAttributes::Value& value);
/**
* @overload
*/
- void setAttribute(const std::string &key, RCSResourceAttributes::Value&& value);
+ void setAttribute(const std::string& key, RCSResourceAttributes::Value&& value);
/**
* @overload
*/
- void setAttribute(std::string&& key, const RCSResourceAttributes::Value & value);
+ void setAttribute(std::string&& key, const RCSResourceAttributes::Value& value);
/**
* @overload
* @throw InvalidKeyException
* Throw exception when empty string is provided as Attribute key.
*/
- RCSResourceAttributes::Value getAttributeValue(const std::string &key) const;
+ RCSResourceAttributes::Value getAttributeValue(const std::string& key) const;
/**
* API for retrieving the attribute value associated with the supplied name.
* It is guaranteed thread-safety about attributes.
*/
template< typename T >
- T getAttribute(const std::string &key) const
+ T getAttribute(const std::string& key) const
{
WeakGuard lock(*this);
return m_resourceAttributes.at(key).get< T >();
*
* It is guaranteed thread-safety about attributes.
*/
- bool removeAttribute(const std::string &key);
+ bool removeAttribute(const std::string& key);
/**
* API for checking whether a particular attribute is there for a resource or not.
*
* It is guaranteed thread-safety about attributes.
*/
- bool containsAttribute(const std::string &key) const;
+ bool containsAttribute(const std::string& key) const;
/**
* API for getting all the attributes of the RCSResourceObject.
* @throw NoLockException
* If you don't do lock with LockGuard, throw exception.
*/
- RCSResourceAttributes &getAttributes();
+ RCSResourceAttributes& getAttributes();
/**
* @overload
*/
- const RCSResourceAttributes &getAttributes() const;
+ const RCSResourceAttributes& getAttributes() const;
/**
* API for checking whether the particular resource is observable or not
* @param listener Listener for updation of the interested attribute
*
*/
- virtual void addAttributeUpdatedListener(const std::string &key,
+ virtual void addAttributeUpdatedListener(const std::string& key,
AttributeUpdatedListener listener);
/**
* @param listener Listener for updation of the interested attribute
*
*/
- virtual void addAttributeUpdatedListener(std::string &&key,
+ virtual void addAttributeUpdatedListener(std::string&& key,
AttributeUpdatedListener listener);
/**
* @param key The interested attribute's key
*
*/
- virtual bool removeAttributeUpdatedListener(const std::string &key);
+ virtual bool removeAttributeUpdatedListener(const std::string& key);
/**
* API for notifying all observers of the RCSResourceObject
OCEntityHandlerResult handleObserve(std::shared_ptr< OC::OCResourceRequest >);
void expectOwnLock() const;
+
void autoNotify(bool, AutoNotifyPolicy) const;
- void autoNotifyIfNeeded(const std::string& , const RCSResourceAttributes::Value& );
+ void autoNotify(bool) const;
+
+ bool testValueUpdated(const std::string&, const RCSResourceAttributes::Value&) const;
+
+ template< typename K, typename V >
+ void setAttributeInternal(K&&, V&&);
private:
const uint8_t m_properties;
OC::EntityHandler entityHandler{ std::bind(&RCSResourceObject::entityHandler,
server.get(), std::placeholders::_1) };
- try
- {
- typedef OCStackResult (*RegisterResource)(OCResourceHandle&, std::string&,
- const std::string&, const std::string&, OC::EntityHandler, uint8_t);
+ typedef OCStackResult (*RegisterResource)(OCResourceHandle&, std::string&,
+ const std::string&, const std::string&, OC::EntityHandler, uint8_t);
- invokeOCFunc(static_cast<RegisterResource>(OC::OCPlatform::registerResource),
- handle, m_uri, m_type, m_interface, entityHandler, m_properties);
- }
- catch (OC::OCException& e)
- {
- throw PlatformException(e.code());
- }
+ invokeOCFunc(static_cast<RegisterResource>(OC::OCPlatform::registerResource),
+ handle, m_uri, m_type, m_interface, entityHandler, m_properties);
server->m_resourceHandle = handle;
}
}
- void RCSResourceObject::setAttribute(const std::string& key,
- const RCSResourceAttributes::Value& value)
+ template< typename K, typename V >
+ void RCSResourceObject::setAttributeInternal(K&& key, V&& value)
{
- WeakGuard lock(*this);
+ bool needToNotify = false;
+ bool valueUpdated = false;
- if(lock.hasLocked())
{
- autoNotifyIfNeeded(key, value);
+ WeakGuard lock(*this);
+
+ if (lock.hasLocked())
+ {
+ needToNotify = true;
+ valueUpdated = testValueUpdated(key, value);
+ }
+
+ m_resourceAttributes[std::forward< K >(key)] = std::forward< V >(value);
}
- m_resourceAttributes[key] = value;
+ if (needToNotify) autoNotify(valueUpdated);
+ }
+ void RCSResourceObject::setAttribute(const std::string& key,
+ const RCSResourceAttributes::Value& value)
+ {
+ setAttributeInternal(key, value);
}
void RCSResourceObject::setAttribute(const std::string& key,
RCSResourceAttributes::Value&& value)
{
- WeakGuard lock(*this);
-
- if(lock.hasLocked())
- {
- autoNotifyIfNeeded(key, value);
- }
-
- m_resourceAttributes[key] = std::move(value);
+ setAttributeInternal(key, std::move(value));
}
void RCSResourceObject::setAttribute(std::string&& key,
const RCSResourceAttributes::Value& value)
{
- WeakGuard lock(*this);
-
- if(lock.hasLocked())
- {
- autoNotifyIfNeeded(key, value);
- }
-
- m_resourceAttributes[std::move(key)] = value;
+ setAttributeInternal(std::move(key), value);
}
void RCSResourceObject::setAttribute(std::string&& key,
RCSResourceAttributes::Value&& value)
{
- WeakGuard lock(*this);
-
- if(lock.hasLocked())
- {
- autoNotifyIfNeeded(key, value);
- }
-
- m_resourceAttributes[std::move(key)] = std::move(value);
+ setAttributeInternal(std::move(key), std::move(value));
}
RCSResourceAttributes::Value RCSResourceObject::getAttributeValue(
bool RCSResourceObject::removeAttribute(const std::string& key)
{
- WeakGuard lock(*this);
- if (m_resourceAttributes.erase(key))
+ bool needToNotify = false;
+ bool erased = false;
{
- autoNotify(true, getAutoNotifyPolicy());
- return true;
+ WeakGuard lock(*this);
+
+ if (m_resourceAttributes.erase(key))
+ {
+ erased = true;
+ needToNotify = lock.hasLocked();
+ }
}
- return false;
+
+ if (needToNotify) autoNotify(true);
+
+ return erased;
}
bool RCSResourceObject::containsAttribute(const std::string& key) const
{
typedef OCStackResult (*NotifyAllObservers)(OCResourceHandle);
- invokeOCFuncWithResultExpect(
- { OC_STACK_OK, OC_STACK_NO_OBSERVERS },
+ invokeOCFuncWithResultExpect({ OC_STACK_OK, OC_STACK_NO_OBSERVERS },
static_cast< NotifyAllObservers >(OC::OCPlatform::notifyAllObservers),
m_resourceHandle);
}
bool RCSResourceObject::removeAttributeUpdatedListener(const std::string& key)
{
std::lock_guard<std::mutex> lock(m_mutexKeyAttributeUpdate);
- return (bool) m_keyAttributesUpdatedListeners.erase(key);
+
+ return m_keyAttributesUpdatedListeners.erase(key) != 0;
}
- void RCSResourceObject::autoNotifyIfNeeded(const std::string& key,
- const RCSResourceAttributes::Value& value)
+ bool RCSResourceObject::testValueUpdated(const std::string& key,
+ const RCSResourceAttributes::Value& value) const
{
- autoNotify( m_resourceAttributes.contains(key) == false
- || m_resourceAttributes.at(key) != value
- , m_autoNotifyPolicy);
+ return m_resourceAttributes.contains(key) == false
+ || m_resourceAttributes.at(key) != value;
}
void RCSResourceObject::setAutoNotifyPolicy(AutoNotifyPolicy policy)
return m_setRequestHandlerPolicy;
}
+ void RCSResourceObject::autoNotify(bool isAttributesChanged) const
+ {
+ autoNotify(isAttributesChanged, m_autoNotifyPolicy);
+ }
+
void RCSResourceObject::autoNotify(
bool isAttributesChanged, AutoNotifyPolicy autoNotifyPolicy) const
{
if(autoNotifyPolicy == AutoNotifyPolicy::NEVER) return;
- if(autoNotifyPolicy == AutoNotifyPolicy::UPDATED && isAttributesChanged == false) return;
+ if(autoNotifyPolicy == AutoNotifyPolicy::UPDATED &&
+ isAttributesChanged == false) return;
+
notify();
}
RCSResourceObject::LockGuard::LockGuard(
const RCSResourceObject& resourceObject, AutoNotifyPolicy autoNotifyPolicy) :
- m_resourceObject(resourceObject),
- m_autoNotifyPolicy { autoNotifyPolicy },
- m_isOwningLock{ false }
+ m_resourceObject(resourceObject),
+ m_autoNotifyPolicy { autoNotifyPolicy },
+ m_isOwningLock{ false }
{
init();
}
if (resourceObject.m_lockOwner != std::this_thread::get_id())
{
m_resourceObject.m_mutex.lock();
+ m_resourceObject.m_lockOwner = std::this_thread::get_id();
m_isOwningLock = true;
}
}
{
if (m_isOwningLock)
{
+ m_resourceObject.m_lockOwner = std::thread::id{ };
m_resourceObject.m_mutex.unlock();
}
}