MOOS 0.2375
/home/toby/moos-ivp/MOOS-2375-Oct0611/Core/MOOSDB/MOOSDB.cpp
Go to the documentation of this file.
00001 
00002 //
00003 //   MOOS - Mission Oriented Operating Suite 
00004 //  
00005 //   A suit of Applications and Libraries for Mobile Robotics Research 
00006 //   Copyright (C) 2001-2005 Massachusetts Institute of Technology and 
00007 //   Oxford University. 
00008 //    
00009 //   This software was written by Paul Newman at MIT 2001-2002 and Oxford 
00010 //   University 2003-2005. email: pnewman@robots.ox.ac.uk. 
00011 //      
00012 //   This file is part of a  MOOS Core Component. 
00013 //        
00014 //   This program is free software; you can redistribute it and/or 
00015 //   modify it under the terms of the GNU General Public License as 
00016 //   published by the Free Software Foundation; either version 2 of the 
00017 //   License, or (at your option) any later version. 
00018 //          
00019 //   This program is distributed in the hope that it will be useful, 
00020 //   but WITHOUT ANY WARRANTY; without even the implied warranty of 
00021 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
00022 //   General Public License for more details. 
00023 //            
00024 //   You should have received a copy of the GNU General Public License 
00025 //   along with this program; if not, write to the Free Software 
00026 //   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 
00027 //   02111-1307, USA. 
00028 //
00030 // MOOSDB.cpp: implementation of the CMOOSDB class.
00031 //
00033 
00034 #ifdef _WIN32
00035 #pragma warning(disable : 4786)
00036 #endif
00037 
00038 
00039 #include <MOOSLIB/MOOSLib.h>
00040 #include <MOOSGenLib/MOOSGenLib.h>
00041 
00042 #include "MOOSDB.h"
00043 #include "assert.h"
00044 #include <iostream>
00045 #include <sstream>
00046 #include <iterator>
00047 using namespace std;
00048 
00050 // Construction/Destruction
00052 
00053 
00054 
00055 bool CMOOSDB::OnRxPktCallBack(const std::string & sWho,MOOSMSG_LIST & MsgListRx,MOOSMSG_LIST & MsgListTx, void * pParam)
00056 {
00057     CMOOSDB* pMe = (CMOOSDB*)(pParam);
00058     
00059     return pMe->OnRxPkt(sWho,MsgListRx,MsgListTx);
00060 }
00061 
00062 bool CMOOSDB::OnDisconnectCallBack(string & sClient, void * pParam)
00063 {
00064     CMOOSDB* pMe = (CMOOSDB*)(pParam);
00065     
00066     return pMe->OnDisconnect(sClient);
00067 }
00068 
00069 CMOOSDB::CMOOSDB()
00070 {
00071     //here we set up default community names and DB Names
00072     m_sDBName = "MOOSDB#1";
00073     m_sCommunityName = "#1";
00074     
00075     //her is the default port to listen on
00076     m_nPort = DEFAULT_MOOS_SERVER_PORT;
00077     
00078     //make our own variable called DB_TIME
00079     {
00080         CMOOSDBVar NewVar("DB_TIME");
00081         NewVar.m_cDataType = MOOS_DOUBLE;
00082         NewVar.m_dfVal= HPMOOSTime();
00083         NewVar.m_sWhoChangedMe = m_sDBName;
00084         NewVar.m_sOriginatingCommunity = m_sCommunityName;
00085         NewVar.m_dfWrittenTime = HPMOOSTime();
00086         m_VarMap["DB_TIME"] = NewVar;
00087     }
00088     
00089     //make our own variable called DB_TIME
00090     {
00091         CMOOSDBVar NewVar("DB_UPTIME");
00092         NewVar.m_cDataType = MOOS_DOUBLE;
00093         NewVar.m_dfVal= 0;
00094         NewVar.m_sWhoChangedMe = m_sDBName;
00095         NewVar.m_sOriginatingCommunity = m_sCommunityName;
00096         NewVar.m_dfWrittenTime = HPMOOSTime();
00097         m_VarMap["DB_UPTIME"] = NewVar;
00098     }
00099 
00100     //make our own variable called DB_CLIENTS
00101     {
00102         CMOOSDBVar NewVar("DB_CLIENTS");
00103         NewVar.m_cDataType = MOOS_DOUBLE;
00104         NewVar.m_dfVal= HPMOOSTime();
00105         NewVar.m_sWhoChangedMe = m_sDBName;
00106         NewVar.m_sOriginatingCommunity = m_sCommunityName;
00107         NewVar.m_dfWrittenTime = HPMOOSTime();
00108         m_VarMap["DB_CLIENTS"] = NewVar;
00109     }
00110     
00111     //ignore broken pipes as is standard for network apps
00112 #ifndef _WIN32
00113     signal(SIGPIPE,SIG_IGN);
00114 #endif
00115     
00116     
00117     
00118 }
00119 
00120 CMOOSDB::~CMOOSDB()
00121 {
00122     
00123 }
00124 
00125 bool CMOOSDB::Run(const std::string  & sMissionFile )
00126 {
00127     if(!m_MissionReader.SetFile(sMissionFile))
00128     {
00129         MOOSTrace("Warning no mission file found - still serving but with trepidation\n");
00130     }
00131         
00132     
00133     if(m_MissionReader.GetValue("COMMUNITY",m_sCommunityName))
00134     {
00135         m_sDBName = "MOOSDB_"+m_sCommunityName;
00136     }
00137 
00138     double dfWarp;
00139     if(m_MissionReader.GetValue("MOOSTimeWarp",dfWarp))
00140     {
00141                 SetMOOSTimeWarp(dfWarp);
00142     }
00143 
00144     //is there a network - default  - true
00145         bool bNoNetwork = false;
00146     m_MissionReader.GetValue("NoNetwork",bNoNetwork);
00147         
00148         
00149     string sPort;
00150     
00151     if(m_MissionReader.GetValue("SERVERPORT",sPort))
00152     {
00153         m_nPort = atoi(sPort.c_str());
00154         if(m_nPort==0)
00155         {
00156             MOOSTrace("Error reading server port defaulting to %d \n",DEFAULT_MOOS_SERVER_PORT);
00157             m_nPort = DEFAULT_MOOS_SERVER_PORT;
00158         }
00159     }
00160     
00161     m_CommServer.SetOnRxCallBack(OnRxPktCallBack,this);
00162     
00163     m_CommServer.SetOnDisconnectCallBack(OnDisconnectCallBack,this);
00164     
00165     LogStartTime();
00166     
00167     m_CommServer.Run(m_nPort,m_sCommunityName,bNoNetwork);
00168         
00169     return true;
00170 }
00171 
00172 
00173 void CMOOSDB::UpdateDBClientsVar()
00174 {
00175 #define CLIENT_LIST_PUBLISH_PERIOD 2
00176     static double dfLastTime = MOOSTime();
00177     double dfNow = MOOSTime();
00178     if(dfNow-dfLastTime>CLIENT_LIST_PUBLISH_PERIOD)
00179     {
00180         STRING_LIST Clients;
00181         m_CommServer.GetClientNames(Clients);
00182 
00183         std::ostringstream ss;
00184         std::copy(Clients.begin(),Clients.end(),ostream_iterator<std::string>(ss,","));
00185         
00186         CMOOSMsg DBC(MOOS_NOTIFY,"DB_CLIENTS",ss.str());
00187         DBC.m_sOriginatingCommunity = m_sCommunityName;
00188         DBC.m_sSrc = m_sDBName;
00189         OnNotify(DBC);
00190         dfLastTime = dfNow;
00191     }
00192 
00193 
00194 
00195 
00196 }
00197 
00198 void CMOOSDB::UpdateDBTimeVars()
00199 {
00200     static double dfLastTime = MOOSTime();
00201     double dfNow = MOOSTime();
00202     if(dfNow-dfLastTime>1.0)
00203     {
00204         CMOOSMsg DBT(MOOS_NOTIFY,"DB_TIME",MOOSTime());
00205         DBT.m_sOriginatingCommunity = m_sCommunityName;
00206         DBT.m_sSrc = m_sDBName;
00207         OnNotify(DBT);
00208         dfLastTime = dfNow;
00209 
00210         CMOOSMsg DBUpT(MOOS_NOTIFY,"DB_UPTIME",MOOSTime()-GetStartTime());
00211         DBUpT.m_sOriginatingCommunity = m_sCommunityName;
00212         DBUpT.m_sSrc = m_sDBName;
00213         OnNotify(DBUpT);    
00214     }
00215 }
00216 
00218 bool CMOOSDB::OnRxPkt(const std::string & sClient,MOOSMSG_LIST & MsgListRx,MOOSMSG_LIST & MsgListTx)
00219 {
00220     
00221 
00222     MOOSMSG_LIST::iterator p;
00223     
00224     for(p = MsgListRx.begin();p!=MsgListRx.end();p++)
00225     {
00226         ProcessMsg(*p,MsgListTx);
00227     }
00228     
00229     //good spot to update our internal time    
00230     UpdateDBTimeVars();
00231 
00232     //and send clients an occasional membersip list
00233     UpdateDBClientsVar();
00234 
00235     if(!MsgListRx.empty())
00236     {
00237         
00238         //now we fill in the packet with our replies to THIS CLIENT
00239         //MOOSMSG_LIST_STRING_MAP::iterator q = m_HeldMailMap.find(MsgListRx.front().m_sSrc);
00240         
00241         MOOSMSG_LIST_STRING_MAP::iterator q = m_HeldMailMap.find(sClient);
00242         
00243         if(q==m_HeldMailMap.end())
00244         {
00245             
00246             //CMOOSMsg & rMsg = MsgListRx.front();
00247             //there is no mail waiting to be sent to this client
00248             //should only happen at start up...
00249             //string sClient = MsgListRx.front().m_sSrc;
00250             
00251             MOOSMSG_LIST NewList;
00252             
00253             m_HeldMailMap[sClient] = NewList;
00254             
00255             q = m_HeldMailMap.find(sClient);
00256             
00257             assert(q!=m_HeldMailMap.end());
00258         }
00259         
00260         
00261         if(q!=m_HeldMailMap.end())
00262         {
00263             if(!q->second.empty())
00264             {
00265                 //copy all the held mail to MsgListTx
00266                 MsgListTx.splice(MsgListTx.begin(),q->second);
00267             }
00268         }
00269     }
00270     
00271     return true;
00272 }
00273 
00275 bool CMOOSDB::ProcessMsg(CMOOSMsg &MsgRx,MOOSMSG_LIST & MsgListTx)
00276 {
00277     
00278     
00279     switch(MsgRx.m_cMsgType)
00280     {
00281     case MOOS_NOTIFY:    //NOTIFICATION
00282         return OnNotify(MsgRx);
00283         break;
00284     case MOOS_UNREGISTER:
00285         return OnUnRegister(MsgRx);
00286         break;
00287     case MOOS_REGISTER:    //REGISTRATION
00288         return OnRegister(MsgRx);
00289         break;
00290     case MOOS_NULL_MSG:
00291         break;    
00292     case MOOS_COMMAND:  //COMMAND
00293         break;
00294     case MOOS_SERVER_REQUEST:
00295         return DoServerRequest(MsgRx,MsgListTx);
00296         break;
00297     }
00298     
00299     return true;
00300 }
00301 
00302 
00305 bool CMOOSDB::OnNotify(CMOOSMsg &Msg)
00306 {
00307     double dfTimeNow = HPMOOSTime();
00308     
00309     
00310     CMOOSDBVar & rVar  = GetOrMakeVar(Msg);
00311     
00312     
00313     if(rVar.m_nWrittenTo==0)
00314     {
00315         rVar.m_cDataType=Msg.m_cDataType;
00316     }
00317     
00318     if(rVar.m_cDataType==Msg.m_cDataType)
00319     {
00320         double dfLastWrittenTime = rVar.m_dfWrittenTime;
00321         
00322         rVar.m_dfWrittenTime = dfTimeNow;
00323         
00324         rVar.m_dfTime        = Msg.m_dfTime;
00325         
00326         rVar.m_sWhoChangedMe = Msg.m_sSrc;
00327         
00328         if(Msg.m_sOriginatingCommunity.empty())
00329         {
00330             //we are the server in the originating community
00331             rVar.m_sOriginatingCommunity = m_sCommunityName;
00332             Msg.m_sOriginatingCommunity = m_sCommunityName;
00333         }
00334         else
00335         {
00336             //this message came from another community
00337             rVar.m_sOriginatingCommunity = Msg.m_sOriginatingCommunity;
00338         }
00339         
00340         switch(rVar.m_cDataType)
00341         {
00342         case MOOS_DOUBLE:
00343             rVar.m_dfVal = Msg.m_dfVal;
00344             break;
00345         case MOOS_STRING:
00346                 case MOOS_BINARY_STRING:
00347             rVar.m_sVal = Msg.m_sVal;
00348             break;
00349         }
00350         
00351         //record sSrc as a writer of this data
00352         rVar.m_Writers.insert(Msg.m_sSrc);
00353         
00354         //increment the number of times we have written to this variable
00355         rVar.m_nWrittenTo++;
00356         
00357         //how often is it being written?
00358         double dfDT = (dfTimeNow-dfLastWrittenTime);
00359         if(dfDT>0)
00360         {
00361             //this looks a little hookey - the numbers are arbitrary to give sensible
00362             //looking frequencies when timing is coarse
00363             if(dfDT>10.0)
00364             {
00365                 //MIN
00366                 rVar.m_dfWriteFreq = 0.0;
00367             }
00368             //else if(dfDT<0.005)
00369             //{
00370                 //MAX OUT
00371                 //this is almost certainly two of tge same mesages arrive in the same commpkt - ignore...
00372                 //MOOSTrace("Msg %s was last updated at %f and its now %f\n", Msg.GetKey().c_str(),dfTimeNow,dfLastWrittenTime);
00373                 //rVar.m_dfWriteFreq = 200.0;
00374             //}
00375             else
00376             {
00377                 //IIR FILTER COOEFFICENT
00378                 double dfAlpha = 0.95;
00379                 rVar.m_dfWriteFreq = dfAlpha*rVar.m_dfWriteFreq + (1.0-dfAlpha)/(dfDT/++rVar.m_nOverTicks);
00380                 rVar.m_nOverTicks=0;
00381             }
00382         }
00383         else
00384         {
00385             rVar.m_nOverTicks++;
00386         }
00387         
00388         //now comes the intersting part...
00389         //which clients have asked to be informed
00390         //of changes in this variable?
00391         REGISTER_INFO_MAP::iterator p;
00392         
00393         
00394         for(p = rVar.m_Subscribers.begin();p!=rVar.m_Subscribers.end();p++)
00395         {
00396             
00397             CMOOSRegisterInfo & rInfo = p->second;
00398             //has enough time expired since the last time we
00399             //sent notification for the variable?
00400             if(rInfo.Expired(dfTimeNow))
00401             {
00402                 
00403                 string  & sClient = p->second.m_sClientName;
00404                 
00405                 //the Msg we were passed has all the information we require already
00406                 Msg.m_cMsgType = MOOS_NOTIFY;
00407                 
00408                 
00409                 AddMessageToClientBox(sClient,Msg);
00410                 
00411                 //finally we remember when we sent this to the client in question
00412                 rInfo.SetLastTimeSent(dfTimeNow);
00413             }
00414         }
00415     }
00416     else
00417     {
00418         MOOSTrace("Attempting to update var \"%s\" which is type %c with data type %c\n",
00419             Msg.m_sKey.c_str(),
00420             rVar.m_cDataType,
00421             Msg.m_cDataType);
00422     }
00423     
00424     
00425     
00426     return true;
00427 }
00428 
00429 
00432 bool    CMOOSDB::AddMessageToClientBox(const string &sClient,CMOOSMsg & Msg)
00433 {
00434     MOOSMSG_LIST_STRING_MAP::iterator q = m_HeldMailMap.find(sClient);
00435     
00436     if(q==m_HeldMailMap.end())
00437     {
00438         //there is no mail waiting to be sent to this client
00439         //should only happen at start up...
00440         MOOSMSG_LIST NewList;
00441         m_HeldMailMap[sClient] = NewList;
00442         
00443         q = m_HeldMailMap.find(sClient);
00444         
00445         assert(q!=m_HeldMailMap.end());
00446     }
00447     
00448     //q->second is now a reference to a list of messages that will be
00449     //sent to sClient the next time it calls into the database...
00450     
00451     q->second.push_front(Msg);
00452     
00453     return true;
00454 }
00455 
00456 
00459 bool CMOOSDB::OnUnRegister(CMOOSMsg &Msg)
00460 {
00461     //what are we looking to un register for?
00462     
00463     //if the variable already exists then post a notification message
00464     //to the client
00465     bool bAlreadyThere = VariableExists(Msg.m_sKey);
00466     if(bAlreadyThere)
00467     {
00468         CMOOSDBVar & rVar  = GetOrMakeVar(Msg);
00469         rVar.RemoveSubscriber(Msg.m_sSrc);
00470     }
00471     
00472     return true;
00473 }
00474 
00475 
00478 bool CMOOSDB::OnRegister(CMOOSMsg &Msg)
00479 {
00480     
00481     
00482     //what are we looking to register for?
00483     
00484     //if the variable already exists then post a notification message
00485     //to the client
00486     bool bAlreadyThere = VariableExists(Msg.m_sKey);
00487     
00488     CMOOSDBVar & rVar  = GetOrMakeVar(Msg);
00489     
00490     if(!rVar.AddSubscriber(Msg.m_sSrc,Msg.m_dfVal))
00491         return false;
00492     
00493     
00494     if(bAlreadyThere && rVar.m_nWrittenTo!=0)
00495     {
00496         //when the client registered the variable already existed...
00497         //better tell them
00498         CMOOSMsg ReplyMsg;
00499         Var2Msg(rVar,ReplyMsg);
00500         
00501         ReplyMsg.m_cMsgType = MOOS_NOTIFY;
00502         
00503         AddMessageToClientBox(Msg.m_sSrc,ReplyMsg);      
00504         
00505     }
00506     
00507     return true;
00508 }
00509 
00510 
00515 CMOOSDBVar & CMOOSDB::GetOrMakeVar(CMOOSMsg &Msg)
00516 {    
00517     
00518     //look up this variable name
00519     DBVAR_MAP::iterator p = m_VarMap.find(Msg.m_sKey);
00520     
00521     if(p==m_VarMap.end())
00522     {
00523         //we need to make a new variable here for this key
00524         //as we don't know about it!
00525         
00526         CMOOSDBVar NewVar(Msg.m_sKey);
00527         
00528         if(Msg.m_cMsgType==MOOS_REGISTER)
00529         {
00530             //interesting case is when this method is being used to 
00531             //register for a variable that has not been written to. Here
00532             //we simply make the variable but don't commit to its data type
00533             NewVar.m_cDataType = MOOS_NOT_SET;
00534         }
00535         else
00536         {
00537             //new variable will have data type of request message
00538             NewVar.m_cDataType = Msg.m_cDataType;
00539         }
00540         
00541         //index our new creation
00542         m_VarMap[Msg.m_sKey] = NewVar;
00543         
00544         //check we can get it back ok!!
00545         p = m_VarMap.find(Msg.m_sKey);
00546         
00547         assert(p!=m_VarMap.end());
00548         
00549 #ifdef DB_VERBOSE
00550         
00551         MOOSTrace("\nMaking new variable: \n");
00552         MOOSTrace("    Name=\"%s\"\n",NewVar.m_sName.c_str());
00553         MOOSTrace("    Src =\"%s\"\n",Msg.m_sSrc.c_str());
00554         MOOSTrace("    Type =\"%s\"\n",NewVar.m_cDataType);
00555 #endif
00556     }
00557     
00558     //ok we know what you are talking about
00559     CMOOSDBVar & rVar = p->second;
00560     
00561     //return the reference
00562     return rVar;
00563 }
00564 
00565 bool CMOOSDB::OnDisconnect(string &sClient)
00566 {
00567     //for all variables remove subscriptions to sClient
00568     
00569     DBVAR_MAP::iterator p;
00570     
00571     for(p=m_VarMap.begin();p!=m_VarMap.end();p++)
00572     {
00573         CMOOSDBVar  & rVar = p->second;
00574         
00575         rVar.RemoveSubscriber(sClient);
00576     }
00577     
00578     MOOSTrace("removing held mail for \"%s\"...\n",sClient.c_str());
00579     
00580     m_HeldMailMap.erase(sClient);
00581     
00582     return true;
00583 }
00584 
00585 bool CMOOSDB::DoServerRequest(CMOOSMsg &Msg, MOOSMSG_LIST &MsgTxList)
00586 {
00587     //explictly requesting the server to do something...
00588     
00589     if(Msg.m_sKey=="ALL")
00590     {
00591         return OnServerAllRequested(Msg,MsgTxList);
00592     }
00593     else if(Msg.m_sKey.find("PROC_SUMMARY")!=string::npos)
00594     {
00595         return OnProcessSummaryRequested(Msg,MsgTxList);
00596     }
00597     else if (Msg.m_sKey.find("VAR_SUMMARY") != string::npos) 
00598     {
00599         return OnVarSummaryRequested(Msg, MsgTxList);
00600     }
00601     else if(Msg.m_sKey.find("DB_CLEAR")!=string::npos)
00602     {
00603         return OnClearRequested(Msg,MsgTxList);
00604     }
00605     
00606     
00607     
00608     return false;
00609 }
00610 
00611 bool CMOOSDB::OnProcessSummaryRequested(CMOOSMsg &Msg, MOOSMSG_LIST &MsgTxList)
00612 {
00613     DBVAR_MAP::iterator p;
00614     STRING_LIST::iterator q;
00615     
00616     STRING_LIST Clients;
00617     
00618     m_CommServer.GetClientNames(Clients);
00619     
00620     
00621     for(q=Clients.begin();q!=Clients.end();q++)
00622     {
00623         string sWho = *q;
00624         
00625         string sPublished= "PUBLISHED=";
00626         string sSubscribed = "SUBSCRIBED=";
00627         
00628         for(p=m_VarMap.begin();p!=m_VarMap.end();p++)
00629         {
00630             CMOOSDBVar  & rVar = p->second;
00631             
00632             if(rVar.m_Writers.find(sWho)!=rVar.m_Writers.end())
00633             {
00634                 if(!sPublished.empty())
00635                 {
00636                     sPublished+=",";
00637                 }
00638                 sPublished+=rVar.m_sName;
00639                 
00640             }
00641             
00642             if(rVar.m_Subscribers.find(sWho)!=rVar.m_Subscribers.end())
00643             {
00644                 if(!sSubscribed.empty())
00645                 {
00646                     sSubscribed+=",";
00647                 }
00648                 sSubscribed+=rVar.m_sName;
00649             }
00650         }
00651         
00652         
00653         CMOOSMsg MsgReply;
00654         
00655         MsgReply.m_nID        = Msg.m_nID;
00656         
00657         MsgReply.m_cMsgType   = MOOS_NOTIFY;
00658         MsgReply.m_cDataType  = MOOS_STRING;
00659         MsgReply.m_dfTime     = MOOSTime()-m_dfStartTime; //for display
00660         MsgReply.m_sSrc       = m_sDBName;
00661         MsgReply.m_sKey       = "PROC_SUMMARY";
00662         MsgReply.m_sVal       = sWho+":"+sSubscribed+","+sPublished;
00663         MsgReply.m_dfVal      = -1;
00664         
00665         
00666         MsgTxList.push_front(MsgReply);
00667     }
00668     
00669     return true;
00670     
00671 }
00672 
00673 bool CMOOSDB::OnServerAllRequested(CMOOSMsg &Msg, MOOSMSG_LIST &MsgTxList)
00674 {
00675     
00676     
00677     DBVAR_MAP::iterator p;
00678     
00679     for(p=m_VarMap.begin();p!=m_VarMap.end();p++)
00680     {
00681         CMOOSDBVar  & rVar = p->second;
00682         
00683         CMOOSMsg MsgVar;
00684         
00685         MsgVar.m_nID        = Msg.m_nID;
00686         
00687         MsgVar.m_cMsgType   = MOOS_NOTIFY;
00688         MsgVar.m_cDataType  = rVar.m_cDataType;
00689         MsgVar.m_dfTime     = rVar.m_dfWrittenTime-m_dfStartTime; //for display
00690         MsgVar.m_sSrc       = rVar.m_sWhoChangedMe;
00691         MsgVar.m_sKey       = rVar.m_sName;
00692         MsgVar.m_sVal       = rVar.m_sVal;
00693                 MsgVar.m_sSrcAux    = rVar.m_sSrcAux;
00694         MsgVar.m_dfVal      = rVar.m_dfVal;
00695         MsgVar.m_dfVal2     = rVar.m_dfWriteFreq;
00696         MsgVar.m_sOriginatingCommunity = rVar.m_sOriginatingCommunity;
00697         
00698         if(MsgVar.m_dfTime<0) 
00699         {
00700             MsgVar.m_dfTime =-1;
00701         }
00702         
00703         MsgTxList.push_front(MsgVar);
00704         
00705         
00706     }
00707     
00708     
00709     return true;
00710 }
00711 
00712 //Suggested addition by MIT users 2006 - shorter version of OnProcessSummary
00713 bool CMOOSDB::OnVarSummaryRequested(CMOOSMsg &Msg, MOOSMSG_LIST &MsgTxList)
00714 {
00715     std::string TheVars;
00716     DBVAR_MAP::iterator p;
00717     for(p = m_VarMap.begin(); p != m_VarMap.end(); p++) 
00718     {
00719         //look to a comma
00720         if(p!=m_VarMap.begin())
00721             TheVars += ",";
00722 
00723         TheVars += p->first;
00724     }
00725     
00726     CMOOSMsg Reply;
00727 
00728     //so the client knows the query result correspondences
00729     Reply.m_nID = Msg.m_nID; 
00730     Reply.m_cMsgType = MOOS_NOTIFY;
00731     Reply.m_cDataType = MOOS_STRING;
00732     Reply.m_dfTime = MOOSTime();
00733     Reply.m_sSrc = m_sDBName;
00734     Reply.m_sKey = "VAR_SUMMARY";
00735     Reply.m_sVal = TheVars;
00736     Reply.m_dfVal = -1;
00737 
00738     MsgTxList.push_front(Reply);
00739 
00740     return true;
00741 }
00742 
00743 
00744 
00745 
00746 
00747 bool CMOOSDB::OnClearRequested(CMOOSMsg &Msg, MOOSMSG_LIST &MsgTxList)
00748 {
00749     MOOSTrace("Clear Down Requested:\n");
00750     
00751     MOOSTrace("    Resetting %d variables...",m_VarMap.size());
00752     
00753     DBVAR_MAP::iterator p;
00754     
00755     for(p = m_VarMap.begin();p!=m_VarMap.end();p++)
00756     {
00757         CMOOSDBVar & rVar = p->second;
00758         rVar.Reset();
00759     }
00760     MOOSTrace("done\n");
00761     
00762     
00763     MOOSTrace("    Removing %d existing notification queues...",m_HeldMailMap.size());
00764     MOOSMSG_LIST_STRING_MAP::iterator q;
00765     
00766     for(q = m_HeldMailMap.begin();q!=m_HeldMailMap.end();q++)
00767     {
00768         MOOSMSG_LIST & rList = q->second;
00769         rList.clear();
00770     }
00771     MOOSTrace("done\n");
00772     
00773     //MOOSTrace("    resetting DB start Time...done\n");
00774     LogStartTime();
00775     
00776     
00777     return true;
00778     
00779 }
00780 
00781 
00782 void CMOOSDB::LogStartTime()
00783 {
00784     m_dfStartTime = MOOSTime();
00785     
00786     return;
00787     string sKey = "DB_START_TIME";
00788     
00789     
00790     DBVAR_MAP::iterator p = m_VarMap.find("DB_START_TIME");
00791     
00792     if(p==m_VarMap.end())
00793     {
00794         
00795         CMOOSDBVar NewVar(sKey);
00796         
00797         NewVar.m_cDataType = MOOS_DOUBLE;
00798         NewVar.m_dfVal  = m_dfStartTime;
00799         NewVar.m_dfTime = m_dfStartTime;
00800         NewVar.m_sWhoChangedMe   = m_sDBName;
00801         NewVar.m_sOriginatingCommunity = m_sCommunityName;
00802         
00803         m_VarMap[sKey] = NewVar;
00804         
00805     }
00806     else
00807     {
00808         CMOOSDBVar & rVar = p->second;
00809         rVar.m_dfVal = m_dfStartTime;
00810         rVar.m_dfTime = m_dfStartTime;
00811     }
00812     
00813 }
00814 
00815 
00816 
00817 bool CMOOSDB::VariableExists(const string &sVar)
00818 {
00819     DBVAR_MAP::iterator p=m_VarMap.find(sVar);
00820     
00821     return (!m_VarMap.empty()) && (p!=m_VarMap.end());
00822 }
00823 
00824 void CMOOSDB::Var2Msg(CMOOSDBVar &Var, CMOOSMsg &Msg)
00825 {
00826     Msg.m_dfTime = Var.m_dfTime;
00827     Msg.m_cDataType = Var.m_cDataType;
00828     Msg.m_sSrc = Var.m_sWhoChangedMe;
00829     Msg.m_sKey = Var.m_sName;
00830     Msg.m_sOriginatingCommunity = Var.m_sOriginatingCommunity;
00831     switch(Var.m_cDataType)
00832     {
00833     case MOOS_DOUBLE:
00834         Msg.m_dfVal = Var.m_dfVal;
00835         break;
00836     case MOOS_STRING:
00837         case MOOS_BINARY_STRING:
00838         Msg.m_sVal = Var.m_sVal;
00839         break;
00840     }
00841 }
00842 
00843 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines