Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <iostream>
00016 #include "TClass.h"
00017 #include "TVirtualCollectionProxy.h"
00018 #include "Reflex/Type.h"
00019 #include "Reflex/Member.h"
00020
00021
00022 #include "Fireworks/Core/interface/FWItemAccessorFactory.h"
00023 #include "Fireworks/Core/interface/FWItemAccessorRegistry.h"
00024 #include "Fireworks/Core/src/FWItemTVirtualCollectionProxyAccessor.h"
00025 #include "Fireworks/Core/src/FWItemSingleAccessor.h"
00026 #include "Fireworks/Core/interface/fwLog.h"
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 FWItemAccessorFactory::FWItemAccessorFactory()
00040 {
00041 }
00042
00043
00044
00045
00046
00047
00048 FWItemAccessorFactory::~FWItemAccessorFactory()
00049 {
00050 }
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00094 boost::shared_ptr<FWItemAccessorBase>
00095 FWItemAccessorFactory::accessorFor(const TClass* iClass) const
00096 {
00097 static const bool debug = false;
00098
00099 TClass *member = 0;
00100 size_t offset=0;
00101
00102 if(hasTVirtualCollectionProxy(iClass))
00103 {
00104 if (debug)
00105 fwLog(fwlog::kDebug) << "class " << iClass->GetName()
00106 << " uses FWItemTVirtualCollectionProxyAccessor." << std::endl;
00107 return boost::shared_ptr<FWItemAccessorBase>(
00108 new FWItemTVirtualCollectionProxyAccessor(iClass,
00109 boost::shared_ptr<TVirtualCollectionProxy>(iClass->GetCollectionProxy()->Generate())));
00110 }
00111 else if (hasMemberTVirtualCollectionProxy(iClass, member,offset))
00112 {
00113 if (debug)
00114 fwLog(fwlog::kDebug) << "class "<< iClass->GetName()
00115 << " only contains data member " << member->GetName()
00116 << " which uses FWItemTVirtualCollectionProxyAccessor."
00117 << std::endl;
00118
00119 return boost::shared_ptr<FWItemAccessorBase>(
00120 new FWItemTVirtualCollectionProxyAccessor(iClass,
00121 boost::shared_ptr<TVirtualCollectionProxy>(member->GetCollectionProxy()->Generate()),
00122 offset));
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132 std::string accessorName;
00133 if (hasAccessor(iClass, accessorName))
00134 {
00135 if (debug)
00136 fwLog(fwlog::kDebug) << "class " << iClass->GetName() << " uses "
00137 << accessorName << "." << std::endl;
00138 return boost::shared_ptr<FWItemAccessorBase>(FWItemAccessorRegistry::get()->create(accessorName, iClass));
00139 }
00140
00141 return boost::shared_ptr<FWItemAccessorBase>(new FWItemSingleAccessor(iClass));
00142 }
00143
00147 bool
00148 FWItemAccessorFactory::hasTVirtualCollectionProxy(const TClass *iClass)
00149 {
00150
00151
00152 return iClass &&
00153 iClass->GetCollectionProxy() &&
00154 iClass->GetCollectionProxy()->GetValueClass() &&
00155 iClass->GetCollectionProxy()->GetValueClass()->IsLoaded();
00156 }
00157
00169 bool
00170 FWItemAccessorFactory::hasMemberTVirtualCollectionProxy(const TClass *iClass,
00171 TClass *&oMember,
00172 size_t& oOffset)
00173 {
00174 assert(iClass->GetTypeInfo());
00175 ROOT::Reflex::Type dataType(ROOT::Reflex::Type::ByTypeInfo(*(iClass->GetTypeInfo())));
00176 assert(dataType != ROOT::Reflex::Type());
00177
00178
00179 if (dataType.DataMemberSize() != 1)
00180 return false;
00181
00182 ROOT::Reflex::Type memType(dataType.DataMemberAt(0).TypeOf());
00183 assert(memType != ROOT::Reflex::Type());
00184
00185 memType = memType.FinalType();
00186 oMember = TClass::GetClass(memType.TypeInfo());
00187 oOffset = dataType.DataMemberAt(0).Offset();
00188
00189
00190
00191
00192 if (!hasTVirtualCollectionProxy(oMember))
00193 return false;
00194
00195 return true;
00196 }
00197
00205 bool
00206 FWItemAccessorFactory::hasAccessor(const TClass *iClass, std::string &result)
00207 {
00208 const std::vector<edmplugin::PluginInfo> &available
00209 = FWItemAccessorRegistry::get()->available();
00210
00211 for (size_t i = 0, e = available.size(); i != e; ++i)
00212 {
00213 std::string name = available[i].name_;
00214 std::string type = name.substr(0, name.find_first_of('@'));
00215 if (iClass->GetTypeInfo()->name() == type)
00216 {
00217 result.swap(name);
00218 return true;
00219 }
00220 }
00221 return false;
00222 }
00223
00229 bool FWItemAccessorFactory::classAccessedAsCollection(const TClass* iClass)
00230 {
00231 std::string accessorName;
00232 TClass *member = 0;
00233 size_t offset=0;
00234
00235
00236 return (FWItemAccessorFactory::hasTVirtualCollectionProxy(iClass)
00237 || FWItemAccessorFactory::hasMemberTVirtualCollectionProxy(iClass, member,offset)
00238 || FWItemAccessorFactory::hasAccessor(iClass, accessorName));
00239 }
00240
00241
00242
00243