descriptions-manager.cpp
Go to the documentation of this file.
00001 /*
00002         Aseba - an event-based framework for distributed robot control
00003         Copyright (C) 2007--2012:
00004                 Stephane Magnenat <stephane at magnenat dot net>
00005                 (http://stephane.magnenat.net)
00006                 and other contributors, see authors.txt for details
00007         
00008         This program is free software: you can redistribute it and/or modify
00009         it under the terms of the GNU Lesser General Public License as published
00010         by the Free Software Foundation, version 3 of the License.
00011         
00012         This program is distributed in the hope that it will be useful,
00013         but WITHOUT ANY WARRANTY; without even the implied warranty of
00014         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015         GNU Lesser General Public License for more details.
00016         
00017         You should have received a copy of the GNU Lesser General Public License
00018         along with this program. If not, see <http://www.gnu.org/licenses/>.
00019 */
00020 
00021 #include "descriptions-manager.h"
00022 #include "msg.h"
00023 #include <iostream>
00024 
00025 using namespace std;
00026 
00027 namespace Aseba
00028 {
00029         DescriptionsManager::NodeDescription::NodeDescription() :
00030                 namedVariablesReceptionCounter(0),
00031                 localEventsReceptionCounter(0),
00032                 nativeFunctionReceptionCounter(0)
00033         {
00034         }
00035         
00036         DescriptionsManager::NodeDescription::NodeDescription(const TargetDescription& targetDescription) :
00037                 TargetDescription(targetDescription),
00038                 namedVariablesReceptionCounter(0),
00039                 localEventsReceptionCounter(0),
00040                 nativeFunctionReceptionCounter(0)
00041         {
00042         }
00043         
00044         void DescriptionsManager::processMessage(const Message* message)
00045         {
00046                 // if we have a disconnection message
00047                 {
00048                         const Disconnected *disconnected = dynamic_cast<const Disconnected *>(message);
00049                         if (disconnected)
00050                         {
00051                                 NodesDescriptionsMap::iterator it = nodesDescriptions.find(disconnected->source);
00052                                 if (it != nodesDescriptions.end())
00053                                         nodesDescriptions.erase(it);
00054                         }
00055                 }
00056                 
00057                 // if we have an initial description
00058                 {
00059                         const Description *description = dynamic_cast<const Description *>(message);
00060                         if (description)
00061                         {
00062                                 NodesDescriptionsMap::iterator it = nodesDescriptions.find(description->source);
00063                                 
00064                                 // We can receive a description twice, for instance if there is another IDE connected
00065                                 if (it != nodesDescriptions.end())
00066                                         return;
00067                                 
00068                                 // Call a user function when a node protocol version mismatches
00069                                 if (description->protocolVersion != ASEBA_PROTOCOL_VERSION)
00070                                 {
00071                                         nodeProtocolVersionMismatch(description->name, description->protocolVersion);
00072                                         return;
00073                                 }
00074                                 
00075                                 // create node and copy description into it
00076                                 nodesDescriptions[description->source] = NodeDescription(*description);
00077                                 checkIfNodeDescriptionComplete(description->source, nodesDescriptions[description->source]);
00078                         }
00079                 }
00080                 
00081                 // if we have a named variabledescription
00082                 {
00083                         const NamedVariableDescription *description = dynamic_cast<const NamedVariableDescription *>(message);
00084                         if (description)
00085                         {
00086                                 NodesDescriptionsMap::iterator it = nodesDescriptions.find(description->source);
00087                                 
00088                                 // we must have received a description first
00089                                 if (it == nodesDescriptions.end())
00090                                         return;
00091                                 
00092                                 // copy description into array if array is empty
00093                                 if (it->second.namedVariablesReceptionCounter < it->second.namedVariables.size())
00094                                 {
00095                                         it->second.namedVariables[it->second.namedVariablesReceptionCounter++] = *description;
00096                                         checkIfNodeDescriptionComplete(it->first, it->second);
00097                                 }
00098                         }
00099                 }
00100                 
00101                 // if we have a local event description
00102                 {
00103                         const LocalEventDescription *description = dynamic_cast<const LocalEventDescription *>(message);
00104                         if (description)
00105                         {
00106                                 NodesDescriptionsMap::iterator it = nodesDescriptions.find(description->source);
00107                                 
00108                                 // we must have received a description first
00109                                 if (it == nodesDescriptions.end())
00110                                         return;
00111                                 
00112                                 // copy description into array if array is empty
00113                                 if (it->second.localEventsReceptionCounter < it->second.localEvents.size())
00114                                 {
00115                                         it->second.localEvents[it->second.localEventsReceptionCounter++] = *description;
00116                                         checkIfNodeDescriptionComplete(it->first, it->second);
00117                                 }
00118                         }
00119                 }
00120                 
00121                 // if we have a native function description
00122                 {
00123                         const NativeFunctionDescription *description = dynamic_cast<const NativeFunctionDescription *>(message);
00124                         if (description)
00125                         {
00126                                 NodesDescriptionsMap::iterator it = nodesDescriptions.find(description->source);
00127                                 
00128                                 // we must have received a description first
00129                                 if (it == nodesDescriptions.end())
00130                                         return;
00131                                 
00132                                 // copy description into array
00133                                 if (it->second.nativeFunctionReceptionCounter < it->second.nativeFunctions.size())
00134                                 {
00135                                         it->second.nativeFunctions[it->second.nativeFunctionReceptionCounter++] = *description;
00136                                         checkIfNodeDescriptionComplete(it->first, it->second);
00137                                 }
00138                         }
00139                 }
00140         }
00141 
00142         void DescriptionsManager::checkIfNodeDescriptionComplete(unsigned id, const NodeDescription& description)
00143         {
00144                 // we will call the virtual function only when we have received all local events and native functions
00145                 if ((description.namedVariablesReceptionCounter == description.namedVariables.size()) &&
00146                         (description.localEventsReceptionCounter == description.localEvents.size()) &&
00147                         (description.nativeFunctionReceptionCounter == description.nativeFunctions.size())
00148                 )
00149                 {
00150                         nodeDescriptionReceived(id);
00151                 }
00152         }
00153         
00154         std::wstring DescriptionsManager::getNodeName(unsigned nodeId) const
00155         {
00156                 NodesDescriptionsMap::const_iterator it = nodesDescriptions.find(nodeId);
00157                 if (it != nodesDescriptions.end())
00158                 {
00159                         return it->second.name;
00160                 }
00161                 else
00162                 {
00163                         return L"";
00164                 }
00165         }
00166         
00167         unsigned DescriptionsManager::getNodeId(const std::wstring& name, unsigned preferedId, bool *ok) const
00168         {
00169                 // search for the first node with a given name
00170                 bool found(false);
00171                 unsigned foundId(0);
00172                 for (NodesDescriptionsMap::const_iterator it = nodesDescriptions.begin(); it != nodesDescriptions.end(); ++it)
00173                 {
00174                         if (it->second.name == name)
00175                         {
00176                                 if (ok)
00177                                         *ok = true;
00178                                 
00179                                 if (it->first == preferedId)
00180                                         return it->first;
00181                                 else if (!found)
00182                                         foundId = it->first;
00183                                 
00184                                 found = true;
00185                         }
00186                 }
00187                 
00188                 // node found, but with another id than prefered
00189                 if (found)
00190                         return foundId;
00191                 
00192                 // node not found
00193                 if (ok)
00194                         *ok = false;
00195                 return 0xFFFFFFFF;
00196         }
00197         
00198         const TargetDescription * const DescriptionsManager::getDescription(unsigned nodeId, bool *ok) const
00199         {
00200                 NodesDescriptionsMap::const_iterator it = nodesDescriptions.find(nodeId);
00201                 
00202                 // node not found
00203                 if (it == nodesDescriptions.end())
00204                 {
00205                         if (ok)
00206                                 *ok = false;
00207                         return 0;
00208                 }
00209                 
00210                 if (ok)
00211                         *ok = true;
00212                 return &(it->second);
00213         }
00214         
00215         unsigned DescriptionsManager::getVariablePos(unsigned nodeId, const std::wstring& name, bool *ok) const
00216         {
00217                 NodesDescriptionsMap::const_iterator it = nodesDescriptions.find(nodeId);
00218                 
00219                 // node not found
00220                 if (it != nodesDescriptions.end())
00221                 {
00222                         size_t pos = 0;
00223                         for (size_t i = 0; i < it->second.namedVariables.size(); ++i)
00224                         {
00225                                 if (it->second.namedVariables[i].name == name)
00226                                 {
00227                                         if (ok)
00228                                                 *ok = true;
00229                                         return pos;
00230                                 }
00231                                 pos += it->second.namedVariables[i].size;
00232                         }
00233                 }
00234                 
00235                 // node not found or variable not found
00236                 if (ok)
00237                         *ok = false;
00238                 return 0xFFFFFFFF;
00239         }
00240         
00241         unsigned DescriptionsManager::getVariableSize(unsigned nodeId, const std::wstring& name, bool *ok) const
00242         {
00243                 NodesDescriptionsMap::const_iterator it = nodesDescriptions.find(nodeId);
00244                 
00245                 // node not found
00246                 if (it != nodesDescriptions.end())
00247                 {
00248                         for (size_t i = 0; i < it->second.namedVariables.size(); ++i)
00249                         {
00250                                 if (it->second.namedVariables[i].name == name)
00251                                 {
00252                                         if (ok)
00253                                                 *ok = true;
00254                                         return it->second.namedVariables[i].size;
00255                                 }
00256                         }
00257                 }
00258                 
00259                 // node not found or variable not found
00260                 if (ok)
00261                         *ok = false;
00262                 return 0xFFFFFFFF;
00263         }
00264         
00265         void DescriptionsManager::reset()
00266         {
00267                 nodesDescriptions.clear();
00268         }
00269 }


aseba
Author(s): Stéphane Magnenat
autogenerated on Thu Jan 2 2014 11:17:16