00001 /* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- 00002 00003 this file is part of rcssserver3D 00004 Fri May 9 2003 00005 Copyright (C) 2002,2003 Koblenz University 00006 Copyright (C) 2003 RoboCup Soccer Server 3D Maintenance Group 00007 $Id: sparkmonitorclient.cpp,v 1.8 2004/12/22 16:12:45 rollmark Exp $ 00008 00009 This program is free software; you can redistribute it and/or modify 00010 it under the terms of the GNU General Public License as published by 00011 the Free Software Foundation; version 2 of the License. 00012 00013 This program is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with this program; if not, write to the Free Software 00020 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00021 */ 00022 #include "sparkmonitorclient.h" 00023 #include <oxygen/monitorserver/custommonitor.h> 00024 #include <zeitgeist/logserver/logserver.h> 00025 #include <netinet/in.h> 00026 #include <rcssnet/exception.hpp> 00027 #include <cerrno> 00028 00029 using namespace oxygen; 00030 using namespace zeitgeist; 00031 using namespace rcss::net; 00032 using namespace salt; 00033 using namespace boost; 00034 using namespace std; 00035 00036 SparkMonitorClient::SparkMonitorClient() : NetClient() 00037 { 00038 } 00039 00040 SparkMonitorClient::~SparkMonitorClient() 00041 { 00042 } 00043 00044 void SparkMonitorClient::OnLink() 00045 { 00046 // setup SceneServer reference 00047 mSceneServer = shared_dynamic_cast<SceneServer> 00048 (GetCore()->Get("/sys/server/scene")); 00049 00050 if (mSceneServer.get() == 0) 00051 { 00052 GetLog()->Error() 00053 << "(SparkMonitor) ERROR: SceneServer not found\n"; 00054 } 00055 } 00056 00057 void SparkMonitorClient::OnUnlink() 00058 { 00059 mSceneServer.reset(); 00060 if (mManagedScene.get() != 0) 00061 { 00062 mManagedScene->UnlinkChildren(); 00063 mManagedScene.reset(); 00064 } 00065 } 00066 00067 void SparkMonitorClient::InitSimulation() 00068 { 00069 if (! Connect()) 00070 { 00071 return; 00072 } 00073 00074 // get the SceneImporter 00075 mSceneImporter = shared_dynamic_cast<SceneImporter> 00076 (GetCore()->Get("/sys/server/scene/RubySceneImporter")); 00077 00078 if (mSceneImporter.get() == 0) 00079 { 00080 GetLog()->Error() 00081 << "(SparkMonitorClient) ERROR: cannot create" 00082 << "a RubySceneImporter instance\n"; 00083 } 00084 00085 // send the monitor init string 00086 SendMessage("(init)"); 00087 } 00088 00089 void SparkMonitorClient::DoneSimulation() 00090 { 00091 mActiveScene.reset(); 00092 mSceneImporter.reset(); 00093 CloseConnection(); 00094 } 00095 00096 void SparkMonitorClient::StartCycle() 00097 { 00098 ReadFragments(); 00099 00100 string msg; 00101 while (mNetMessage->Extract(mNetBuffer, msg)) 00102 { 00103 ParseMessage(msg); 00104 } 00105 } 00106 00107 void SparkMonitorClient::ParseCustomPredicates(sexp_t* sexp, PredicateList& pList) 00108 { 00109 if ( 00110 (sexp == 0) || 00111 (sexp->ty != SEXP_VALUE) 00112 ) 00113 { 00114 return; 00115 } 00116 00117 Predicate& pred = pList.AddPredicate(); 00118 pred.name = sexp->val; 00119 00120 sexp = sexp->next; 00121 while (sexp != 0) 00122 { 00123 if (sexp->ty == SEXP_VALUE) 00124 { 00125 pred.parameter.AddValue(sexp->val); 00126 } 00127 00128 sexp = sexp->next; 00129 } 00130 } 00131 00132 void SparkMonitorClient::ParseCustomPredicates(sexp_t* sexp) 00133 { 00134 // ( (name param1 param2 ...) (name param1 param2 ...) ... ) 00135 if (sexp == 0) 00136 { 00137 return; 00138 } 00139 00140 // get list of registered CustomMonitor objects 00141 TLeafList customList; 00142 ListChildrenSupportingClass<CustomMonitor>(customList); 00143 00144 if (customList.empty()) 00145 { 00146 return; 00147 } 00148 00149 // parse predicates 00150 PredicateList pList; 00151 00152 sexp = sexp->list; 00153 while (sexp != 0) 00154 { 00155 if (sexp->ty == SEXP_LIST) 00156 { 00157 sexp_t* sPred = sexp->list; 00158 ParseCustomPredicates(sPred,pList); 00159 } 00160 00161 sexp = sexp->next; 00162 } 00163 00164 // pass predicates to all registered CustomMonitor objects 00165 for ( 00166 TLeafList::iterator iter = customList.begin(); 00167 iter != customList.end(); 00168 ++iter 00169 ) 00170 { 00171 shared_static_cast<CustomMonitor>((*iter)) 00172 ->ParseCustomPredicates(pList); 00173 } 00174 } 00175 00176 void SparkMonitorClient::ParseMessage(const string& msg) 00177 { 00178 if ( 00179 (mSceneServer.get() == 0) || 00180 (mSceneImporter.get() == 0) 00181 ) 00182 { 00183 return; 00184 } 00185 00186 mActiveScene = mSceneServer->GetActiveScene(); 00187 00188 if (mActiveScene.get() == 0) 00189 { 00190 return; 00191 } 00192 00193 if (mManagedScene.get() == 0) 00194 { 00195 mManagedScene = shared_dynamic_cast<BaseNode> 00196 (GetCore()->New("oxygen/BaseNode")); 00197 mActiveScene->AddChildReference(mManagedScene); 00198 } 00199 00200 // parse s-expressions; we expect a leading list of custom 00201 // predicates followed by the RubySceneGraph expressions 00202 00213 char* msgBuf = const_cast<char*>(msg.c_str()); 00214 pcont_t* pcont = init_continuation(msgBuf); 00215 sexp_t* sexp_custom = iparse_sexp(msgBuf,msg.size(),pcont); 00216 00217 if (sexp_custom == 0) 00218 { 00219 destroy_sexp(sexp_custom); 00220 destroy_continuation(pcont); 00221 return; 00222 } 00223 00224 ParseCustomPredicates(sexp_custom); 00225 00226 mSceneImporter->ParseScene(string(pcont->lastPos), 00227 mManagedScene, 00228 shared_ptr<ParameterList>()); 00229 00230 destroy_sexp(sexp_custom); 00231 destroy_continuation(pcont); 00232 }