Skip to content

Replace custom SingleLinkedList with std::list #130

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 33 additions & 23 deletions src/cbor/ArduinoCloudProperty.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@

#include "ArduinoCloudProperty.h"

#undef max
#undef min
#include <algorithm>

#ifndef ARDUINO_ARCH_SAMD
#pragma message "No RTC available on this architecture - ArduinoIoTCloud will not keep track of local change timestamps ."
#endif
Expand All @@ -38,7 +42,6 @@ ArduinoCloudProperty::ArduinoCloudProperty()
_update_interval_millis(0),
_last_local_change_timestamp(0),
_last_cloud_change_timestamp(0),
_map_data_list(nullptr),
_identifier(0),
_attributeIdentifier(0),
_lightPayload(false) {
Expand Down Expand Up @@ -174,7 +177,7 @@ void ArduinoCloudProperty::appendAttributeName(String attributeName, std::functi
cbor_encoder_close_container(encoder, &mapEncoder);
}

void ArduinoCloudProperty::setAttributesFromCloud(LinkedList<CborMapData *> *map_data_list) {
void ArduinoCloudProperty::setAttributesFromCloud(std::list<CborMapData *> * map_data_list) {
_map_data_list = map_data_list;
_attributeIdentifier = 0;
setAttributesFromCloud();
Expand Down Expand Up @@ -215,31 +218,38 @@ void ArduinoCloudProperty::setAttributeReal(String& value, String attributeName)
});
}

