Writing: fixed collage theorem talk.
[fic.git] / modules.cpp
blobeb564898765cb93788219b1d02038d774d786f61
1 #include "modules/root.h"
2 #include "modules/colorModel.h"
3 #include "modules/squarePixels.h"
4 #include "modules/quadTree.h"
5 #include "modules/stdDomains.h"
6 #include "modules/quality2SE.h"
7 #include "modules/stdEncoder.h"
8 #include "modules/vliCodec.h"
9 #include "modules/saupePredictor.h"
10 #include "modules/noPredictor.h"
12 #include "util.h"
13 #include "fileUtil.h"
15 #include "FerrisLoki/DataGenerators.h"
17 using namespace std;
19 typedef Loki::TL::MakeTypelist< MRoot, MColorModel, MSquarePixels, MQuadTree, MStdDomains
20 , MQuality2SE_std, MStandardEncoder, MDifferentialVLICodec, MSaupePredictor, NoPredictor >
21 ::Result Modules;
23 const int powers[31]= { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2*1024 /* 2^11 */
24 , 4*1024, 8*1024, 16*1024, 32*1024, 64*1024, 128*1024, 256*1024, 512*1024 /* 2^19 */
25 , 1024*1024, 2*1024*1024, 4*1024*1024, 8*1024*1024, 16*1024*1024, 32*1024*1024 /* 2^25 */
26 , 64*1024*1024, 128*1024*1024, 256*1024*1024, 512*1024*1024, 1024*1024*1024 }; /* 2^30 */
28 const bool UpdateInfo::noTerminate;
30 //// Compatible<TypeList,Iface> struct template - leaves in the TypeList only derivates
31 //// of Iface class parameter - used by Inteface<Iface>, hidden for others
32 namespace NOSPACE {
33 using namespace Loki;
34 using namespace Loki::TL;
36 template <class Typelist,class Interface>
37 struct Compatible;
39 template <class Iface>
40 struct Compatible<NullType,Iface> {
41 typedef NullType Result;
44 template <class Head,class Tail,class Iface>
45 struct Compatible< Typelist<Head,Tail> , Iface > {
46 typedef typename Select
47 <SuperSubclass<Iface,Head>::value
48 ,Typelist< Head , typename Compatible<Tail,Iface>::Result >
49 ,typename Compatible<Tail,Iface>::Result
50 >::Result Result;
53 template <class T> struct ExtractId {
54 int operator()() const
55 { return Loki::TL::IndexOf<Modules,T>::value; }
58 template<class Iface> const vector<int>& Interface<Iface>::getCompMods() {
59 using namespace Loki::TL;
60 typedef typename Compatible<Modules,Iface>::Result CompList;
61 if ( compMods_.empty() && Length<CompList>::value ) {
62 compMods_.reserve(Length<CompList>::value);
63 IterateTypes<CompList,ExtractId> gendata;
64 gendata( back_inserter(compMods_) );
66 return compMods_;
68 template <class Iface> std::vector<int> Interface<Iface>::compMods_;
71 //// Module class members
72 const Module::SettingsTypeItem Module::SettingsTypeItem
73 ::stopper= { 0, 0, {Stop,{i:-1},{text:0}} };
75 Module::SettingsItem* Module::copySettings(CloneMethod method) const {
76 assert( method==DeepCopy || method==ShallowCopy );
77 // copy the settings array
78 int length= info().setLength;
79 if (!length)
80 return 0;
81 SettingsItem *result= new SettingsItem[length];
82 copy( settings, settings+length, result );
84 SettingsItem *item= result, *itemEnd= result+length;
85 if (method==DeepCopy)
86 // make child modules copy themselves (deeply again)
87 while (item!=itemEnd) {
88 if (item->m)
89 item->m= clone(item->m);
90 ++item;
92 else // ShallowCopy
93 // null module links
94 while (item!=itemEnd) {
95 item->m= 0;
96 ++item;
99 return result;
101 void Module::initDefaultModuleLinks() {
102 // iterate over all settings
103 const SettingsTypeItem *setType= info().setType;
104 for (int i=0; setType[i].type.type!=Stop; ++i )
105 if (setType[i].type.type==ModuleCombo) {
106 // it is a module link -> initialize it with the right prototype
107 assert(!settings[i].m);
108 settings[i].m= constCast(&ModuleFactory::prototype(
109 (*setType[i].type.data.compatIDs)[settings[i].val.i]
113 void Module::nullModuleLinks() {
114 // iterate over all settings
115 SettingsItem *itEnd= settings+info().setLength;
116 for (SettingsItem *it=settings; it!=itEnd; ++it)
117 it->m= 0;
119 template<class M> M* Module::concreteClone(CloneMethod method) const {
120 assert( this && info().id == ModuleFactory::getModuleID<M>() );
121 // create a new instance of the same type and fill its settings with a copy of mine
122 M *result= new M;
123 result->settings= copySettings(method);
124 return result;
127 void Module::createDefaultSettings() {
128 assert(!settings);
129 const TypeInfo &inf= info();
130 settings= new SettingsItem[inf.setLength];
131 copy( inf.setType, inf.setType+inf.setLength, settings );
134 void Module::file_saveModuleType( ostream &os, int which ) {
135 // do some assertions - we expect to have the child module, etc.
136 assert( which>=0 && which<info().setLength );
137 SettingsItem &setItem= settings[which];
138 assert( info().setType[which].type.type==ModuleCombo && setItem.m );
139 // put the module's identifier
140 put<Uchar>( os, setItem.m->info().id );
142 void Module::file_loadModuleType( istream &is, int which ) {
143 // do some assertions - we expect not to have the child module, etc.
144 assert( which>=0 && which<info().setLength );
145 const SettingsTypeItem &setType= info().setType[which];
146 SettingsItem &setItem= settings[which];
147 assert( setType.type.type==ModuleCombo && !setItem.m );
148 // get module identifier and check its existence
149 int newId= get<Uchar>(is);
150 checkThrow( 0<=newId && newId<Loki::TL::Length<Modules>::value );
151 // check module compatibility
152 const vector<int> &v= *setType.type.data.compatIDs;
153 settings[which].val.i= find(v.begin(),v.end(),newId) - v.begin();
154 checkThrow( settings[which].val.i < (int)v.size() );
155 // create a new correct empty module
156 setItem.m= ModuleFactory::newModule(newId,ShallowCopy);
159 void Module::saveAllSettings(std::ostream &stream) {
160 int setLength= info().setLength;
161 if (!setLength)
162 return;
163 else
164 assert( settings && setLength>0 );
166 const SettingsTypeItem *setType= info().setType;
167 for (int i=0; i<setLength; ++i)
168 switch(setType[i].type.type) {
169 case Int:
170 case IntLog2:
171 case Combo:
172 put<Uint32>( stream, settings[i].val.i );
173 break;
174 case Float:
175 put<float>( stream, settings[i].val.f );
176 break;
177 case ModuleCombo:
178 file_saveModuleType( stream, i );
179 settings[i].m->saveAllSettings(stream);
180 break;
181 default:
182 assert(false);
183 } // switch
186 void Module::loadAllSettings(std::istream &stream) {
187 int setLength= info().setLength;
188 assert(setLength>=0);
189 if (!setLength)
190 return;
191 if (!settings)
192 settings= new SettingsItem[setLength];
194 const SettingsTypeItem *setType= info().setType;
195 for (int i=0; i<setLength; ++i)
196 switch(setType[i].type.type) {
197 case Int:
198 case IntLog2:
199 case Combo:
200 settings[i].val.i= get<Uint32>(stream);
201 break;
202 case Float:
203 settings[i].val.f= get<float>(stream);
204 break;
205 case ModuleCombo:
206 file_loadModuleType( stream, i );
207 settings[i].m->loadAllSettings(stream);
208 break;
209 default:
210 assert(false);
211 } // switch
214 //// ModuleFactory class members
215 ModuleFactory* ModuleFactory::instance=0;
217 template<class M> int ModuleFactory::getModuleID()
218 { return Loki::TL::IndexOf<Modules,M>::value; }
220 void ModuleFactory::initialize() {
221 // create one instance of each module-type
222 assert( prototypes.empty() );
223 prototypes.reserve( Loki::TL::Length<Modules>::value );
224 Loki::TL::IterateTypes<Modules,Creator> gendata;
225 gendata( back_inserter(prototypes) );
226 // initialize the prototypes' settings and interconnections
227 for_each( prototypes.begin(), prototypes.end()
228 , mem_fun(&Module::createDefaultSettings) );
229 for_each( prototypes.begin(), prototypes.end()
230 , mem_fun(&Module::initDefaultModuleLinks) );
232 void ModuleFactory::changeDefaultSettings(const Module &module) {
233 // get the right prototype
234 const Module::TypeInfo &mi= module.info();
235 Module::SettingsItem *protSet= prototype(mi.id).settings;
236 // replace prototype's settings
237 assert( protSet && module.settings );
238 copy( module.settings, module.settings+mi.setLength, protSet );
239 // convert module-links to links to the correct prototypes
240 for (const Module::SettingsTypeItem *setType= mi.setType
241 ; setType->type.type!=Module::Stop; ++setType,++protSet)
242 if ( setType->type.type==Module::ModuleCombo ) {
243 assert(protSet->m);
244 protSet->m= constCast(&prototype( protSet->m->info().id ));
249 template<class T> int ModuleFactory::Instantiator<T>::operator()() const {
250 T::newCompatibleModule();
251 getModuleID<T>();
252 ((T*)(0))->T::abstractClone();
253 T::getCompMods().size();
254 return 0;
256 void ModuleFactory::instantiateModules() {
257 IterateTypes<Modules,Instantiator> gendata;
258 vector<int> v;
259 gendata(back_inserter(v));