// $Header: /cvs/gled-1.2/GledCore/Stones/ZComet.cxx,v 1.6 2005/03/11 17:50:16 matevz Exp $
// Copyright (C) 1999-2005, Matevz Tadel. All rights reserved.
// This file is part of GLED, released under GNU General Public License version 2.
// For the licensing terms see $GLEDSYS/LICENSE or http://www.gnu.org/.
//
// ZComet
//
// ZComet is a container class for streaming collections of glasses.
// It can be created from a ZCometBag, ZQueen or ZKing by calling the
// appropriate MakeComet() method.
// Service is rather elementary ... external references are only
// meaningfull if Saturn layout used for writing/reading is identical.
// A special class will be provided to make proper references into
// static objects.
// Comets of type CT_Queen & CT_King are used internally for exportation
// to connecting Moons.
//
// !!!!!! Need structure { ZGlass* g; bool links_done, lists_done; }
// as value type of idHash. Loops of infiniteness are awaiting you otherwise.
// Then, also, need no special treatment of ZNode::Parent. Or just maybe.
#include "ZComet.h"
#include <Gled/GledNS.h>
#include <Glasses/ZList.h>
#include <Glasses/ZKing.h>
#include <Glasses/ZQueen.h>
#include <Ephra/Saturn.h>
#include <Gled/Gled.h>
#include <TBuffer.h>
#include <TDirectory.h>
#include <TFile.h>
ClassImp(ZComet)
/**************************************************************************/
void ZComet::_init()
{
mType = CT_CometBag;
mExtDemangler = 0;
bWarnOn = false; bVerbose = false;
mQueen = 0; mKing = 0;
}
/**************************************************************************/
Int_t ZComet::AddTopLevel(ZGlass* g, Bool_t do_links, Bool_t do_lists, Int_t depth)
{
// !! should check if already in? not my problem ...
mTopLevels.push_back(g);
return AddGlass(g, do_links, do_lists, depth);
}
Int_t ZComet::AddGlass(ZGlass* g, Bool_t do_links, Bool_t do_lists, Int_t depth)
{
// Adds a glass (et al) into local structure
// depth controls traversal length
// depth of 0 means add ONLY g, not even its links or lists.
// depth of -1 means don't stop
Int_t num_new = 0;
ID_t id = g->GetSaturnID();
if(mIDMap.find(id) == mIDMap.end()) {
++num_new;
mIDMap[id] = g;
mLibSets.insert(g->VFID().lid);
ISdebug(D_STREAM, GForm("ZComet::AddGlass added lens %s, id=%u",
g->GetName(), id));
}
if(depth==0) return num_new;
if(do_links) {
ZGlass::lLinkRep_t lreps; g->CopyLinkReps(lreps);
for(ZGlass::lLinkRep_i i = lreps.begin(); i != lreps.end(); ++i) {
ZGlass* l = i->fLinkRef;
if(l != 0 && mIgnoredLinks.find(i->fLinkInfo->FullName())==mIgnoredLinks.end()) {
num_new += AddGlass(l, do_links, do_lists, depth-1);
}
}
}
ZList* l = dynamic_cast<ZList*>(g);
if(l && do_lists) {
lpZGlass_t members; l->Copy(members);
for(lpZGlass_i i=members.begin(); i!=members.end(); ++i) {
num_new += AddGlass(*i, do_links, do_lists, depth-1);
}
}
return num_new;
}
/**************************************************************************/
ZGlass* ZComet::DemangleID(ID_t id)
{
static const string _eh("ZComet::DemangleID ");
if(id == 0) return 0;
mID2pZGlass_i i;
if((i = mIDMap.find(id)) != mIDMap.end())
return i->second;
if(mExtDemangler != 0) {
ZGlass* l = mExtDemangler->DemangleID(id);
if(l == 0 && bVerbose)
ISmess(_eh + GForm("id %u not found (comet, ext-demangler).", id));
return l;
} else {
if(bVerbose)
ISmess(_eh + GForm("id %u not found (comet).", id));
return 0;
}
}
/**************************************************************************/
void ZComet::AssignQueen(ZQueen* queen)
{
// Sets the ZGlass::mQueen pointer to queen for all elements of the comet.
// This should be called prior to RebuildGraph if it is desired that
// reference counts are properly increased.
for(mID2pZGlass_i i=mIDMap.begin(); i!=mIDMap.end(); i++) {
i->second->mQueen = queen;
}
}
Int_t ZComet::RebuildGraph()
{
static const string _eh("ZComet::RebuildGraph ");
if(bGraphRebuilt) return 0;
Int_t ret = 0;
// First pass: rebuild and count missed links & list members
for(mID2pZGlass_i i=mIDMap.begin(); i!=mIDMap.end(); i++) {
ZGlass* g = i->second;
if(Int_t m = g->RebuildLinkRefs(this)) {
ret += m;
if(bWarnOn)
ISwarn(_eh + GForm("(links) %d missed lens(es) in '%s'.",
m, g->GetName()));
}
ZList* l = dynamic_cast<ZList*>(g);
if(l) {
Int_t m = l->RebuildListRefs(this);
if(m>0) {
ret += m;
if(bWarnOn)
ISwarn(_eh + GForm("(list) %d missed lens(es) in '%s'.",
m, g->GetName()));
}
}
}
// Second pass: grep NotRefed Glasses that are NOT toplevel
// !!!! hmmph ... should copy map, and remove connected ones.
for(mID2pZGlass_i i=mIDMap.begin(); i!=mIDMap.end(); ++i) {
ZGlass* g = i->second;
if(g->GetRefCount()==0) {
if(find(mTopLevels.begin(), mTopLevels.end(), g) == mTopLevels.end()) {
ISdebug(D_STREAM, _eh + GForm("'%s' is an orphan.", g->GetName()));
mOrphans.push_back(g);
}
}
}
bGraphRebuilt = true;
return ret;
}
/**************************************************************************/
/**************************************************************************/
// Streamer functions
/**************************************************************************/
/**************************************************************************/
void ZComet::Streamer(TBuffer& b)
{
static const string _eh("ZComet::Streamer ");
StreamHeader(b);
StreamContents(b);
if(b.IsReading()) {
// Rebuild kings/queens
if(mType == CT_Queen) {
mQueen = dynamic_cast<ZQueen*>(DemangleID((ID_t)mQueen));
if(mQueen==0) {
ISerr(_eh + GForm("(Queen) couldn't demangle QueenID %u.",
(ID_t)(mQueen)));
}
}
if(mType == CT_King) {
mKing = dynamic_cast<ZKing*>(DemangleID((ID_t)mKing));
if(mKing==0) {
ISerr(_eh + GForm("(King) couldn't demangle KingID %u.", (ID_t)mKing));
}
}
// Reconstruct TopLevels
for(lpZGlass_i i=mTopLevels.begin(); i!=mTopLevels.end(); ++i) {
mID2pZGlass_i j = mIDMap.find((ID_t)(*i));
if(j != mIDMap.end()) {
*i = j->second;
} else {
if(bWarnOn)
ISwarn(_eh + GForm("(top_levels) missing ID %u.", (ID_t)(*i)));
}
}
}
}
void ZComet::StreamHeader(TBuffer& b)
{
// Streams Type, Size, Libsets, TopLevels|Queen|King
static const string _eh("ZComet::StreamHeader ");
if(b.IsReading()) {
/*** Reading ***/
bGraphRebuilt = false;
mLibSets.clear(); mTopLevels.clear(); mOrphans.clear();
UInt_t t; b >> t; mType = CometType_e(t);
UInt_t cnt; b >> cnt;
bFail = false;
for(UInt_t i=0; i<cnt; i++) {
LID_t lid; b >> lid;
mLibSets.insert(lid);
if(!GledNS::IsLoaded(lid)) {
ISmess(_eh + GForm("attempting to load LibSet w/ id=%u.", lid));
int ret = Gled::theOne->LoadLibSet(lid);
if(ret != 0) {
ISerr(_eh + GForm("failed to load LibSet w/ id=%u.", lid));
bFail = true;
}
}
}
if(bFail) throw(string("LibSets missing."));
switch(mType) {
case CT_CometBag:
b >> cnt;
for(UInt_t i=0; i<cnt; i++) {
ID_t id; b >> id;
mTopLevels.push_back((ZGlass*)id);
}
break;
case CT_Queen: b >> mQueen; break;
case CT_King: b >> mKing; break;
}
} else {
/*** Writing ***/
b << (UInt_t) mType;
b << (UInt_t) mLibSets.size();
for(set<LID_t>::iterator i=mLibSets.begin(); i!=mLibSets.end(); ++i)
b << *i;
switch(mType) {
case CT_CometBag:
b << (UInt_t) mTopLevels.size();
for(lpZGlass_i i=mTopLevels.begin(); i!=mTopLevels.end(); ++i)
b << (*i)->GetSaturnID();
break;
case CT_Queen: b << mQueen; break;
case CT_King: b << mKing; break;
}
}
}
void ZComet::StreamContents(TBuffer& b)
{
static const string _eh("ZComet::StreamContents ");
if(b.IsReading()) {
UInt_t size;
b >> size;
ISdebug(D_STREAM, _eh + GForm("reading %u glasses.", size));
for(UInt_t i=0; i<size; ++i) {
ZGlass *g = GledNS::StreamLens(b);
if(g) {
ID_t id = g->GetSaturnID();
mIDMap[id] = g;
ISdebug(D_STREAM+1, _eh + GForm("read lens %s[%s] addr=%p.",
g->GetName(), g->ClassName(), (void*)g));
} else {
ISdebug(D_STREAM, _eh + "lens creation failed.");
}
}
} else {
UInt_t size = (UInt_t)(mIDMap.size());
b << size;
ISdebug(D_STREAM, _eh + GForm("writing %u glasses.", size));
if(size > 0) {
for(mID2pZGlass_i i=mIDMap.begin(); i!=mIDMap.end(); i++) {
ISdebug(D_STREAM+1, _eh + GForm("writing %s", (i->second)->GetName()));
GledNS::StreamLens(b, i->second);
}
}
}
}
/**************************************************************************/
ROOT page - Home page - Class index - Class Hierarchy - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.