void ArduinoCloudProperty::setAttributeReal(String attributeName, std::function<void (CborMapData *md)>setValue) {
void ArduinoCloudProperty::setAttributeReal(String attributeName, std::function<void (CborMapData *md)>setValue)
{
if (attributeName != "") {
_attributeIdentifier++;
}
for (int i = 0; i < _map_data_list->size(); i++) {
CborMapData *map = _map_data_list->get(i);
if (map != nullptr) {
if (map->light_payload.isSet() && map->light_payload.get()) {
// if a light payload is detected, the attribute identifier is retrieved from the cbor map and the corresponding attribute is updated
int attid = map->attribute_identifier.get();
if (attid == _attributeIdentifier) {
setValue(map);
break;
}
} else {
// if a normal payload is detected, the name of the attribute to be updated is extracted directly from the cbor map
String an = map->attribute_name.get();
if (an == attributeName) {
setValue(map);
break;
}
}
}
}

std::for_each(_map_data_list->begin(),
_map_data_list->end(),
[this, attributeName, setValue](CborMapData * map)
{
if (map != nullptr)
{
if (map->light_payload.isSet() && map->light_payload.get())
{
// if a light payload is detected, the attribute identifier is retrieved from the cbor map and the corresponding attribute is updated
int attid = map->attribute_identifier.get();
if (attid == _attributeIdentifier) {
setValue(map);
return;
}
}
else
{
// if a normal payload is detected, the name of the attribute to be updated is extracted directly from the cbor map
String an = map->attribute_name.get();
if (an == attributeName) {
setValue(map);
return;
}
}
}
});
}

String ArduinoCloudProperty::getAttributeName(String propertyName, char separator) {
Expand Down
7 changes: 3 additions & 4 deletions src/cbor/ArduinoCloudProperty.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,14 @@
INCLUDE
******************************************************************************/


#include <Arduino.h>
// in order to allow <functional> to define its own max and min functions
#undef max
#undef min
#include <list>
#include <functional>

#include "lib/tinycbor/cbor-lib.h"
#include "lib/LinkedList/LinkedList.h"

#define appendAttributesToCloud() appendAttributesToCloudReal(CborEncoder *encoder)
#define appendAttribute(x) appendAttributeReal(x, getAttributeName(#x, '.'), encoder)
Expand Down Expand Up @@ -169,7 +168,7 @@ class ArduinoCloudProperty {
void appendAttributeReal(float value, String attributeName = "", CborEncoder *encoder = nullptr);
void appendAttributeReal(String value, String attributeName = "", CborEncoder *encoder = nullptr);
void appendAttributeName(String attributeName, std::function<void (CborEncoder& mapEncoder)>f, CborEncoder *encoder);
void setAttributesFromCloud(LinkedList<CborMapData *> *map_data_list);
void setAttributesFromCloud(std::list<CborMapData *> * map_data_list);
void setAttributeReal(bool& value, String attributeName = "");
void setAttributeReal(int& value, String attributeName = "");
void setAttributeReal(float& value, String attributeName = "");
Expand Down Expand Up @@ -206,7 +205,7 @@ class ArduinoCloudProperty {
/* Variables used for reconnection sync*/
unsigned long _last_local_change_timestamp;
unsigned long _last_cloud_change_timestamp;
LinkedList<CborMapData *> * _map_data_list;
std::list<CborMapData *> * _map_data_list;
/* Store the identifier of the property in the array list */
int _identifier;
int _attributeIdentifier;
Expand Down
123 changes: 73 additions & 50 deletions src/cbor/ArduinoCloudThing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@

#include <Arduino.h>

#undef max
#undef min
#include <algorithm>

#include "ArduinoCloudThing.h"

/******************************************************************************
Expand Down Expand Up @@ -157,61 +161,78 @@ void ArduinoCloudThing::decode(uint8_t const * const payload, size_t const lengt
}
}

bool ArduinoCloudThing::isPropertyInContainer(String const & name) {
for (int i = 0; i < _property_list.size(); i++) {
ArduinoCloudProperty * p = _property_list.get(i);
if (p->name() == name) {
return true;
}
}
return false;
bool ArduinoCloudThing::isPropertyInContainer(String const & name)
{
return (getProperty(name) != nullptr);
}

int ArduinoCloudThing::appendChangedProperties(CborEncoder * arrayEncoder, bool lightPayload) {
int ArduinoCloudThing::appendChangedProperties(CborEncoder * arrayEncoder, bool lightPayload)
{
int appendedProperties = 0;
for (int i = 0; i < _property_list.size(); i++) {
ArduinoCloudProperty * p = _property_list.get(i);
if (p->shouldBeUpdated() && p->isReadableByCloud()) {
p->append(arrayEncoder, lightPayload);
appendedProperties++;
}
}
std::for_each(_property_list.begin(),
_property_list.end(),
[arrayEncoder, lightPayload, &appendedProperties](ArduinoCloudProperty * p)
{
if (p->shouldBeUpdated() && p->isReadableByCloud())
{
p->append(arrayEncoder, lightPayload);
appendedProperties++;
}
});
return appendedProperties;
}

//retrieve property by name
ArduinoCloudProperty * ArduinoCloudThing::getProperty(String const & name) {
for (int i = 0; i < _property_list.size(); i++) {
ArduinoCloudProperty * p = _property_list.get(i);
if (p->name() == name) {
return p;
}
}
return NULL;
ArduinoCloudProperty * ArduinoCloudThing::getProperty(String const & name)
{
std::list<ArduinoCloudProperty *>::iterator iter;

iter = std::find_if(_property_list.begin(),
_property_list.end(),
[name](ArduinoCloudProperty * p) -> bool
{
return (p->name() == name);
});

if (iter == _property_list.end())
return nullptr;
else
return (*iter);
}

//retrieve property by identifier
ArduinoCloudProperty * ArduinoCloudThing::getProperty(int const & pos) {
for (int i = 0; i < _property_list.size(); i++) {
ArduinoCloudProperty * p = _property_list.get(i);
if (p->identifier() == pos) {
return p;
}
}
return NULL;
ArduinoCloudProperty * ArduinoCloudThing::getProperty(int const & pos)
{
std::list<ArduinoCloudProperty *>::iterator iter;

iter = std::find_if(_property_list.begin(),
_property_list.end(),
[pos](ArduinoCloudProperty * p) -> bool
{
return (p->identifier() == pos);
});

if (iter == _property_list.end())
return nullptr;
else
return (*iter);
}

// this function updates the timestamps on the primitive properties that have been modified locally since last cloud synchronization
void ArduinoCloudThing::updateTimestampOnLocallyChangedProperties() {
if (_numPrimitivesProperties == 0) {
return;
} else {
for (int i = 0; i < _property_list.size(); i++) {
CloudWrapperBase * p = (CloudWrapperBase *)_property_list.get(i);
if (p->isPrimitive() && p->isChangedLocally() && p->isReadableByCloud()) {
p->updateLocalTimestamp();
}
}
void ArduinoCloudThing::updateTimestampOnLocallyChangedProperties()
{
if (_numPrimitivesProperties > 0)
{
std::for_each(_property_list.begin(),
_property_list.end(),
[](ArduinoCloudProperty * p)
{
CloudWrapperBase * pbase = reinterpret_cast<CloudWrapperBase *>(p);
if (pbase->isPrimitive() && pbase->isChangedLocally() && pbase->isReadableByCloud())
{
p->updateLocalTimestamp();
}
});
}
}

Expand Down Expand Up @@ -448,7 +469,6 @@ ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_LeaveMap(CborValue *
updateProperty(_currentPropertyName, _currentPropertyBaseTime + _currentPropertyTime);
/* Reset current property data */
freeMapDataList(&_map_data_list);
_map_data_list.clear();
_currentPropertyBaseTime = 0;
_currentPropertyTime = 0;
}
Expand All @@ -459,7 +479,7 @@ ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_LeaveMap(CborValue *
if (map_data->time.isSet() && (map_data->time.get() > _currentPropertyTime)) {
_currentPropertyTime = (unsigned long)map_data->time.get();
}
_map_data_list.add(map_data);
_map_data_list.push_back(map_data);
_currentPropertyName = propertyName;
}

Expand All @@ -472,19 +492,22 @@ ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_LeaveMap(CborValue *
updateProperty(_currentPropertyName, _currentPropertyBaseTime + _currentPropertyTime);
/* Reset last property data */
freeMapDataList(&_map_data_list);
_map_data_list.clear();
next_state = MapParserState::Complete;
}
}

return next_state;
}

void ArduinoCloudThing::freeMapDataList(LinkedList<CborMapData *> *map_data_list) {
while (map_data_list->size() > 0) {
CborMapData const * mapData = map_data_list->pop();
delete mapData;
}
void ArduinoCloudThing::freeMapDataList(std::list<CborMapData *> * map_data_list)
{
std::for_each(map_data_list->begin(),
map_data_list->end(),
[](CborMapData * map_data)
{
delete map_data;
});
map_data_list->clear();
}

void ArduinoCloudThing::updateProperty(String propertyName, unsigned long cloudChangeEventTime) {
Expand Down
14 changes: 9 additions & 5 deletions src/cbor/ArduinoCloudThing.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,12 @@
INCLUDE
******************************************************************************/

#undef max
#undef min
#include <list>

#include "ArduinoCloudProperty.h"
#include "lib/LinkedList/LinkedList.h"

#include "types/CloudBool.h"
#include "types/CloudFloat.h"
#include "types/CloudInt.h"
Expand Down Expand Up @@ -95,14 +99,14 @@ class ArduinoCloudThing {

private:
GetTimeCallbackFunc _get_time_func;
LinkedList<ArduinoCloudProperty *> _property_list;
std::list<ArduinoCloudProperty *> _property_list;
/* Keep track of the number of primitive properties in the Thing. If 0 it allows the early exit in updateTimestampOnLocallyChangedProperties() */
int _numPrimitivesProperties;
int _numProperties;
/* Indicates the if the message received to be decoded is a response to the getLastValues inquiry */
bool _isSyncMessage;
/* List of map data that will hold all the attributes of a property */
LinkedList<CborMapData *> _map_data_list;
std::list<CborMapData *> _map_data_list;
/* Current property name during decoding: use to look for a new property in the senml value array */
String _currentPropertyName;
unsigned long _currentPropertyBaseTime,
Expand Down Expand Up @@ -140,15 +144,15 @@ class ArduinoCloudThing {

static bool ifNumericConvertToDouble(CborValue * value_iter, double * numeric_val);
static double convertCborHalfFloatToDouble(uint16_t const half_val);
void freeMapDataList(LinkedList<CborMapData *> * map_data_list);
void freeMapDataList(std::list<CborMapData *> * map_data_list);
inline void addProperty(ArduinoCloudProperty * property_obj, int propertyIdentifier) {
if (propertyIdentifier != -1) {
property_obj->setIdentifier(propertyIdentifier);
} else {
// if property identifier is -1, an incremental value will be assigned as identifier.
property_obj->setIdentifier(_numProperties);
}
_property_list.add(property_obj);
_property_list.push_back(property_obj);
}
ArduinoCloudProperty * getProperty(String const & name);
ArduinoCloudProperty * getProperty(int const & identifier);
Expand Down
21 changes: 0 additions & 21 deletions src/cbor/lib/LinkedList/LICENSE.txt

This file was deleted.

Loading