]> git.tdb.fi Git - r2c2.git/blob - source/shoppinglist/main.cpp
Major code refactoring:
[r2c2.git] / source / shoppinglist / main.cpp
1 #include <iostream>
2 #include <map>
3 #include <msp/core/getopt.h>
4 #include <msp/datafile/loader.h>
5 #include <msp/datafile/parser.h>
6
7 using namespace std;
8 using namespace Msp;
9
10 class ShoppingList
11 {
12 public:
13         ShoppingList(int, char **);
14         void print(ostream &);
15 private:
16         class InventoryLoader: public DataFile::Loader
17         {
18         public:
19                 InventoryLoader(ShoppingList &);
20         private:
21                 ShoppingList &sl;
22
23                 void track(unsigned, unsigned);
24         };
25
26         class LayoutLoader: public DataFile::Loader
27         {
28         public:
29                 LayoutLoader(ShoppingList &);
30         private:
31                 ShoppingList &sl;
32
33                 void track(unsigned);
34         };
35
36         typedef map<unsigned, unsigned> TrackMap;
37
38         TrackMap inventory;
39         TrackMap layout;
40
41         void load_inventory(const string &);
42         void load_layout(const string &);
43 };
44
45 int main(int argc, char **argv)
46 {
47         ShoppingList sl(argc, argv);
48         sl.print(cout);
49         return 0;
50 }
51
52 ShoppingList::ShoppingList(int argc, char **argv)
53 {
54         string inv_fn="inventory";
55         GetOpt getopt;
56         getopt.add_option('i', "inventory", inv_fn, GetOpt::REQUIRED_ARG);
57         getopt(argc,argv);
58
59         load_inventory(inv_fn);
60         load_layout(getopt.get_args().front());
61 }
62
63 void ShoppingList::load_inventory(const string &fn)
64 {
65         IO::File in(fn);
66         DataFile::Parser parser(in, fn);
67         InventoryLoader il(*this);
68         il.load(parser);
69 }
70
71 void ShoppingList::load_layout(const string &fn)
72 {
73         IO::File in(fn);
74         DataFile::Parser parser(in, fn);
75         LayoutLoader ll(*this);
76         ll.load(parser);
77 }
78
79 void ShoppingList::print(ostream &out)
80 {
81         out<<"// Need to get:\n";
82         for(TrackMap::iterator i=layout.begin(); i!=layout.end(); ++i)
83         {
84                 TrackMap::iterator j=inventory.find(i->first);
85                 if(j!=inventory.end())
86                 {
87                         if(j->second<i->second)
88                                 out<<"track "<<i->first<<' '<<i->second-j->second<<";\n";
89                 }
90                 else
91                         out<<"track "<<i->first<<' '<<i->second<<";\n";
92         }
93
94         out<<"// Pre-existing:\n";
95         for(TrackMap::iterator i=layout.begin(); i!=layout.end(); ++i)
96         {
97                 TrackMap::iterator j=inventory.find(i->first);
98                 if(j!=inventory.end())
99                         out<<"track "<<i->first<<' '<<min(i->second,j->second)<<";\n";
100         }
101
102         out<<"// Unused:\n";
103         for(TrackMap::iterator i=inventory.begin(); i!=inventory.end(); ++i)
104         {
105                 TrackMap::iterator j=layout.find(i->first);
106                 if(j!=layout.end())
107                 {
108                         if(j->second<i->second)
109                                 out<<"track "<<i->first<<' '<<i->second-j->second<<";\n";
110                 }
111                 else
112                         out<<"track "<<i->first<<' '<<i->second<<";\n";
113         }
114 }
115
116 ShoppingList::InventoryLoader::InventoryLoader(ShoppingList &s):
117         sl(s)
118 {
119         add("track", &InventoryLoader::track);
120 }
121
122 void ShoppingList::InventoryLoader::track(unsigned part, unsigned count)
123 {
124         sl.inventory[part]+=count;
125 }
126
127 ShoppingList::LayoutLoader::LayoutLoader(ShoppingList &s):
128         sl(s)
129 {
130         add("track", &LayoutLoader::track);
131         add("base");
132 }
133
134 void ShoppingList::LayoutLoader::track(unsigned part)
135 {
136         ++sl.layout[part];
137 }