1 #include "interfaces.h"
3 #include "modules/root.h"
4 #include "modules/colorModel.h"
5 #include "modules/squarePixels.h"
6 #include "modules/quadTree.h"
7 #include "modules/stdDomains.h"
8 #include "modules/quality2SE.h"
9 #include "modules/stdEncoder.h"
10 #include "modules/vliCodec.h"
11 #include "modules/saupePredictor.h"
12 #include "modules/noPredictor.h"
17 #include "FerrisLoki/DataGenerators.h"
21 typedef Loki::TL::MakeTypelist
< MRoot
, MColorModel
, MSquarePixels
, MQuadTree
, MStdDomains
22 , MQuality2SE_std
, MStandardEncoder
, MDifferentialVLICodec
, MSaupePredictor
, NoPredictor
26 const int powers
[31]= { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2*1024 /* 2^11 */
27 , 4*1024, 8*1024, 16*1024, 32*1024, 64*1024, 128*1024, 256*1024, 512*1024 /* 2^19 */
28 , 1024*1024, 2*1024*1024, 4*1024*1024, 8*1024*1024, 16*1024*1024, 32*1024*1024 /* 2^25 */
29 , 64*1024*1024, 128*1024*1024, 256*1024*1024, 512*1024*1024, 1024*1024*1024 }; /* 2^30 */
32 const bool UpdateInfo::noTerminate
;
33 const UpdateInfo
UpdateInfo::none
= UpdateInfo
34 ( UpdateInfo::noTerminate
, &UpdateInfo::emptyFunction
, &UpdateInfo::emptyFunction
);
39 using namespace Loki::TL
;
41 /** Compatible<TypeList,Iface> struct template - leaves in the TypeList only derivates
42 * of Iface class parameter - used by Inteface<Iface>, hidden for others */
43 template <class Typelist
,class Interface
>
46 template <class Iface
>
47 struct Compatible
<NullType
,Iface
> {
48 typedef NullType Result
;
51 template <class Head
,class Tail
,class Iface
>
52 struct Compatible
< Typelist
<Head
,Tail
> , Iface
> {
53 typedef typename Select
54 <SuperSubclass
<Iface
,Head
>::value
55 ,Typelist
< Head
, typename Compatible
<Tail
,Iface
>::Result
>
56 ,typename Compatible
<Tail
,Iface
>::Result
60 template <class T
> struct ExtractId
{
61 int operator()() const
62 { return Loki::TL::IndexOf
<Modules
,T
>::value
; }
65 template<class Iface
> const vector
<int>& Interface
<Iface
>::getCompMods() {
66 using namespace Loki::TL
;
67 typedef typename Compatible
<Modules
,Iface
>::Result CompList
;
68 // if compMods_ vector is empty, create it and fill it
69 if ( compMods_
.empty() && Length
<CompList
>::value
) {
70 compMods_
.reserve(Length
<CompList
>::value
);
71 IterateTypes
<CompList
,ExtractId
> gendata
;
72 gendata( back_inserter(compMods_
) );
76 template <class Iface
> std::vector
<int> Interface
<Iface
>::compMods_
;
79 //// Module class members
80 const Module::SettingTypeItem
Module::SettingTypeItem
81 ::stopper
= { 0, 0, {Stop
,{i
:-1},{text
:0}} };
83 Module::SettingItem
* Module::copySettings(CloneMethod method
) const {
84 ASSERT( method
==DeepCopy
|| method
==ShallowCopy
);
85 // copy the settings array
86 int length
= info().setLength
;
89 SettingItem
*result
= new SettingItem
[length
];
90 copy( settings
, settings
+length
, result
);
92 SettingItem
*item
= result
, *itemEnd
= result
+length
;
94 // make child modules copy themselves (deeply again)
95 while (item
!=itemEnd
) {
97 item
->m
= item
->m
->abstractClone(DeepCopy
);
102 while (item
!=itemEnd
) {
109 void Module::initDefaultModuleLinks() {
110 // iterate over all settings
111 const SettingTypeItem
*setType
= info().setType
;
112 for (int i
=0; setType
[i
].type
.type
!=Stop
; ++i
)
113 if (setType
[i
].type
.type
==ModuleCombo
) {
114 // it is a module link -> initialize it with the right prototype
115 ASSERT(!settings
[i
].m
);
116 settings
[i
].m
= constCast(&ModuleFactory::prototype(
117 (*setType
[i
].type
.data
.compatIDs
)[settings
[i
].val
.i
]
121 void Module::nullModuleLinks() {
122 // iterate over all settings
123 SettingItem
*itEnd
= settings
+info().setLength
;
124 for (SettingItem
*it
=settings
; it
!=itEnd
; ++it
)
127 template<class M
> M
* Module::concreteClone(CloneMethod method
) const {
128 ASSERT( this && info().id
== ModuleFactory::getModuleID
<M
>() );
129 // create a new instance of the same type and fill its settings with a copy of mine
131 result
->settings
= copySettings(method
);
135 void Module::createDefaultSettings() {
137 const TypeInfo
&inf
= info();
138 settings
= new SettingItem
[inf
.setLength
];
139 copy( inf
.setType
, inf
.setType
+inf
.setLength
, settings
);
142 void Module::file_saveModuleType( ostream
&os
, int which
) {
143 // do some assertions - we expect to have the child module, etc.
144 ASSERT( which
>=0 && which
<info().setLength
);
145 SettingItem
&setItem
= settings
[which
];
146 ASSERT( info().setType
[which
].type
.type
==ModuleCombo
&& setItem
.m
);
147 // put the module's identifier
148 put
<Uchar
>( os
, setItem
.m
->info().id
);
150 void Module::file_loadModuleType( istream
&is
, int which
) {
151 // do some assertions - we expect not to have the child module, etc.
152 ASSERT( which
>=0 && which
<info().setLength
);
153 const SettingTypeItem
&setType
= info().setType
[which
];
154 SettingItem
&setItem
= settings
[which
];
155 ASSERT( setType
.type
.type
==ModuleCombo
&& !setItem
.m
);
156 // get module identifier and check its existence
157 int newId
= get
<Uchar
>(is
);
158 checkThrow( 0<=newId
&& newId
<Loki::TL::Length
<Modules
>::value
);
159 // check module compatibility
160 const vector
<int> &v
= *setType
.type
.data
.compatIDs
;
161 settings
[which
].val
.i
= find(v
.begin(),v
.end(),newId
) - v
.begin();
162 checkThrow( settings
[which
].val
.i
< (int)v
.size() );
163 // create a new correct empty module
164 setItem
.m
= ModuleFactory::newModule(newId
,ShallowCopy
);
167 void Module::file_saveAllSettings(std::ostream
&stream
) {
168 int setLength
= info().setLength
;
172 ASSERT( settings
&& setLength
>0 );
174 const SettingTypeItem
*setType
= info().setType
;
175 for (int i
=0; i
<setLength
; ++i
)
176 switch(setType
[i
].type
.type
) {
180 put
<Uint32
>( stream
, settings
[i
].val
.i
);
183 put
<float>( stream
, settings
[i
].val
.f
);
186 file_saveModuleType( stream
, i
);
187 settings
[i
].m
->file_saveAllSettings(stream
);
194 void Module::file_loadAllSettings(std::istream
&stream
) {
195 int setLength
= info().setLength
;
196 ASSERT(setLength
>=0);
200 settings
= new SettingItem
[setLength
];
202 const SettingTypeItem
*setType
= info().setType
;
203 for (int i
=0; i
<setLength
; ++i
)
204 switch(setType
[i
].type
.type
) {
208 settings
[i
].val
.i
= get
<Uint32
>(stream
);
211 settings
[i
].val
.f
= get
<float>(stream
);
214 file_loadModuleType( stream
, i
);
215 settings
[i
].m
->file_loadAllSettings(stream
);
222 //// ModuleFactory class members
223 ModuleFactory
* ModuleFactory::instance
=0;
225 template<class M
> int ModuleFactory::getModuleID()
226 { return Loki::TL::IndexOf
<Modules
,M
>::value
; }
229 void ModuleFactory::initialize() {
230 // create one instance of each module-type
231 ASSERT( prototypes
.empty() );
232 prototypes
.reserve( Loki::TL::Length
<Modules
>::value
);
233 Loki::TL::IterateTypes
<Modules
,Creator
> gendata
;
234 gendata( back_inserter(prototypes
) );
235 // initialize the prototypes' settings and interconnections
236 for_each( prototypes
.begin(), prototypes
.end()
237 , mem_fun(&Module::createDefaultSettings
) );
238 for_each( prototypes
.begin(), prototypes
.end()
239 , mem_fun(&Module::initDefaultModuleLinks
) );
241 void ModuleFactory::changeDefaultSettings(const Module
&module
) {
242 // get the right prototype
243 const Module::TypeInfo
&mi
= module
.info();
244 Module::SettingItem
*protSet
= prototype(mi
.id
).settings
;
245 // replace prototype's settings
246 ASSERT( protSet
&& module
.settings
);
247 copy( module
.settings
, module
.settings
+mi
.setLength
, protSet
);
248 // convert module-links to links to the correct prototypes
249 for (const Module::SettingTypeItem
*setType
= mi
.setType
250 ; setType
->type
.type
!=Module::Stop
; ++setType
,++protSet
)
251 if ( setType
->type
.type
==Module::ModuleCombo
) {
253 protSet
->m
= constCast(&prototype( protSet
->m
->info().id
));
258 template<class T
> int ModuleFactory::Instantiator
<T
>::operator()() const {
259 int i
= getModuleID
<T
>();
260 Module
*m
= T::newCompatibleModule();
261 m
= m
->concreteClone
<T
>(Module::DeepCopy
);
262 i
+= T::getCompMods().front();
265 void ModuleFactory::instantiateModules() {
266 IterateTypes
<Modules
,Instantiator
> gendata
;
268 gendata(back_inserter(v
));