UniSet  2.6.0
UInterface.h
00001 /*
00002  * Copyright (c) 2015 Pavel Vainerman.
00003  *
00004  * This program is free software: you can redistribute it and/or modify
00005  * it under the terms of the GNU Lesser General Public License as
00006  * published by the Free Software Foundation, version 2.1.
00007  *
00008  * This program is distributed in the hope that it will be useful, but
00009  * WITHOUT ANY WARRANTY; without even the implied warranty of
00010  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00011  * Lesser General Lesser Public License for more details.
00012  *
00013  * You should have received a copy of the GNU Lesser General Public License
00014  * along with this program. If not, see <http://www.gnu.org/licenses/>.
00015  */
00016 // --------------------------------------------------------------------------
00021 // --------------------------------------------------------------------------
00022 #ifndef UInterface_H_
00023 #define UInterface_H_
00024 // ---------------------------------------------------------------------------
00025 #include <memory>
00026 #include <string>
00027 #include <sstream>
00028 #include <unordered_map>
00029 #include <functional>
00030 #include <omniORB4/CORBA.h>
00031 #include "Exceptions.h"
00032 #include "UniSetTypes.h"
00033 #include "ObjectIndex.h"
00034 #include "ObjectRepository.h"
00035 #include "IOController_i.hh"
00036 #include "MessageType.h"
00037 #include "Configuration.h"
00038 
00039 // -----------------------------------------------------------------------------------------
00040 #define UI_THROW_EXCEPTIONS uniset::TimeOut,uniset::IOBadParam,uniset::ORepFailed
00041 // -----------------------------------------------------------------------------------------
00042 namespace uniset
00043 {
00044 
00054 class UInterface
00055 {
00056     public:
00057 
00058         UInterface( const uniset::ObjectId backid, CORBA::ORB_var orb = NULL, const std::shared_ptr<uniset::ObjectIndex> oind = nullptr );
00059         UInterface( const std::shared_ptr<uniset::Configuration>& uconf = uniset::uniset_conf() );
00060         ~UInterface();
00061 
00062         // ---------------------------------------------------------------
00063         // Работа с датчиками
00064 
00066         long getValue (const uniset::ObjectId id, const uniset::ObjectId node) const throw(UI_THROW_EXCEPTIONS);
00067         long getValue ( const uniset::ObjectId id ) const;
00068         long getRawValue( const IOController_i::SensorInfo& si );
00069 
00071         void setValue ( const uniset::ObjectId id, long value, const uniset::ObjectId node, uniset::ObjectId sup_id = uniset::DefaultObjectId ) const throw(UI_THROW_EXCEPTIONS);
00072         void setValue ( const uniset::ObjectId id, long value ) const;
00073         void setValue ( const IOController_i::SensorInfo& si, long value, const uniset::ObjectId supplier ) const;
00074 
00075         // fast - это удалённый вызов "без подтверждения", он быстрее, но менее надёжен
00076         // т.к. вызывающий никогда не узнает об ошибке, если она была (датчик такой не найдён и т.п.)
00077         void fastSetValue( const IOController_i::SensorInfo& si, long value, uniset::ObjectId supplier ) const;
00078 
00080         IOController_i::SensorInfoSeq_var getSensorSeq( const uniset::IDList& lst );
00081 
00084         uniset::IDSeq_var setOutputSeq( const IOController_i::OutSeq& lst, uniset::ObjectId sup_id );
00085 
00086         // ---------------------------------------------------------------
00087         // Заказ датчиков
00088 
00090         void askSensor( const uniset::ObjectId id, UniversalIO::UIOCommand cmd,
00091                         uniset::ObjectId backid = uniset::DefaultObjectId ) const;
00092 
00093         void askRemoteSensor( const uniset::ObjectId id, UniversalIO::UIOCommand cmd, const uniset::ObjectId node,
00094                               uniset::ObjectId backid = uniset::DefaultObjectId ) const throw(UI_THROW_EXCEPTIONS);
00095 
00097         uniset::IDSeq_var askSensorsSeq( const uniset::IDList& lst, UniversalIO::UIOCommand cmd,
00098                                          uniset::ObjectId backid = uniset::DefaultObjectId );
00099         // ------------------------------------------------------
00100 
00101         // установка неопределённого состояния
00102         void setUndefinedState( const IOController_i::SensorInfo& si, bool undefined, uniset::ObjectId supplier );
00103 
00104         // ---------------------------------------------------------------
00105         // Калибровка... пороги...
00106 
00108         void calibrate(const IOController_i::SensorInfo& si,
00109                        const IOController_i::CalibrateInfo& ci,
00110                        uniset::ObjectId adminId = uniset::DefaultObjectId );
00111 
00112         IOController_i::CalibrateInfo getCalibrateInfo( const IOController_i::SensorInfo& si );
00113 
00115         void askThreshold( const uniset::ObjectId sensorId, const uniset::ThresholdId tid,
00116                            UniversalIO::UIOCommand cmd,
00117                            long lowLimit, long hiLimit, bool invert = false,
00118                            uniset::ObjectId backid = uniset::DefaultObjectId ) const;
00119 
00120         void askRemoteThreshold( const uniset::ObjectId sensorId, const uniset::ObjectId node,
00121                                  const uniset::ThresholdId thresholdId, UniversalIO::UIOCommand cmd,
00122                                  long lowLimit, long hiLimit, bool invert = false,
00123                                  uniset::ObjectId backid = uniset::DefaultObjectId ) const;
00124 
00125         IONotifyController_i::ThresholdInfo getThresholdInfo( const IOController_i::SensorInfo& si, const uniset::ThresholdId tid ) const;
00126         IONotifyController_i::ThresholdInfo getThresholdInfo( const uniset::ObjectId sid, const uniset::ThresholdId tid ) const;
00127 
00128         // ---------------------------------------------------------------
00129         // Вспомогательные функции
00130 
00131         UniversalIO::IOType getIOType(const uniset::ObjectId id, uniset::ObjectId node) const throw(UI_THROW_EXCEPTIONS);
00132         UniversalIO::IOType getIOType(const uniset::ObjectId id) const;
00133 
00134         // read from xml (only for xml!) т.е. без удалённого запроса
00135         UniversalIO::IOType getConfIOType( const uniset::ObjectId id ) const noexcept;
00136 
00137         // Получение типа объекта..
00138         uniset::ObjectType getType(const uniset::ObjectId id, const uniset::ObjectId node) const throw(UI_THROW_EXCEPTIONS);
00139         uniset::ObjectType getType(const uniset::ObjectId id) const;
00140 
00142         IOController_i::ShortIOInfo getTimeChange( const uniset::ObjectId id, const uniset::ObjectId node ) const;
00143 
00145         std::string getObjectInfo( const uniset::ObjectId id, const std::string& params, const uniset::ObjectId node ) const;
00146         std::string apiRequest( const uniset::ObjectId id, const std::string& query, const uniset::ObjectId node ) const;
00147 
00149         IOController_i::ShortMapSeq* getSensors( const uniset::ObjectId id,
00150                                                  const uniset::ObjectId node = uniset::uniset_conf()->getLocalNode() );
00151 
00152         IOController_i::SensorInfoSeq* getSensorsMap( const uniset::ObjectId id,
00153                                                       const uniset::ObjectId node = uniset::uniset_conf()->getLocalNode() );
00154 
00155         IONotifyController_i::ThresholdsListSeq* getThresholdsList( const uniset::ObjectId id,
00156                 const uniset::ObjectId node = uniset::uniset_conf()->getLocalNode() );
00157         // ---------------------------------------------------------------
00158         // Работа с репозиторием
00159 
00160         //        /*! регистрация объекта в репозитории */
00161         void registered(const uniset::ObjectId id, const uniset::ObjectPtr oRef, bool force = false)const throw(uniset::ORepFailed);
00162 
00163         //        /*! разрегистрация объекта */
00164         void unregister(const uniset::ObjectId id)throw(uniset::ORepFailed);
00165 
00167         inline uniset::ObjectPtr resolve( const std::string& name ) const
00168         {
00169             return rep.resolve(name);
00170         }
00171 
00172         inline uniset::ObjectPtr resolve( const uniset::ObjectId id ) const
00173         {
00174             return rep.resolve( oind->getNameById(id) );
00175         }
00176 
00177         uniset::ObjectPtr resolve(const uniset::ObjectId id, const uniset::ObjectId nodeName) const
00178         throw(uniset::ResolveNameError, uniset::TimeOut);
00179 
00180 
00181         // Проверка доступности объекта или датчика
00182         bool isExist( const uniset::ObjectId id ) const noexcept;
00183         bool isExist( const uniset::ObjectId id, const uniset::ObjectId node ) const noexcept;
00184 
00185         // used for check 'isExist'
00186         bool waitReady( const uniset::ObjectId id, int msec, int pause = 5000,
00187                         const uniset::ObjectId node = uniset::uniset_conf()->getLocalNode() ) noexcept;
00188 
00189         // used for check 'getValue'
00190         bool waitWorking( const uniset::ObjectId id, int msec, int pause = 3000,
00191                           const uniset::ObjectId node = uniset::uniset_conf()->getLocalNode() ) noexcept;
00192 
00193         // ---------------------------------------------------------------
00194         // Работа с ID, Name
00195 
00197         inline uniset::ObjectId getIdByName( const std::string& name ) const noexcept
00198         {
00199             return oind->getIdByName(name);
00200         }
00201 
00203         inline std::string getNameById( const uniset::ObjectId id ) const noexcept
00204         {
00205             return oind->getNameById(id);
00206         }
00207 
00208         inline uniset::ObjectId getNodeId( const std::string& fullname ) const noexcept
00209         {
00210             return oind->getNodeId(fullname);
00211         }
00212 
00213         inline std::string getTextName( const uniset::ObjectId id ) const noexcept
00214         {
00215             return oind->getTextName(id);
00216         }
00217 
00218         // ---------------------------------------------------------------
00219         // Получение указателей на вспомогательные классы.
00220         inline const std::shared_ptr<uniset::ObjectIndex> getObjectIndex() noexcept
00221         {
00222             return oind;
00223         }
00224         inline const std::shared_ptr<uniset::Configuration> getConf() noexcept
00225         {
00226             return uconf;
00227         }
00228         // ---------------------------------------------------------------
00229         // Посылка сообщений
00230 
00232         void send( const uniset::ObjectId name, const uniset::TransportMessage& msg, uniset::ObjectId node ) throw(UI_THROW_EXCEPTIONS);
00233         void send( const uniset::ObjectId name, const uniset::TransportMessage& msg);
00234 
00235         // ---------------------------------------------------------------
00236         // Вспомогательный класс для кэширования ссылок на удалённые объекты
00237 
00238         inline void setCacheMaxSize( size_t newsize ) noexcept
00239         {
00240             rcache.setMaxSize(newsize);
00241         }
00242 
00244         class CacheOfResolve
00245         {
00246             public:
00247                 CacheOfResolve( size_t maxsize, size_t cleancount = 20 ):
00248                     MaxSize(maxsize), minCallCount(cleancount) {};
00249                 ~CacheOfResolve() {};
00250 
00251                 uniset::ObjectPtr resolve( const uniset::ObjectId id, const uniset::ObjectId node ) const throw(uniset::NameNotFound);
00252                 void cache(const uniset::ObjectId id, const uniset::ObjectId node, uniset::ObjectVar& ptr ) const;
00253                 void erase( const uniset::ObjectId id, const uniset::ObjectId node ) const noexcept;
00254 
00255                 inline void setMaxSize( size_t ms ) noexcept
00256                 {
00257                     MaxSize = ms;
00258                 };
00259 
00260             protected:
00261                 CacheOfResolve() {};
00262 
00263             private:
00264 
00265                 bool clean() noexcept;       
00266                 inline void clear() noexcept 
00267                 {
00268                     uniset::uniset_rwmutex_wrlock l(cmutex);
00269                     mcache.clear();
00270                 };
00271 
00272                 struct Item
00273                 {
00274                     Item( const uniset::ObjectVar& ptr ): ptr(ptr), ncall(0) {}
00275                     Item(): ptr(NULL), ncall(0) {}
00276 
00277                     uniset::ObjectVar ptr;
00278                     size_t ncall; // счётчик обращений
00279 
00280                     bool operator<( const CacheOfResolve::Item& rhs ) const
00281                     {
00282                         return this->ncall > rhs.ncall;
00283                     }
00284                 };
00285 
00286                 typedef std::unordered_map<uniset::KeyType, Item> CacheMap;
00287                 mutable CacheMap mcache;
00288                 mutable uniset::uniset_rwmutex cmutex;
00289                 size_t MaxSize = { 20 };      
00290                 size_t minCallCount = { 20 }; 
00291         };
00292 
00293         void initBackId( uniset::ObjectId backid );
00294 
00295     protected:
00296         std::string set_err(const std::string& pre, const uniset::ObjectId id, const uniset::ObjectId node) const;
00297 
00298     private:
00299         void init();
00300 
00301         ObjectRepository rep;
00302         uniset::ObjectId myid;
00303         mutable CosNaming::NamingContext_var localctx;
00304         mutable CORBA::ORB_var orb;
00305         CacheOfResolve rcache;
00306         std::shared_ptr<uniset::ObjectIndex> oind;
00307         std::shared_ptr<uniset::Configuration> uconf;
00308 };
00309 // -------------------------------------------------------------------------
00310 } // end of uniset namespace
00311 // --------------------------------------------------------------------------
00312 #endif
00313 // --------------------------------------------------------------------------