2 Copyright (C) 2012 Intel Corporation
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 #ifndef _ABSTRACTPROPERTYTYPE_H_
20 #define _ABSTRACTPROPERTYTYPE_H_
28 #include <boost/any.hpp>
29 #include <boost/lexical_cast.hpp>
30 #include <boost/utility.hpp>
31 #include <type_traits>
34 #include "timestamp.h"
36 #include <boost/algorithm/string.hpp>
37 #include <superptr.hpp>
59 static const Zone::Type FrontRight;
60 static const Zone::Type FrontLeft;
61 static const Zone::Type MiddleRight;
62 static const Zone::Type MiddleLeft;
63 static const Zone::Type RearRight;
64 static const Zone::Type RearLeft;
66 typedef std::vector<Zone::Type> ZoneList;
70 class AbstractPropertyType
75 * \brief The Priority enum describes prority of the property type.
79 /*!< normal priority. This is default */
85 /*!< Instant. Using this priority is not thread safe. This is typically used for
86 * Properties that need to be deterministic.
91 AbstractPropertyType(std::string property)
92 : name(property), timestamp(amb::currentTime()), sequence(-1), zone(Zone::None), priority(Normal)
97 virtual ~AbstractPropertyType()
99 for(auto i : destroyed)
107 * @return strigified value
109 virtual std::string toString() const = 0;
112 * @brief fromString converts from string value
114 virtual void fromString(std::string)= 0;
118 * @return GVariant representation of value. Caller must unref the returned GVariant
120 virtual GVariant* toVariant() = 0;
123 * @brief fromVariant converts GVariant value into compatible native value. Caller owns
126 virtual void fromVariant(GVariant*) = 0;
130 * @return a copy of the AbstractPropertyType
132 virtual AbstractPropertyType* copy() = 0;
135 * @brief quickCopy is intended as a way to quickly copy the often changing bits from one abstract property to another
136 * It assumes that the properties are almost identical in name, source, and zone.
137 * @param other the property to copy from
139 virtual void quickCopy(AbstractPropertyType* other)
141 sequence = other->sequence;
142 mValue = other->anyValue();
143 timestamp = other->timestamp;
146 bool operator == (AbstractPropertyType &other)
148 std::string one = toString();
149 std::string two = other.toString();
151 && zone == other.zone
152 && sourceUuid == other.sourceUuid
153 && name == other.name;
156 bool operator != (AbstractPropertyType &other)
158 std::string one = toString();
159 std::string two = other.toString();
164 * @brief name Property name. @see VehicleProperty for built-in supported property names
169 * @brief timestamp. Timestamp when the value was last updated by the system. This is updated automatically
170 * any time setValue() is called
171 * @see amb::currentTime()
177 * @brief sequence internal counter. Useful as a unique indentifier. values is -1 if not used (default).
182 * @brief sourceUuid uuid of the source that produced this property. This is set by the routingengine
183 * if left unmodified.
185 std::string sourceUuid;
188 * @brief zone that the property is situated in.
193 * \brief priority is used to tell the routing engine how to prioritize routing the value to plugins.
194 * setting this value to AbstractPropertyType::Instant will tell the routing engine to immedietly
195 * route the value without any reliance on the mainloop. Instant priority is NOT thread safe.
196 * Default priority is AbstractPropertyType::Normal.
202 * @param val boost::any value. NOTE: boost::any does not accept type coercion. Types must match exactly
203 * with native type. (ie, don't use "int" if the native type is "uint")
205 virtual void setValue(boost::any val)
208 timestamp = amb::currentTime();
212 * \brief value() native value. Does not use type coercion. Will throw if types do not match.
214 template <typename T>
217 return boost::any_cast<T>(mValue);
222 * @return boost::any value
224 boost::any anyValue()
231 * \return gvariant signature
233 virtual const string signature()
235 auto var = amb::make_super(toVariant());
238 const string s = g_variant_get_type_string(var.get());
240 DebugOut() << "returning signature: " << s << " for "<< name << endl;
246 * @brief destroyed is called if this property is destroyed.
248 std::vector<std::function<void(AbstractPropertyType*)>> destroyed;
259 struct PropertyCompare
261 bool operator()(AbstractPropertyType* const & lhs, AbstractPropertyType* & rhs) const
263 if (lhs->name == rhs->name
264 && lhs->sourceUuid == rhs->sourceUuid
265 && lhs->zone == rhs->zone)
278 template <typename T>
285 static const char* signature() { return "i"; }
287 static int value(GVariant* v)
290 g_variant_get(v, signature(), &val);
294 static std::string stringize(std::string v)
304 static const char* signature() { return "d"; }
306 static double value(GVariant* v)
308 return g_variant_get_double(v);
310 static std::string stringize(std::string v)
320 static const char* signature() { return "q"; }
322 static uint16_t value(GVariant* v)
324 return g_variant_get_uint16(v);
326 static std::string stringize(std::string v)
336 static const char* signature() { return "n"; }
338 static int16_t value(GVariant* v)
340 return g_variant_get_int16(v);
342 static std::string stringize(std::string v)
352 static const char* signature() { return "y"; }
354 static char value(GVariant* v)
356 return g_variant_get_byte(v);
358 static std::string stringize(std::string v)
368 static const char* signature() { return "u"; }
370 static uint32_t value(GVariant* v)
372 return g_variant_get_uint32(v);
374 static std::string stringize(std::string v)
384 static const char* signature() { return "x"; }
386 static int64_t value(GVariant* v)
388 return g_variant_get_int64(v);
390 static std::string stringize(std::string v)
400 static const char* signature() { return "t"; }
402 static uint64_t value(GVariant* v)
404 return g_variant_get_uint64(v);
406 static std::string stringize(std::string v)
416 static const char* signature() { return "b"; }
418 static bool value(GVariant *v)
420 return g_variant_get_boolean(v);
422 static std::string stringize(std::string v)
424 if(v == "0" || v == "1")
427 boost::algorithm::to_lower(v);
428 return v == "true" ? "1":"0";
433 * \brief BasicPropertyType is a typed property type. Most internal types are derived from this class
435 * std::unique_ptr<BasicPropertyType<int>> boostPSI = new BasicPropertyType<int>("BoostPSI",5);
436 * boostPSI->priority = AbstractPropertyType::Instant; //set instant because we clean up right after.
437 * routingEngine->updateProperty(boostPSI.get(), sourceUuid());
439 template <typename T>
440 class BasicPropertyType: public AbstractPropertyType
443 BasicPropertyType(): AbstractPropertyType("")
448 BasicPropertyType(BasicPropertyType const & other)
449 :AbstractPropertyType(other.name)
451 setValue(other.value<T>());
452 timestamp = other.timestamp;
453 sequence = other.sequence;
454 sourceUuid = other.sourceUuid;
460 BasicPropertyType & operator = (BasicPropertyType const & other)
462 setValue(other.value<T>());
463 timestamp = other.timestamp;
464 sequence = other.sequence;
465 sourceUuid = other.sourceUuid;
472 BasicPropertyType & operator = (T const & other)
478 BasicPropertyType & operator ++ ()
480 setValue(basicValue() + 1);
483 BasicPropertyType & operator -- ()
485 setValue(basicValue() - 1);
488 bool operator < (const BasicPropertyType<T>& other) const
490 return value<T>() < other.value<T>();
493 bool operator > (const BasicPropertyType<T>& other) const
495 return value<T>() > other.value<T>();
498 BasicPropertyType( T val)
499 :AbstractPropertyType("")
504 BasicPropertyType( std::string propertyName, T val)
505 :AbstractPropertyType(propertyName)
510 BasicPropertyType( std::string propertyName, std::string val)
511 :AbstractPropertyType(propertyName)
513 if(!val.empty() && val != "")
520 BasicPropertyType(std::string propertyName)
521 :AbstractPropertyType(propertyName)
526 AbstractPropertyType* copy()
528 return new BasicPropertyType<T>(*this);
531 void fromString(std::string val)
533 if(!val.empty() && val != "")
539 std::string toString() const
541 std::stringstream stream;
542 stream.precision(10);
548 GVariant* toVariant()
550 return serializeVariant<T>(value<T>());
553 void fromVariant(GVariant *v)
555 setValue(deserializeVariant<T>(v));
560 * @return Typed version of value. Slightly more useful than @see AbstractPropertyType::value()
570 AbstractPropertyType::setValue(val);
573 void setValue(boost::any val)
575 AbstractPropertyType::setValue(val);
580 //GVariant* mVariant;
583 void serialize(std::string val, typename std::enable_if<std::is_enum<N>::value, N>::type* = 0)
587 std::stringstream stream(val);
590 setValue((N)someTemp);
594 void serialize(std::string val, typename std::enable_if<!std::is_enum<N>::value, N>::type* = 0)
596 std::stringstream stream(GVS<T>::stringize(val));
603 GVariant* serializeVariant(T val, typename std::enable_if<std::is_enum<N>::value, N>::type* = 0)
605 //mVariant = Glib::VariantBase(Glib::Variant<gint16>::create((int)val).gobj());
607 return (g_variant_new("i",(int)val));
611 GVariant* serializeVariant(T val, typename std::enable_if<!std::is_enum<N>::value, N>::type* = 0)
613 //mVariant = Glib::Variant<T>::create(val);
614 //mVariant = g_variant_ref(g_variant_new(GVS<T>::signature(),val));
615 return g_variant_new(GVS<T>::signature(),val);
619 T deserializeVariant(GVariant* v, typename std::enable_if<std::is_enum<N>::value, N>::type* = 0)
621 // return (T)((Glib::Variant<int>::cast_dynamic<Glib::Variant<int> >(*v)).get());
623 return (T)GVS<int>::value(v);
627 T deserializeVariant(GVariant* v, typename std::enable_if<!std::is_enum<N>::value, N>::type* = 0)
629 // return Glib::VariantBase::cast_dynamic<Glib::Variant<T> >(*v).get();
630 return GVS<T>::value(v);
634 class StringPropertyType: public AbstractPropertyType
640 :AbstractPropertyType("")
642 setValue(std::string());
645 StringPropertyType(std::string propertyName)
646 :AbstractPropertyType(propertyName)
648 setValue(std::string());
651 StringPropertyType(std::string propertyName, std::string val)
652 :AbstractPropertyType(propertyName)
657 StringPropertyType(StringPropertyType const & other)
658 :AbstractPropertyType(other.name)
660 setValue(other.value<std::string>());
661 timestamp = other.timestamp;
662 sequence = other.sequence;
663 sourceUuid = other.sourceUuid;
668 StringPropertyType & operator = (StringPropertyType const & other)
670 setValue(other.value<std::string>());
671 timestamp = other.timestamp;
672 sequence = other.sequence;
673 sourceUuid = other.sourceUuid;
680 StringPropertyType & operator = (std::string const & other)
682 setValue(std::string(other));
686 bool operator < (const StringPropertyType& other) const
688 return value<std::string>() < other.value<std::string>();
692 void fromString(std::string val)
697 AbstractPropertyType* copy()
699 return new StringPropertyType(*this);
702 std::string toString() const
704 return value<std::string>();
707 GVariant* toVariant()
709 //mVariant = Glib::Variant<std::string>::create(toString());
711 return g_variant_new_string(toString().c_str());
715 void fromVariant(GVariant *v)
717 setValue(std::string(g_variant_get_string(v,NULL)));
722 * \brief ListPropertyType is a AbstractPropertyType for arrays of AbstractPropertyTypes
724 template <class T = AbstractPropertyType>
725 class ListPropertyType: public AbstractPropertyType
729 ListPropertyType(std::string propertyName)
730 : AbstractPropertyType(propertyName), initialized(false)
735 ListPropertyType(std::string propertyName, T value)
736 : AbstractPropertyType(propertyName), initialized(false)
741 ListPropertyType(ListPropertyType & other)
742 :AbstractPropertyType(other.name),initialized(false)
744 std::vector<T> l = other.list();
750 timestamp = other.timestamp;
751 sequence = other.sequence;
752 sourceUuid = other.sourceUuid;
762 /** \brief append - appends a property to the list
763 * @arg property - property to be appended.
765 void append(T property)
773 appendPriv(property);
781 AbstractPropertyType* copy()
783 return new ListPropertyType(*this);
786 void quickCopy(AbstractPropertyType* other)
788 AbstractPropertyType::quickCopy(other);
789 ListPropertyType<T>* v = static_cast<ListPropertyType<T>*>(other);
792 DebugOut(DebugOut::Error) << "ListPropertyType Quick Copy failed" << endl;
798 std::string toString() const
800 std::string str = "[";
802 for(auto itr = mList.begin(); itr != mList.end(); itr++)
818 void fromString(std::string str )
825 if(str[0] == '[' && str[str.length()-1] == ']')
827 str = str.substr(1,str.length() - 2);
830 std::vector<std::string> elements;
832 std::istringstream f(str);
835 while(std::getline(f,element,','))
840 timestamp = amb::currentTime();
844 GVariant* toVariant()
847 GVariantBuilder params;
848 g_variant_builder_init(¶ms, ((const GVariantType *) "av"));
850 for(auto itr = mList.begin(); itr != mList.end(); itr++)
853 auto var = t.toVariant();
854 GVariant *newvar = g_variant_new("v", var);
855 g_variant_builder_add_value(¶ms, newvar);
858 GVariant* var = g_variant_builder_end(¶ms);
864 void fromVariant(GVariant* v)
868 /// TODO: fill this in
869 gsize dictsize = g_variant_n_children(v);
870 for (int i=0;i<dictsize;i++)
872 GVariant *childvariant = g_variant_get_child_value(v,i);
873 GVariant *innervariant = g_variant_get_variant(childvariant);
875 t.fromVariant(innervariant);
880 std::vector<T> list() { return mList; }
896 std::vector<T> mList;