]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/io/server/src/vbus_factory.h
79e1943efdb539a5e3b2eff8bb0333bf07f5d947
[l4.git] / l4 / pkg / io / server / src / vbus_factory.h
1 /*
2  * (c) 2010 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
3  *          Alexander Warg <warg@os.inf.tu-dresden.de>
4  *     economic rights: Technische Universität Dresden (Germany)
5  *
6  * This file is part of TUD:OS and distributed under the terms of the
7  * GNU General Public License 2.
8  * Please see the COPYING-GPL-2 file for details.
9  */
10 #pragma once
11
12 #include "main.h"
13
14 #include <l4/cxx/avl_map>
15 #include <string>
16 #include <cstdio>
17 #include <typeinfo>
18
19 #include "hw_device.h"
20 #include "vdevice.h"
21
22 namespace Vi {
23
24 template< typename VI, typename HW >
25 class Generic_type_factory
26 {
27 public:
28   virtual VI *vcreate(HW *f) = 0;
29   virtual ~Generic_type_factory() {}
30
31   typedef cxx::Avl_map<std::type_info const *, Generic_type_factory *> Type_map;
32
33 protected:
34   static Type_map &type_map()
35   {
36     static Type_map _tm;
37     return _tm;
38   }
39
40 public:
41   static VI *create(HW *f);
42 };
43
44 typedef Generic_type_factory<Dev_feature, Hw::Dev_feature> Feature_factory;
45
46 class Dev_factory
47 : public Generic_type_factory<Device, Hw::Device>
48 {
49 public:
50   virtual Device *vcreate() = 0;
51
52   typedef cxx::Avl_map<std::string, Dev_factory *> Name_map;
53
54 protected:
55   static Name_map &name_map()
56   {
57     static Name_map _name_map;
58     return _name_map;
59   }
60
61 public:
62   using Generic_type_factory<Device, Hw::Device>::create;
63   static Device *create(std::string const &_class);
64 };
65
66
67 template< typename VI,  typename HW_BASE, typename HW, typename BASE >
68 class Generic_factory_t : public BASE
69 {
70 public:
71   Generic_factory_t()
72   { BASE::type_map()[&typeid(HW)] = this; }
73
74
75   VI *vcreate(HW_BASE *dev)
76   {
77 #if 0
78     if (dev->ref_count())
79       printf("WARNING: device '%s' already assigned to an other virtual bus.\n",
80              dev->name());
81 #endif
82
83     VI *d = 0;
84     if (HW* h = dynamic_cast<HW*>(dev))
85       d = new VI(h);
86 //    dev->inc_ref_count();
87     return d;
88   }
89
90   VI *vcreate()
91   { return 0; }
92
93 };
94
95 template< typename VI, typename HW >
96 class Feature_factory_t
97 : public Generic_factory_t<VI, Hw::Dev_feature, HW, Feature_factory >
98 {};
99
100 template< typename V_DEV, typename HW_DEV = void >
101 class Dev_factory_t :  public Dev_factory
102 {
103 public:
104   typedef HW_DEV Hw_dev;
105   typedef V_DEV  V_dev;
106
107   Dev_factory_t()
108   {
109     type_map()[&typeid(Hw_dev)] = this;
110   }
111
112
113   virtual Device *vcreate(Hw::Device *dev)
114   {
115     if (dev->ref_count())
116       printf("WARNING: device '%s' already assigned to an other virtual bus.\n",
117              dev->name());
118
119     Device *d = new V_dev(static_cast<Hw_dev*>(dev));
120     dev->inc_ref_count();
121     return d;
122   }
123
124   virtual Device *vcreate()
125   { return 0; }
126
127 };
128
129 template< typename V_DEV >
130 class Dev_factory_t<V_DEV, void> :  public Dev_factory
131 {
132 public:
133   typedef void  Hw_dev;
134   typedef V_DEV V_dev;
135
136   explicit Dev_factory_t(std::string const &_class)
137   {
138     name_map()[_class] = this;
139   }
140
141
142   virtual Device *vcreate(Hw::Device *)
143   { return 0; }
144
145   virtual Device *vcreate()
146   {
147     Device *d = new V_dev();
148     return d;
149   }
150
151 };
152
153
154 template< typename VI, typename HW >
155 VI *
156 Generic_type_factory<VI, HW>::create(HW *f)
157 {
158   if (!f)
159     return 0;
160
161   Type_map &tm = type_map();
162   typename Type_map::const_iterator i = tm.find(&typeid(*f));
163   if (i == tm.end())
164     {
165       printf("WARNING: cannot fabricate buddy object for '%s'\n",
166              typeid(*f).name());
167       return 0;
168     }
169
170     return i->second->vcreate(f);
171 }
172
173 }
174