From ce1df18d30b552d3bfb50a02a7dec1aa1514230d Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Thu, 4 Jun 2020 07:34:54 +0200 Subject: [PATCH 1/2] Delete custom LinkedList implementation (why bother if we've got STL which is definitely more efficient and definitely correct) --- src/cbor/lib/LinkedList/LICENSE.txt | 21 -- src/cbor/lib/LinkedList/LinkedList.h | 325 --------------------- src/cbor/lib/LinkedList/README.md | 171 ----------- src/cbor/lib/LinkedList/keywords.txt | 28 -- src/cbor/lib/LinkedList/library.json | 12 - src/cbor/lib/LinkedList/library.properties | 9 - 6 files changed, 566 deletions(-) delete mode 100644 src/cbor/lib/LinkedList/LICENSE.txt delete mode 100644 src/cbor/lib/LinkedList/LinkedList.h delete mode 100644 src/cbor/lib/LinkedList/README.md delete mode 100644 src/cbor/lib/LinkedList/keywords.txt delete mode 100644 src/cbor/lib/LinkedList/library.json delete mode 100644 src/cbor/lib/LinkedList/library.properties diff --git a/src/cbor/lib/LinkedList/LICENSE.txt b/src/cbor/lib/LinkedList/LICENSE.txt deleted file mode 100644 index 5c02604a0..000000000 --- a/src/cbor/lib/LinkedList/LICENSE.txt +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 Ivan Seidel - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/src/cbor/lib/LinkedList/LinkedList.h b/src/cbor/lib/LinkedList/LinkedList.h deleted file mode 100644 index 237849285..000000000 --- a/src/cbor/lib/LinkedList/LinkedList.h +++ /dev/null @@ -1,325 +0,0 @@ -/* - LinkedList.h - V1.1 - Generic LinkedList implementation - Works better with FIFO, because LIFO will need to - search the entire List to find the last one; - - For instructions, go to https://github.com/ivanseidel/LinkedList - - Created by Ivan Seidel Gomes, March, 2013. - Released into the public domain. -*/ - - -#ifndef LinkedList_h -#define LinkedList_h - -#include - -template -struct ListNode -{ - T data; - ListNode *next; -}; - -template -class LinkedList{ - -protected: - int _size; - ListNode *root; - ListNode *last; - - // Helps "get" method, by saving last position - ListNode *lastNodeGot; - int lastIndexGot; - // isCached should be set to FALSE - // everytime the list suffer changes - bool isCached; - - ListNode* getNode(int index); - -public: - LinkedList(); - ~LinkedList(); - - /* - Returns current size of LinkedList - */ - virtual int size(); - /* - Adds a T object in the specified index; - Unlink and link the LinkedList correcly; - Increment _size - */ - virtual bool add(int index, T); - /* - Adds a T object in the end of the LinkedList; - Increment _size; - */ - virtual bool add(T); - /* - Adds a T object in the start of the LinkedList; - Increment _size; - */ - virtual bool unshift(T); - /* - Set the object at index, with T; - Increment _size; - */ - virtual bool set(int index, T); - /* - Remove object at index; - If index is not reachable, returns false; - else, decrement _size - */ - virtual T remove(int index); - /* - Remove last object; - */ - virtual T pop(); - /* - Remove first object; - */ - virtual T shift(); - /* - Get the index'th element on the list; - Return Element if accessible, - else, return false; - */ - virtual T get(int index); - - /* - Clear the entire array - */ - virtual void clear(); - -}; - -// Initialize LinkedList with false values -template -LinkedList::LinkedList() -{ - root=NULL; - last=NULL; - _size=0; - - lastNodeGot = root; - lastIndexGot = 0; - isCached = false; -} - -// Clear Nodes and free Memory -template -LinkedList::~LinkedList() -{ - ListNode* tmp; - while(root!=NULL) - { - tmp=root; - root=root->next; - delete tmp; - } - last = NULL; - _size=0; - isCached = false; -} - -/* - Actualy "logic" coding -*/ - -template -ListNode* LinkedList::getNode(int index){ - - int _pos = 0; - ListNode* current = root; - - // Check if the node trying to get is - // immediatly AFTER the previous got one - if(isCached && lastIndexGot <= index){ - _pos = lastIndexGot; - current = lastNodeGot; - } - - while(_pos < index && current){ - current = current->next; - - _pos++; - } - - // Check if the object index got is the same as the required - if(_pos == index){ - isCached = true; - lastIndexGot = index; - lastNodeGot = current; - - return current; - } - - return NULL; -} - -template -int LinkedList::size(){ - return _size; -} - -template -bool LinkedList::add(int index, T _t){ - - if(index >= _size) - return add(_t); - - if(index == 0) - return unshift(_t); - - ListNode *tmp = new ListNode(), - *_prev = getNode(index-1); - tmp->data = _t; - tmp->next = _prev->next; - _prev->next = tmp; - - _size++; - isCached = false; - - return true; -} - -template -bool LinkedList::add(T _t){ - - ListNode *tmp = new ListNode(); - tmp->data = _t; - tmp->next = NULL; - - if(root){ - // Already have elements inserted - last->next = tmp; - last = tmp; - }else{ - // First element being inserted - root = tmp; - last = tmp; - } - - _size++; - isCached = false; - - return true; -} - -template -bool LinkedList::unshift(T _t){ - - if(_size == 0) - return add(_t); - - ListNode *tmp = new ListNode(); - tmp->next = root; - tmp->data = _t; - root = tmp; - - _size++; - isCached = false; - - return true; -} - -template -bool LinkedList::set(int index, T _t){ - // Check if index position is in bounds - if(index < 0 || index >= _size) - return false; - - getNode(index)->data = _t; - return true; -} - -template -T LinkedList::pop(){ - if(_size <= 0) - return T(); - - isCached = false; - - if(_size >= 2){ - ListNode *tmp = getNode(_size - 2); - T ret = tmp->next->data; - delete(tmp->next); - tmp->next = NULL; - last = tmp; - _size--; - return ret; - }else{ - // Only one element left on the list - T ret = root->data; - delete(root); - root = NULL; - last = NULL; - _size = 0; - return ret; - } -} - -template -T LinkedList::shift(){ - if(_size <= 0) - return T(); - - if(_size > 1){ - ListNode *_next = root->next; - T ret = root->data; - delete(root); - root = _next; - _size --; - isCached = false; - - return ret; - }else{ - // Only one left, then pop() - return pop(); - } - -} - -template -T LinkedList::remove(int index){ - if (index < 0 || index >= _size) - { - return T(); - } - - if(index == 0) - return shift(); - - if (index == _size-1) - { - return pop(); - } - - ListNode *tmp = getNode(index - 1); - ListNode *toDelete = tmp->next; - T ret = toDelete->data; - tmp->next = tmp->next->next; - delete(toDelete); - _size--; - isCached = false; - return ret; -} - - -template -T LinkedList::get(int index){ - ListNode *tmp = getNode(index); - - return (tmp ? tmp->data : T()); -} - -template -void LinkedList::clear(){ - while(size() > 0) - shift(); -} - -#endif diff --git a/src/cbor/lib/LinkedList/README.md b/src/cbor/lib/LinkedList/README.md deleted file mode 100644 index bdb16fdbd..000000000 --- a/src/cbor/lib/LinkedList/README.md +++ /dev/null @@ -1,171 +0,0 @@ -# LinkedList - -This library was developed targeting **`Arduino`** applications. However, works just great with any C++. - -Implementing a buffer for objects takes time. If we are not in the mood, we just create an `array[1000]` with enough size. - -The objective of this library is to create a pattern for projects. -If you need to use a List of: `int`, `float`, `objects`, `Lists` or `Wales`. **This is what you are looking for.** - -With a simple but powerful caching algorithm, you can get subsequent objects much faster than usual. Tested without any problems with Lists bigger than 2000 members. - -## Installation - -1. [Download](https://github.com/ivanseidel/LinkedList/archive/master.zip) the Latest release from gitHub. -2. Unzip and modify the Folder name to "LinkedList" (Remove the '-version') -3. Paste the modified folder on your Library folder (On your `Libraries` folder inside Sketchbooks or Arduino software). -4. Reopen the Arduino software. - -**If you are here, because another Library requires this class, just don't waste time reading bellow. Install and ready.** - -------------------------- - -## Getting started - -### The `LinkedList` class - -In case you don't know what a LinkedList is and what it's used for, take a quick look at [Wikipedia::LinkedList](https://en.wikipedia.org/wiki/Linked_list) before continuing. - -#### To declare a LinkedList object -```c++ -// Instantiate a LinkedList that will hold 'integer' -LinkedList myLinkedList = LinkedList(); - -// Or just this -LinkedList myLinkedList; - -// But if you are instantiating a pointer LinkedList... -LinkedList *myLinkedList = new LinkedList(); - -// If you want a LinkedList with any other type such as 'MyClass' -// Make sure you call delete(MyClass) when you remove! -LinkedList *myLinkedList = new LinkedList(); -``` - -#### Getting the size of the linked list -```c++ -// To get the size of a linked list, make use of the size() method -int theSize = myList.size(); - -// Notice that if it's pointer to the linked list, you should use -> instead -int theSize = myList->size(); -``` - -#### Adding elements - -```c++ -// add(obj) method will insert at the END of the list -myList.add(myObject); - -// add(index, obj) method will try to insert the object at the specified index -myList.add(0, myObject); // Add at the beginning -myList.add(3, myObject); // Add at index 3 - -// unshift(obj) method will insert the object at the beginning -myList.unshift(myObject); -``` - -#### Getting elements - -```c++ -// get(index) will return the element at index -// (notice that the start element is 0, not 1) - -// Get the FIRST element -myObject = myList.get(0); - -// Get the third element -myObject = myList.get(2); - -// Get the LAST element -myObject = myList.get(myList.size() - 1); -``` - -#### Changing elements -```c++ -// set(index, obj) method will change the object at index to obj - -// Change the first element to myObject -myList.set(0, myObject); - -// Change the third element to myObject -myList.set(2, myObject); - -// Change the LAST element of the list -myList.set(myList.size() - 1, myObject); -``` - -#### Removing elements -```c++ -// remove(index) will remove and return the element at index - -// Remove the first object -myList.remove(0); - -// Get and Delete the third element -myDeletedObject = myList.remove(2); - -// pop() will remove and return the LAST element -myDeletedObject = myList.pop(); - -// shift() will remove and return the FIRST element -myDeletedObject = myList.shift(); - -// clear() will erase the entire list, leaving it with 0 elements -// NOTE: Clear wont DELETE/FREE memory from Pointers, if you -// are using Classes/Poiners, manualy delete and free those. -myList.clear(); -``` - ------------------------- - -## Library Reference - -### `ListNode` struct - -- `T` `ListNode::data` - The object data - -- `ListNode` `*next` - Pointer to the next Node - -### `LinkedList` class - -**`boolean` methods returns if succeeded** - -- `LinkedList::LinkedList()` - Constructor. - -- `LinkedList::~LinkedList()` - Destructor. Clear Nodes to minimize memory. Does not free pointer memory. - -- `int` `LinkedList::size()` - Returns the current size of the list. - -- `bool` `LinkedList::add(T)` - Add element T at the END of the list. - -- `bool` `LinkedList::add(int index, T)` - Add element T at `index` of the list. - -- `bool` `LinkedList::unshift(T)` - Add element T at the BEGINNING of the list. - -- `bool` `LinkedList::set(int index, T)` - Set the element at `index` to T. - -- `T` `LinkedList::remove(int index)` - Remove element at `index`. Return the removed element. Does not free pointer memory - -- `T` `LinkedList::pop()` - Remove the LAST element. Return the removed element. - -- `T` `LinkedList::shift()` - Remove the FIRST element. Return the removed element. - -- `T` `LinkedList::get(int index)` - Return the element at `index`. - -- `void` `LinkedList::clear()` - Removes all elements. Does not free pointer memory. - -- **protected** `int` `LinkedList::_size` - Holds the cached size of the list. - -- **protected** `ListNode` `LinkedList::*root` - Holds the root node of the list. - -- **protected** `ListNode` `LinkedList::*last` - Holds the last node of the list. - -- **protected** `ListNode*` `LinkedList::getNode(int index)` - Returns the `index` node of the list. - -### Version History - -* `1.1 (2013-07-20)`: Cache implemented. Getting subsequent objects is now O(N). Before, O(N^2). -* `1.0 (2013-07-20)`: Original release - -![LinkedList](https://d2weczhvl823v0.cloudfront.net/ivanseidel/LinkedList/trend.png) diff --git a/src/cbor/lib/LinkedList/keywords.txt b/src/cbor/lib/LinkedList/keywords.txt deleted file mode 100644 index 3ae496859..000000000 --- a/src/cbor/lib/LinkedList/keywords.txt +++ /dev/null @@ -1,28 +0,0 @@ -####################################### -# Syntax Coloring -####################################### - -####################################### -# Datatypes (KEYWORD1) -####################################### - -LinkedList KEYWORD1 -ListNode KEYWORD1 - -####################################### -# Methods and Functions (KEYWORD2) -####################################### - -size KEYWORD2 -add KEYWORD2 -unshift KEYWORD2 -set KEYWORD2 -remove KEYWORD2 -pop KEYWORD2 -shift KEYWORD2 -get KEYWORD2 -clear KEYWORD2 - -####################################### -# Constants (LITERAL1) -####################################### diff --git a/src/cbor/lib/LinkedList/library.json b/src/cbor/lib/LinkedList/library.json deleted file mode 100644 index 4179b248d..000000000 --- a/src/cbor/lib/LinkedList/library.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "LinkedList", - "keywords": "pattern", - "description": "A fully implemented LinkedList (int, float, objects, Lists or Wales) made to work with Arduino projects", - "repository": - { - "type": "git", - "url": "https://github.com/ivanseidel/LinkedList.git" - }, - "frameworks": "arduino", - "platforms": "*" -} diff --git a/src/cbor/lib/LinkedList/library.properties b/src/cbor/lib/LinkedList/library.properties deleted file mode 100644 index 77b1423c0..000000000 --- a/src/cbor/lib/LinkedList/library.properties +++ /dev/null @@ -1,9 +0,0 @@ -name=LinkedList -version=1.2.3 -author=Ivan Seidel -maintainer=Ivan Seidel -sentence=A fully implemented LinkedList made to work with Arduino projects -paragraph=The objective of this library is to create a pattern for projects. If you need to use a List of: int, float, objects, Lists or Wales. This is what you are looking for. -category=Data Processing -url=https://github.com/ivanseidel/LinkedList -architectures=* From 34b50799c52bfd88ccf1de8a59d7617408526139 Mon Sep 17 00:00:00 2001 From: Alexander Entinger Date: Thu, 4 Jun 2020 07:35:12 +0200 Subject: [PATCH 2/2] Replacing custom list implementation with std::list --- src/cbor/ArduinoCloudProperty.cpp | 56 ++++++++------ src/cbor/ArduinoCloudProperty.h | 7 +- src/cbor/ArduinoCloudThing.cpp | 123 ++++++++++++++++++------------ src/cbor/ArduinoCloudThing.h | 14 ++-- 4 files changed, 118 insertions(+), 82 deletions(-) diff --git a/src/cbor/ArduinoCloudProperty.cpp b/src/cbor/ArduinoCloudProperty.cpp index 6dfdd8997..b7abb50ea 100644 --- a/src/cbor/ArduinoCloudProperty.cpp +++ b/src/cbor/ArduinoCloudProperty.cpp @@ -17,6 +17,10 @@ #include "ArduinoCloudProperty.h" +#undef max +#undef min +#include + #ifndef ARDUINO_ARCH_SAMD #pragma message "No RTC available on this architecture - ArduinoIoTCloud will not keep track of local change timestamps ." #endif @@ -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) { @@ -174,7 +177,7 @@ void ArduinoCloudProperty::appendAttributeName(String attributeName, std::functi cbor_encoder_close_container(encoder, &mapEncoder); } -void ArduinoCloudProperty::setAttributesFromCloud(LinkedList *map_data_list) { +void ArduinoCloudProperty::setAttributesFromCloud(std::list * map_data_list) { _map_data_list = map_data_list; _attributeIdentifier = 0; setAttributesFromCloud(); @@ -215,31 +218,38 @@ void ArduinoCloudProperty::setAttributeReal(String& value, String attributeName) }); } -void ArduinoCloudProperty::setAttributeReal(String attributeName, std::functionsetValue) { +void ArduinoCloudProperty::setAttributeReal(String attributeName, std::functionsetValue) +{ 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) { diff --git a/src/cbor/ArduinoCloudProperty.h b/src/cbor/ArduinoCloudProperty.h index 8d961f465..1e7011f45 100644 --- a/src/cbor/ArduinoCloudProperty.h +++ b/src/cbor/ArduinoCloudProperty.h @@ -27,15 +27,14 @@ INCLUDE ******************************************************************************/ - #include // in order to allow to define its own max and min functions #undef max #undef min +#include #include #include "lib/tinycbor/cbor-lib.h" -#include "lib/LinkedList/LinkedList.h" #define appendAttributesToCloud() appendAttributesToCloudReal(CborEncoder *encoder) #define appendAttribute(x) appendAttributeReal(x, getAttributeName(#x, '.'), encoder) @@ -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::functionf, CborEncoder *encoder); - void setAttributesFromCloud(LinkedList *map_data_list); + void setAttributesFromCloud(std::list * map_data_list); void setAttributeReal(bool& value, String attributeName = ""); void setAttributeReal(int& value, String attributeName = ""); void setAttributeReal(float& value, String attributeName = ""); @@ -206,7 +205,7 @@ class ArduinoCloudProperty { /* Variables used for reconnection sync*/ unsigned long _last_local_change_timestamp; unsigned long _last_cloud_change_timestamp; - LinkedList * _map_data_list; + std::list * _map_data_list; /* Store the identifier of the property in the array list */ int _identifier; int _attributeIdentifier; diff --git a/src/cbor/ArduinoCloudThing.cpp b/src/cbor/ArduinoCloudThing.cpp index e52b7e097..d7e2ff4cd 100644 --- a/src/cbor/ArduinoCloudThing.cpp +++ b/src/cbor/ArduinoCloudThing.cpp @@ -21,6 +21,10 @@ #include +#undef max +#undef min +#include + #include "ArduinoCloudThing.h" /****************************************************************************** @@ -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::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::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(p); + if (pbase->isPrimitive() && pbase->isChangedLocally() && pbase->isReadableByCloud()) + { + p->updateLocalTimestamp(); + } + }); } } @@ -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; } @@ -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; } @@ -472,7 +492,6 @@ 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; } } @@ -480,11 +499,15 @@ ArduinoCloudThing::MapParserState ArduinoCloudThing::handle_LeaveMap(CborValue * return next_state; } -void ArduinoCloudThing::freeMapDataList(LinkedList *map_data_list) { - while (map_data_list->size() > 0) { - CborMapData const * mapData = map_data_list->pop(); - delete mapData; - } +void ArduinoCloudThing::freeMapDataList(std::list * 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) { diff --git a/src/cbor/ArduinoCloudThing.h b/src/cbor/ArduinoCloudThing.h index 3bd6b31ef..37f08b960 100644 --- a/src/cbor/ArduinoCloudThing.h +++ b/src/cbor/ArduinoCloudThing.h @@ -22,8 +22,12 @@ INCLUDE ******************************************************************************/ +#undef max +#undef min +#include + #include "ArduinoCloudProperty.h" -#include "lib/LinkedList/LinkedList.h" + #include "types/CloudBool.h" #include "types/CloudFloat.h" #include "types/CloudInt.h" @@ -95,14 +99,14 @@ class ArduinoCloudThing { private: GetTimeCallbackFunc _get_time_func; - LinkedList _property_list; + std::list _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 _map_data_list; + std::list _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, @@ -140,7 +144,7 @@ class ArduinoCloudThing { static bool ifNumericConvertToDouble(CborValue * value_iter, double * numeric_val); static double convertCborHalfFloatToDouble(uint16_t const half_val); - void freeMapDataList(LinkedList * map_data_list); + void freeMapDataList(std::list * map_data_list); inline void addProperty(ArduinoCloudProperty * property_obj, int propertyIdentifier) { if (propertyIdentifier != -1) { property_obj->setIdentifier(propertyIdentifier); @@ -148,7 +152,7 @@ class ArduinoCloudThing { // 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);