Systems of the FluxSvc Package
How the SpectrumFactoryTable infrastructure works:
SpectrumFactoryTable:
SpectrumFactoryTable is a singleton object, which is also a map designed to hold connections between names of potential sources and pointers to their associated SpectrumFactories (see below).
SpectrumFactory:
SpectrumFactory is a template class which holds methods to instantiate the classes it represents. It also adds a reference to itself into SpectrumFactoryTable upon its creation, with the line:
SpectrumFactoryTable::instance()->addFactory(classname, this);
this serves to ensure that all created SpectrumFactories are represented in the SpectrumFactoryTable.
At run time:
In each Spectrum-type Object (i.e. HeSpectrum.cxx), lines like these are called:
static SpectrumFactory<HeSpectrum> factory;
const ISpectrumFactory& HeSpectrumFactory = factory;
This properly creates an ISpectrumFactory for each Spectrum Object, to be used for instantiating this class in the future (note that this also means that the SpectrumFactoryTable is filled with references to each Spectrum Object to do the instantiation).
also:
in SpectrumFactoryTable.cxx, the line:SpectrumFactoryTable* SpectrumFactoryTable::s_instance = 0;
forces creation of the SpectrumFactoryTable Object, and then in the constructor:
s_instance=this;
sets the object up as a singleton to be called with SpectrumFactoryTable::instance();
After this process has been done, a Spectrum Object can be instantiated with the line:
SpectrumFactoryTable::instance()->instantiate(name);
Here, A reference to the singleton SpectrumFactoryTable is found from the instance() method, then the instantiate(name) method finds the entry in the internal map corresponding to the desired SpectrumFactory, and uses it's instantiate() method to make the desired Spectrum.
How FluxSvc Makes EventSource:
| FluxSvc | ===> "source" method gets called to create the link to Flux.
| FluxSvc | ---> | Flux | ====> FluxSvc::initialize() is called, FluxMgr is instantiated, Flux is passed a reference to it.
| FluxSvc | ---> | Flux | ---> | FluxMgr | ===> Now FluxMgr::source() creates some kind of EventSource (see next section), which can be addressed from the Flux object.
How Event/Composite/FluxSource works:
As above, FluxMgr::source(name) is responsible for creating an EventSource (or the appropriate object inheriting from EventSource) and returning the pointer. Basically, one of three things happen at this point:
(1): A Spectrum is created with SpectrumFactoryTable::instance()->instantiate(name),then a FluxSource is created with that Spectrum as the internally-held Spectrum.
(2): If the source is defined in the XML, a FluxSource is created which is instantiated from the relevant XML element (this basically is the same process, albeit being handled in FluxSource - the construction is handled differently if the Spectrum is to return the direction, etc.)
(3): If a CompositeSource is needed (read: a "nestedsource" element is found), each contained XML element is used to create a FluxSource as above, then each FluxSource is added into a CompositeSource ( via CompositeSource->addSource(getSourceFromXML(selem)); ), which has been created to hold them all.
From here, we can see how EventSource::rate(time), flux(time), or whatever else can be called and the proper information returned.
EventSource::event():
Once all this linkage is established, we must have a method of calling subsequent particles through the interface. EventSource::event is responsible for calling the "next" particle, and returning a FluxSource(EventSource) corresponding to it. As overridden by FluxSource, this is no more difficult than recalculating everything involved with the particle, and returning a pointer to itself. As overridden by CompositeSource, however, this method sequentially calls the interval() method of each contained FluxSource in order to determine which particle would have "come first", then returns a pointer to that specific object. Thus, subsequent particles are called into existence tis way, and can be addressed thereafter.
How External Spectrum Declaration Works:
An ISpectrum Object can be declared ENTIRELY outside the memory space of
FluxSvc (i.e.) in another package, like so:
class ExternalSpectrum : public ISpectrum{
....
}
Then, in the external code, we can create a RemoteSpectrumFactory object (which works essentially like SpectrumFactory, but uses world-accessible code to insert the new spectrum), and add our new Spectrum to the Service:
static RemoteSpectrumFactory<ExternalSpectrum> testFactory(m_fluxSvc);
where m_fluxSvc is a pointer to the FluxSvc object that the external package has created. NOte that the include files ISPectrum.h and ISpectrumFactory.h from FluxSvc must be included, as the class RemoteSpectrumFactory resides in ISpectrumFactory.h.