#include "field.hpp" #include "attribute_template.hpp" #include "object_template.hpp" #include "group_template.hpp" #include "node_type.hpp" #include "calendar_util.hpp" #include "message.hpp" #include "xios_spl.hpp" #include "type.hpp" #include "context_client.hpp" #include "context_server.hpp" #include namespace xios{ /// ////////////////////// Définitions ////////////////////// /// CField::CField(void) : CObjectTemplate(), CFieldAttributes() , refObject(), baseRefObject() , grid(), file() , freq_operation(), freq_write() , nstep(0), nstepMax(0), isEOF(false) , last_Write(), last_operation() , foperation(), hasInstantData(false), hasExpression(false) , active(false) , hasOutputFile(false),hasFieldOut(false), slotUpdateDate(NULL) , processed(false), domAxisIds_("", ""), areAllReferenceSolved(false), areAllExpressionBuilt(false) , isReadDataRequestPending(false) { setVirtualVariableGroup(); } CField::CField(const StdString& id) : CObjectTemplate(id), CFieldAttributes() , refObject(), baseRefObject() , grid(), file() , freq_operation(), freq_write() , nstep(0), nstepMax(0), isEOF(false) , last_Write(), last_operation() , foperation(), hasInstantData(false), hasExpression(false) , active(false), hasOutputFile(false), hasFieldOut(false), slotUpdateDate(NULL) , processed(false), domAxisIds_("", ""), areAllReferenceSolved(false), areAllExpressionBuilt(false) , isReadDataRequestPending(false) { setVirtualVariableGroup(); } CField::~CField(void) { // this->grid.reset(); // this->file.reset(); this->foperation.reset(); if (hasExpression) delete expression; if (slotUpdateDate != NULL) delete slotUpdateDate; } //---------------------------------------------------------------- void CField::setVirtualVariableGroup(CVariableGroup* newVVariableGroup) { this->vVariableGroup = newVVariableGroup; } void CField::setVirtualVariableGroup(void) { this->setVirtualVariableGroup(CVariableGroup::create()); } CVariableGroup* CField::getVirtualVariableGroup(void) const { return this->vVariableGroup; } std::vector CField::getAllVariables(void) const { return this->vVariableGroup->getAllChildren(); } void CField::solveDescInheritance(bool apply, const CAttributeMap* const parent) { SuperClassAttribute::setAttributes(parent, apply); this->getVirtualVariableGroup()->solveDescInheritance(apply, NULL); } //---------------------------------------------------------------- //---------------------------------------------------------------- bool CField::updateDataServer (const CDate& currDate, const std::deque< CArray* > storedClient) { const CDate opeDate = *last_operation + freq_operation; const CDate writeDate = *last_Write + freq_write; if (opeDate <= currDate) { if (this->data.numElements() != this->grid->storeIndex[0]->numElements()) { this->data.resize(this->grid->storeIndex[0]->numElements()); } CArray input(data.numElements()); this->grid->inputFieldServer(storedClient, input); (*this->foperation)(input); *last_operation = currDate; } if (writeDate < (currDate + freq_operation)) { this->foperation->final(); this->incrementNStep(); *last_Write = writeDate; return true; } return false; } bool CField::dispatchEvent(CEventServer& event) { if (SuperClass::dispatchEvent(event)) return true; else { switch(event.type) { case EVENT_ID_UPDATE_DATA : recvUpdateData(event); return true; break; case EVENT_ID_READ_DATA : recvReadDataRequest(event); return true; break; case EVENT_ID_READ_DATA_READY : recvReadDataReady(event); return true; break; case EVENT_ID_ADD_VARIABLE : recvAddVariable(event); return true; break; case EVENT_ID_ADD_VARIABLE_GROUP : recvAddVariableGroup(event); return true; break; default : ERROR("bool CField::dispatchEvent(CEventServer& event)", << "Unknown Event"); return false; } } } void CField::sendUpdateData(void) { CContext* context = CContext::getCurrent(); CContextClient* client = context->client; CEventClient event(getType(),EVENT_ID_UPDATE_DATA); map* >::iterator it; list > list_msg; list< CArray* > list_data; if (!grid->doGridHaveDataDistributed()) { if (0 == client->clientRank) { for(it=grid->storeIndex_toSrv.begin();it!=grid->storeIndex_toSrv.end();it++) { int rank=(*it).first ; CArray& index = *(it->second) ; CArray data_tmp(index.numElements()) ; for(int n=0;n(new CMessage)) ; list_data.push_back(new CArray(data_tmp)) ; *list_msg.back()<sendEvent(event) ; } else client->sendEvent(event); } else { for(it=grid->storeIndex_toSrv.begin();it!=grid->storeIndex_toSrv.end();it++) { int rank=(*it).first ; CArray& index = *(it->second) ; CArray data_tmp(index.numElements()) ; for(int n=0;n(new CMessage)) ; list_data.push_back(new CArray(data_tmp)) ; *list_msg.back()<nbSenders[rank],*list_msg.back()) ; } client->sendEvent(event) ; } for (list< CArray* >::iterator it = list_data.begin(); it != list_data.end(); it++) delete *it; } void CField::recvUpdateData(CEventServer& event) { vector ranks; vector buffers; list::iterator it; string fieldId; for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) { int rank = it->rank; CBufferIn* buffer = it->buffer; *buffer >> fieldId; ranks.push_back(rank); buffers.push_back(buffer); } get(fieldId)->recvUpdateData(ranks,buffers); } void CField::recvUpdateData(vector& ranks, vector& buffers) { if (data_srv.empty()) { for (map* >::iterator it = grid->outIndexFromClient.begin(); it != grid->outIndexFromClient.end(); ++it) { int rank = it->first; CArray data_tmp(it->second->numElements()); data_srv.insert( pair* >(rank, new CArray(data_tmp))); foperation_srv.insert(pair >(rank,boost::shared_ptr(new func::CInstant(*data_srv[rank])))); } } CContext* context = CContext::getCurrent(); const CDate& currDate = context->getCalendar()->getCurrentDate(); const CDate opeDate = *last_operation_srv + freq_operation_srv; const CDate writeDate = *last_Write_srv + freq_write_srv; if (opeDate <= currDate) { for (int n = 0; n < ranks.size(); n++) { CArray data_tmp; *buffers[n] >> data_tmp; (*foperation_srv[ranks[n]])(data_tmp); } *last_operation_srv = currDate; } if (writeDate < (currDate + freq_operation_srv)) { for (int n = 0; n < ranks.size(); n++) { this->foperation_srv[ranks[n]]->final(); } *last_Write_srv = writeDate; writeField(); *lastlast_Write_srv = *last_Write_srv; } } void CField::writeField(void) { if (!getRelFile()->allDomainEmpty) { if (grid->doGridHaveDataToWrite() || getRelFile()->type == CFile::type_attr::one_file) { getRelFile()->checkFile(); this->incrementNStep(); getRelFile()->getDataOutput()->writeFieldData(CField::get(this)); } } } void CField::sendReadDataRequest(void) { CContext* context = CContext::getCurrent(); CContextClient* client = context->client; CEventClient event(getType(), EVENT_ID_READ_DATA); if (client->isServerLeader()) { CMessage msg; msg << getId(); const std::list& ranks = client->getRanksServerLeader(); for (std::list::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) event.push(*itRank, 1, msg); client->sendEvent(event); } else client->sendEvent(event); lastDataRequestedFromServer = context->getCalendar()->getCurrentDate(); isReadDataRequestPending = true; } /*! Send request new data read from file if need be, that is the current data is out-of-date. \return true if and only if some data was requested */ bool CField::sendReadDataRequestIfNeeded(void) { const CDate& currentDate = CContext::getCurrent()->getCalendar()->getCurrentDate(); bool requestData = (currentDate >= lastDataRequestedFromServer + file->output_freq.getValue()); if (requestData) sendReadDataRequest(); return requestData; } void CField::recvReadDataRequest(CEventServer& event) { CBufferIn* buffer = event.subEvents.begin()->buffer; StdString fieldId; *buffer >> fieldId; get(fieldId)->recvReadDataRequest(); } void CField::recvReadDataRequest(void) { CContext* context = CContext::getCurrent(); CContextClient* client = context->client; CEventClient event(getType(), EVENT_ID_READ_DATA_READY); std::list msgs; bool hasData = readField(); map* >::iterator it; for (it = data_srv.begin(); it != data_srv.end(); it++) { msgs.push_back(CMessage()); CMessage& msg = msgs.back(); msg << getId(); if (hasData) msg << getNStep() - 1 << *it->second; else msg << SIZE_MAX; event.push(it->first, grid->nbSenders[it->first], msg); } client->sendEvent(event); } bool CField::readField(void) { if (!getRelFile()->allDomainEmpty) { if (grid->doGridHaveDataToWrite() || getRelFile()->type == CFile::type_attr::one_file) { if (data_srv.empty()) { for (map* >::iterator it = grid->outIndexFromClient.begin(); it != grid->outIndexFromClient.end(); ++it) data_srv.insert(pair*>(it->first, new CArray(it->second->numElements()))); } getRelFile()->checkFile(); this->incrementNStep(); if (!nstepMax) { nstepMax = getRelFile()->getDataInput()->getFieldNbRecords(CField::get(this)); } if (getNStep() > nstepMax) return false; getRelFile()->getDataInput()->readFieldData(CField::get(this)); } } return true; } void CField::recvReadDataReady(CEventServer& event) { string fieldId; vector ranks; vector buffers; list::iterator it; for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it) { ranks.push_back(it->rank); CBufferIn* buffer = it->buffer; *buffer >> fieldId; buffers.push_back(buffer); } get(fieldId)->recvReadDataReady(ranks, buffers); } void CField::recvReadDataReady(vector ranks, vector buffers) { CContext* context = CContext::getCurrent(); StdSize record; for (int i = 0; i < ranks.size(); i++) { int rank = ranks[i]; *buffers[i] >> record; isEOF = (record == SIZE_MAX); if (!isEOF) { CArray& index = *grid->storeIndex_toSrv[rank]; CArray data_tmp(index.numElements()); *buffers[i] >> data_tmp; for (int n = 0; n < data_tmp.numElements(); n++) instantData(index(n)) = data_tmp(n); } else break; } if (!isEOF) { for (list< pair >::iterator it = fieldDependency.begin(); it != fieldDependency.end(); ++it) it->first->setSlot(it->second); if (!hasExpression) // Should be always true ? { const std::vector& refField = getAllReference(); std::vector::const_iterator it = refField.begin(), end = refField.end(); for (; it != end; it++) (*it)->setDataFromExpression(instantData); if (hasFieldOut) updateDataFromExpression(instantData); } } isReadDataRequestPending = false; } //---------------------------------------------------------------- void CField::setRelFile(CFile* _file) { this->file = _file; hasOutputFile = true; } //---------------------------------------------------------------- StdString CField::GetName(void) { return StdString("field"); } StdString CField::GetDefName(void) { return CField::GetName(); } ENodeType CField::GetType(void) { return eField; } //---------------------------------------------------------------- CGrid* CField::getRelGrid(void) const { return this->grid; } //---------------------------------------------------------------- CFile* CField::getRelFile(void) const { return this->file; } StdSize CField::getNStep(void) const { return this->nstep; } void CField::incrementNStep(void) { this->nstep++; } void CField::resetNStep(void) { this->nstep = 0; } void CField::resetNStepMax(void) { this->nstepMax = 0; } //---------------------------------------------------------------- const CDuration& CField::getFreqOperation(void) const { return this->freq_operation; } //---------------------------------------------------------------- const CDuration& CField::getFreqWrite(void) const { return this->freq_write; } //---------------------------------------------------------------- boost::shared_ptr CField::getFieldOperation(void) const { return this->foperation; } bool CField::isActive(void) const { return !this->refObject.empty(); } //---------------------------------------------------------------- CArray CField::getData(void) const { return(this->data); } //---------------------------------------------------------------- boost::shared_ptr CField::getLastWriteDate(void) const { return(this->last_Write); } //---------------------------------------------------------------- boost::shared_ptr CField::getLastOperationDate(void) const { return(this->last_operation); } //---------------------------------------------------------------- // void CField::processEnabledField(void) // { // if (!processed) // { // processed = true; // solveRefInheritance(true); // solveBaseReference(); // solveOperation(); // solveGridReference(); // // if (hasDirectFieldReference()) baseRefObject->processEnabledField(); // buildExpression(); // active = true; // } // } void CField::solveAllReferenceEnabledField(bool doSending2Sever) { CContext* context = CContext::getCurrent(); if (!areAllReferenceSolved) { areAllReferenceSolved = true; if (context->hasClient) { solveRefInheritance(true); solveBaseReference(); } solveOperation(); solveGridReference(); } solveGridDomainAxisRef(doSending2Sever); solveCheckMaskIndex(doSending2Sever); } std::map CField::getGridDataSize() { return grid->getConnectedServerDataSize(); } void CField::buildAllExpressionEnabledField() { if (!areAllReferenceSolved) solveAllReferenceEnabledField(true); if (!areAllExpressionBuilt) { areAllExpressionBuilt = true; // solveCheckMaskIndex(true); // solveCheckMaskIndex(); if (hasDirectFieldReference()) baseRefObject->buildAllExpressionEnabledField(); buildExpression(); active = true; } } //---------------------------------------------------------------- void CField::solveOperation(void) { using namespace func; if (!hasOutputFile && !hasFieldOut) return; StdString id; if (hasId()) id = getId(); else if (!name.isEmpty()) id = name; else if (hasDirectFieldReference()) id = baseRefObject->getId(); CContext* context = CContext::getCurrent(); if (freq_op.isEmpty()) freq_op.setValue(TimeStep); if (operation.isEmpty()) { ERROR("CField::solveOperation(void)", << "[ id = " << id << "]" << "Impossible to define an operation for this field !"); } if (freq_offset.isEmpty()) freq_offset.setValue(NoneDu); // if (CXIOSManager::GetStatus() == CXIOSManager::LOC_SERVER) if (context->hasServer) { if (hasOutputFile) { this->freq_operation_srv = this->file->output_freq.getValue(); this->freq_write_srv = this->file->output_freq.getValue(); } this->lastlast_Write_srv = boost::shared_ptr (new CDate(context->getCalendar()->getInitDate())); this->last_Write_srv = boost::shared_ptr (new CDate(context->getCalendar()->getInitDate())); this->last_operation_srv = boost::shared_ptr (new CDate(context->getCalendar()->getInitDate())); // this->foperation_srv = // boost::shared_ptr(new CInstant(this->data_srv)); if (hasOutputFile) { const CDuration toffset = this->freq_operation_srv - freq_offset.getValue() - context->getCalendar()->getTimeStep(); *this->last_operation_srv = *this->last_operation_srv - toffset; } } // if (context->hasClient) // { this->freq_operation = freq_op.getValue(); if (hasOutputFile) this->freq_write = this->file->output_freq.getValue(); if (hasFieldOut) { this->freq_write = this->fieldOut->freq_op.getValue(); } this->last_Write = boost::shared_ptr (new CDate(context->getCalendar()->getInitDate())); this->last_operation = boost::shared_ptr (new CDate(context->getCalendar()->getInitDate())); const CDuration toffset = this->freq_operation - freq_offset.getValue() - context->getCalendar()->getTimeStep(); *this->last_operation = *this->last_operation - toffset; lastDataRequestedFromServer.setRelCalendar(*context->getCalendar()); if (operation.get() == "once") isOnceOperation = true; else isOnceOperation = false; isFirstOperation = true; #define DECLARE_FUNCTOR(MType, mtype) \ if (operation.getValue().compare(#mtype) == 0) \ { \ if (!detect_missing_value.isEmpty() && !default_value.isEmpty() && detect_missing_value == true) \ { \ boost::shared_ptr foperation_(new C##MType(this->data,default_value)); \ this->foperation = foperation_; \ } \ else \ { \ boost::shared_ptr foperation_(new C##MType(this->data)); \ this->foperation = foperation_; \ } \ return; \ } #include "functor_type.conf" ERROR("CField::solveOperation(void)", << "[ operation = " << operation.getValue() << "]" << "The operation is not defined !"); // } } //---------------------------------------------------------------- /* void CField::fromBinary(StdIStream& is) { SuperClass::fromBinary(is); #define CLEAR_ATT(name_)\ SuperClassAttribute::operator[](#name_)->reset() CLEAR_ATT(domain_ref); CLEAR_ATT(axis_ref); #undef CLEAR_ATT } */ //---------------------------------------------------------------- void CField::solveGridReference(void) { CDomain* domain; CAxis* axis; std::vector vecDom; std::vector vecAxis; std::vector domList, axisList; if (!domain_ref.isEmpty()) { if (CDomain::has(domain_ref.getValue())) { domain = CDomain::get(domain_ref.getValue()); vecDom.push_back(domain); } else ERROR("CField::solveGridReference(void)", << "Reference to the domain \'" << domain_ref.getValue() << "\' is wrong"); } if (!axis_ref.isEmpty()) { if (CAxis::has(axis_ref.getValue())) { axis = CAxis::get(axis_ref.getValue()); vecAxis.push_back(axis); } else ERROR("CField::solveGridReference(void)", << "Reference to the axis \'" << axis_ref.getValue() <<"\' is wrong"); } if (!grid_ref.isEmpty()) { if (CGrid::has(grid_ref.getValue())) { this->grid = CGrid::get(grid_ref.getValue()); domList = grid->getDomainList(); axisList = grid->getAxisList(); if (domList.empty() && axisList.empty() && (!(this->grid->scalar_grid.getValue()))) { this->grid = CGrid::createGrid(vecDom, vecAxis); } } else ERROR("CField::solveGridReference(void)", << "Reference to the grid \'" << grid_ref.getValue() << "\' is wrong"); } else { this->grid = CGrid::createGrid(vecDom, vecAxis); } if (grid_ref.isEmpty() && domain_ref.isEmpty() && axis_ref.isEmpty()) { ERROR("CField::solveGridReference(void)", << "At least one dimension must be defined for this field."); } } void CField::solveGridDomainAxisRef(bool checkAtt) { grid->solveDomainAxisRef(checkAtt); } void CField::solveCheckMaskIndex(bool doSendingIndex) { grid->checkMaskIndex(doSendingIndex); } ///------------------------------------------------------------------- template <> void CGroupTemplate::solveRefInheritance(void) { if (this->group_ref.isEmpty()) return; StdString gref = this->group_ref.getValue(); if (!CFieldGroup::has(gref)) ERROR("CGroupTemplate::solveRefInheritance(void)", << "[ gref = " << gref << "]" << " invalid group name !"); CFieldGroup* group = CFieldGroup::get(gref); CFieldGroup* owner = CFieldGroup::get(boost::polymorphic_downcast(this)); std::vector allChildren = group->getAllChildren(); std::vector::iterator it = allChildren.begin(), end = allChildren.end(); for (; it != end; it++) { CField* child = *it; if (child->hasId()) owner->createChild()->field_ref.setValue(child->getId()); } } void CField::scaleFactorAddOffset(double scaleFactor, double addOffset) { map* >::iterator it; for (it = data_srv.begin(); it != data_srv.end(); it++) *it->second = (*it->second - addOffset) / scaleFactor; } void CField::invertScaleFactorAddOffset(double scaleFactor, double addOffset) { map* >::iterator it; for (it = data_srv.begin(); it != data_srv.end(); it++) *it->second = *it->second * scaleFactor + addOffset; } void CField::outputField(CArray& fieldOut) { map* >::iterator it; for (it = data_srv.begin(); it != data_srv.end(); it++) { grid->outputField(it->first,*it->second, fieldOut.dataFirst()); } } void CField::outputField(CArray& fieldOut) { map* >::iterator it; for(it=data_srv.begin();it!=data_srv.end();it++) { grid->outputField(it->first,*it->second, fieldOut.dataFirst()) ; } } void CField::outputField(CArray& fieldOut) { map* >::iterator it; for (it = data_srv.begin(); it != data_srv.end(); it++) { grid->outputField(it->first,*it->second, fieldOut.dataFirst()) ; } } void CField::inputField(CArray& fieldOut) { map*>::iterator it; for (it = data_srv.begin(); it != data_srv.end(); it++) { grid->inputField(it->first, fieldOut.dataFirst(), *it->second); } } void CField::inputField(CArray& fieldOut) { map*>::iterator it; for(it = data_srv.begin(); it != data_srv.end(); it++) { grid->inputField(it->first, fieldOut.dataFirst(), *it->second); } } void CField::inputField(CArray& fieldOut) { map*>::iterator it; for (it = data_srv.begin(); it != data_srv.end(); it++) { grid->inputField(it->first, fieldOut.dataFirst(), *it->second); } } ///------------------------------------------------------------------- void CField::parse(xml::CXMLNode& node) { SuperClass::parse(node); if (!node.getContent(this->content)) { if (node.goToChildElement()) { do { if (node.getElementName() == "variable" || node.getElementName() == "variable_group") this->getVirtualVariableGroup()->parseChild(node); } while (node.goToNextElement()); node.goToParentElement(); } } } CArray* CField::getInstantData(void) { if (!hasInstantData) { instantData.resize(grid->storeIndex_client.numElements()); hasInstantData = true; } return &instantData; } void CField::addDependency(CField* field, int slotId) { fieldDependency.push_back(pair(field,slotId)); } void CField::buildExpression(void) { if (content.size() > 0) { CSimpleNodeExpr* simpleExpr = parseExpr(content+'\0'); expression = CFieldNode::newNode(simpleExpr); delete simpleExpr; set instantFieldIds; map associatedInstantFieldIds; expression->getInstantFieldIds(instantFieldIds); for (set::iterator it = instantFieldIds.begin(); it != instantFieldIds.end(); ++it) { if (*it != "this") { if (CField::has(*it)) { CField* field = CField::get(*it); // field->processEnabledField(); field->buildAllExpressionEnabledField(); associatedInstantFieldIds[*it] = field; } else ERROR("void CField::buildExpression(void)", << " Field " << *it << " does not exist"); } } set averageFieldIds; map associatedAverageFieldIds; expression->getAverageFieldIds(averageFieldIds); for (set::iterator it = averageFieldIds.begin(); it != averageFieldIds.end(); ++it) { if (CField::has(*it)) { CFieldGroup* root = CFieldGroup::get("field_definition"); CField* averageField = root->createChild(); CField* instantField = root->createChild(); averageField->field_ref = *it; averageField->hasFieldOut = true; averageField->fieldOut = instantField; instantField->freq_op = freq_op; // averageField-> processEnabledField(); averageField->buildAllExpressionEnabledField(); instantField->SuperClassAttribute::setAttributes(averageField, true); instantField->field_ref.reset(); instantField->operation.reset(); // instantField-> processEnabledField(); instantField->buildAllExpressionEnabledField(); associatedAverageFieldIds[*it] = instantField; } else ERROR("void CField::buildExpression(void)", << " Field " << *it << " does not exist"); } expression->reduce(this,associatedInstantFieldIds,associatedAverageFieldIds); slots.resize(instantFieldIds.size() + averageFieldIds.size()); resetSlots(); int slotId = 0; set fields; expression->getFields(fields); for (set::iterator it = fields.begin(); it != fields.end(); ++it, ++slotId) (*it)->addDependency(this,slotId); hasExpression = true; } } void CField::resetSlots(void) { for (vector::iterator it = slots.begin(); it != slots.end(); ++it) *it = false; } bool CField::slotsFull(void) { bool ret = true; for (vector::iterator it = slots.begin(); it != slots.end(); ++it) ret &= *it; return ret; } void CField::setSlot(int slotId) { CContext* context = CContext::getCurrent(); const CDate& currDate = context->getCalendar()->getCurrentDate(); if (slotUpdateDate == NULL || currDate != *slotUpdateDate) { resetSlots(); if (slotUpdateDate == NULL) slotUpdateDate = new CDate(currDate); else *slotUpdateDate = currDate; } slots[slotId] = true; if (slotsFull()) { CArray expr(expression->compute()); if (hasInstantData) { instantData = expr; for (list< pair >::iterator it = fieldDependency.begin(); it != fieldDependency.end(); ++it) if (it->first != this) it->first->setSlot(it->second); } if (hasOutputFile) updateDataFromExpression(expr); const std::vector& refField = getAllReference(); for (std::vector::const_iterator it = refField.begin(); it != refField.end(); it++) { if (!(*it)->hasExpression) (*it)->setDataFromExpression(expr); } } } /*! This function retrieves Id of corresponding domain_ref and axis_ref (if any) of a field. In some cases, only domain exists but axis doesn't \return pair of Domain and Axis id */ const std::pair& CField::getRefDomainAxisIds() { CGrid* cgPtr = getRelGrid(); if (NULL != cgPtr) { std::vector::iterator it; if (!domain_ref.isEmpty()) { std::vector domainList = cgPtr->getDomainList(); it = std::find(domainList.begin(), domainList.end(), domain_ref.getValue()); if (domainList.end() != it) domAxisIds_.first = *it; } if (!axis_ref.isEmpty()) { std::vector axisList = cgPtr->getAxisList(); it = std::find(axisList.begin(), axisList.end(), axis_ref.getValue()); if (axisList.end() != it) domAxisIds_.second = *it; } } return (domAxisIds_); } CVariable* CField::addVariable(const string& id) { return vVariableGroup->createChild(id); } CVariableGroup* CField::addVariableGroup(const string& id) { return vVariableGroup->createChildGroup(id); } void CField::sendAddAllVariables() { if (!getAllVariables().empty()) { // Firstly, it's necessary to add virtual variable group sendAddVariableGroup(getVirtualVariableGroup()->getId()); // Okie, now we can add to this variable group std::vector allVar = getAllVariables(); std::vector::const_iterator it = allVar.begin(); std::vector::const_iterator itE = allVar.end(); for (; it != itE; ++it) { this->sendAddVariable((*it)->getId()); (*it)->sendAllAttributesToServer(); (*it)->sendValue(); } } } void CField::sendAddVariable(const string& id) { CContext* context = CContext::getCurrent(); if (!context->hasServer) { CContextClient* client = context->client; CEventClient event(this->getType(),EVENT_ID_ADD_VARIABLE); if (client->isServerLeader()) { CMessage msg; msg << this->getId(); msg << id; const std::list& ranks = client->getRanksServerLeader(); for (std::list::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) event.push(*itRank,1,msg); client->sendEvent(event); } else client->sendEvent(event); } } void CField::sendAddVariableGroup(const string& id) { CContext* context = CContext::getCurrent(); if (!context->hasServer) { CContextClient* client = context->client; CEventClient event(this->getType(),EVENT_ID_ADD_VARIABLE_GROUP); if (client->isServerLeader()) { CMessage msg; msg << this->getId(); msg << id; const std::list& ranks = client->getRanksServerLeader(); for (std::list::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank) event.push(*itRank,1,msg); client->sendEvent(event); } else client->sendEvent(event); } } void CField::recvAddVariable(CEventServer& event) { CBufferIn* buffer = event.subEvents.begin()->buffer; string id; *buffer >> id; get(id)->recvAddVariable(*buffer); } void CField::recvAddVariable(CBufferIn& buffer) { string id; buffer >> id; addVariable(id); } void CField::recvAddVariableGroup(CEventServer& event) { CBufferIn* buffer = event.subEvents.begin()->buffer; string id; *buffer >> id; get(id)->recvAddVariableGroup(*buffer); } void CField::recvAddVariableGroup(CBufferIn& buffer) { string id; buffer >> id; addVariableGroup(id); } DEFINE_REF_FUNC(Field,field) // void CField::addReference(CField* field) // { // refObject.push_back(field); // } // // //---------------------------------------------------------------- // // bool CField::hasDirectFieldReference(void) const // { // return !this->field_ref.isEmpty(); // } // // //---------------------------------------------------------------- // // const StdString& CField::getBaseFieldId(void) const // { // return this->getBaseFieldReference()->getId(); // } // // //---------------------------------------------------------------- // // /*! // \brief Get pointer to direct field to which the current field refers. // */ // CField* CField::getDirectFieldReference(void) const // { // if (this->field_ref.isEmpty()) // return this->getBaseFieldReference(); // // if (!CField::has(this->field_ref.getValue())) // ERROR("CField::getDirectFieldReference(void)", // << "[ ref_name = " << this->field_ref.getValue() << "]" // << " invalid field name !"); // // return CField::get(this->field_ref.getValue()); // } // // //---------------------------------------------------------------- // // CField* CField::getBaseFieldReference(void) const // { // return baseRefObject; // } // // //---------------------------------------------------------------- // // const std::vector& CField::getAllReference(void) const // { // return refObject; // } // // /*! // \brief Searching for all reference of a field // If a field refers to (an)other field(s), we will search for all its referenced parents. // Moreover, if any father, direct or indirect (e.g: two levels up), has non-empty attributes, // all its attributes will be added to the current field // \param [in] apply Flag to specify whether current field uses attributes of its father // in case the attribute is empty (true) or its attributes are replaced by ones of its father (false) // */ // void CField::solveRefInheritance(bool apply) // { // std::set sset; // CField* refer_sptr; // CField* refer_ptr = this; // // while (refer_ptr->hasDirectFieldReference()) // { // refer_sptr = refer_ptr->getDirectFieldReference(); // refer_ptr = refer_sptr; // // if(sset.end() != sset.find(refer_ptr)) // { // DEBUG (<< "Circular dependency stopped for field object on " // << "\"" + refer_ptr->getId() + "\" !"); // break; // } // // SuperClassAttribute::setAttributes(refer_ptr, apply); // sset.insert(refer_ptr); // } // } // // /*! // \brief Only on SERVER side. Remove all field_ref from current field // On creating a new field on server side, redundant "field_ref" is still kept in the attribute list // of the current field. This function removes this from current field // */ // void CField::removeRefInheritance() // { // if (this->field_ref.isEmpty()) return; // this->clearAttribute("field_ref"); // } // // void CField::solveBaseReference(void) // { // std::set sset; // CField* refer_sptr; // CField* refer_ptr = this; // // if (this->hasDirectFieldReference()) baseRefObject = getDirectFieldReference(); // else baseRefObject = CField::get(this); // // while (refer_ptr->hasDirectFieldReference()) // { // refer_sptr = refer_ptr->getDirectFieldReference(); // refer_ptr = refer_sptr; // // if(sset.end() != sset.find(refer_ptr)) // { // DEBUG (<< "Circular dependency stopped for field object on " // << "\"" + refer_ptr->getId() + "\" !"); // break; // } // // sset.insert(refer_ptr); // } // // if (hasDirectFieldReference()) baseRefObject->addReference(this); // } } // namespace xios