Xcos MVC: handle graphics and model port creation
[scilab.git] / scilab / modules / scicos / src / cpp / view_scilab / BaseAdapter.hxx
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2014-2014 - Scilab Enterprises - Clement DAVID
4  *
5  *  This file must be used under the terms of the CeCILL.
6  *  This source file is licensed as described in the file COPYING, which
7  *  you should have received as part of this distribution.  The terms
8  *  are also available at
9  *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 #ifndef BASEADAPTER_HXX_
14 #define BASEADAPTER_HXX_
15
16 #include <algorithm>
17 #include <string>
18 #include <utility>
19 #include <iostream>
20
21 #include "user.hxx"
22
23 #include "Controller.hxx"
24 #include "Adapters.hxx"
25 #include "model/BaseObject.hxx"
26
27 namespace org_scilab_modules_scicos
28 {
29 namespace view_scilab
30 {
31
32 /**
33  * A property used as a getter/setter for a specific name
34  */
35 template<typename Adaptor>
36 struct property
37 {
38 public:
39     typedef types::InternalType* (*getter_t)(const Adaptor& adaptor, const Controller& controller);
40     typedef bool (*setter_t)(Adaptor& adaptor, types::InternalType* v, Controller& controller);
41
42     typedef std::vector< property<Adaptor> > props_t;
43     typedef typename props_t::iterator props_t_it;
44
45
46     property(const std::wstring& prop, getter_t g, setter_t s) : name(prop), get(g), set(s) {};
47     ~property() {};
48
49     std::wstring name;
50     getter_t get;
51     setter_t set;
52
53     bool operator< (const std::wstring& v) const
54     {
55         return name < v;
56     }
57
58     /*
59      * Static properties accessors
60      */
61     static props_t fields;
62
63     /**
64      * @return true if the properties has already been setup, false otherwise.
65      */
66     static bool properties_has_not_been_set()
67     {
68         return fields.empty();
69     }
70
71     /**
72      * Add a property to an Adaptor
73      */
74     static void add_property(const std::wstring& name, getter_t g, setter_t s)
75     {
76         property<Adaptor>::props_t_it pos = std::lower_bound(fields.begin(), fields.end(), name);
77         fields.insert(pos, property(name, g, s));
78     }
79 };
80
81
82 /**
83  * Base definition of the adapter pattern, implement the get / set dispatch.
84  *
85  * Note that sub-classes are responsible to fill the fields accordingly to theirs interfaces.
86  */
87 template<typename Adaptor, typename Adaptee>
88 class BaseAdapter : public types::User<Adaptor>
89 {
90
91 public:
92     BaseAdapter(Adaptee* o) : adaptee(o) {};
93     BaseAdapter(const BaseAdapter& o) : adaptee(o.adaptee) {};
94     virtual ~BaseAdapter() {};
95
96     /*
97      * property accessors
98      */
99
100     bool hasProperty(const std::wstring& _sKey) const
101     {
102         typename property<Adaptor>::props_t_it found = std::binary_search(property<Adaptor>::fields.begin(), property<Adaptor>::fields.end(), _sKey);
103         return found != property<Adaptor>::fields.end();
104     }
105
106     types::InternalType* getProperty(const std::wstring& _sKey, Controller controller = Controller()) const
107     {
108         typename property<Adaptor>::props_t_it found = std::lower_bound(property<Adaptor>::fields.begin(), property<Adaptor>::fields.end(), _sKey);
109         if (found != property<Adaptor>::fields.end())
110         {
111             return found->get(static_cast<Adaptor*>(this), controller);
112         }
113         return 0;
114     }
115
116     bool setProperty(const std::wstring& _sKey, types::InternalType* v, Controller controller = Controller())
117     {
118         typename property<Adaptor>::props_t_it found = std::lower_bound(property<Adaptor>::fields.begin(), property<Adaptor>::fields.end(), _sKey);
119         if (found != property<Adaptor>::fields.end())
120         {
121             return found->set(*static_cast<Adaptor*>(this), v, controller);
122         }
123         return false;
124     }
125
126     /**
127      * @return the Adaptee instance
128      */
129     Adaptee* getAdaptee() const
130     {
131         return adaptee;
132     };
133
134     /**
135      * set the adaptee
136      */
137     void setAdaptee(Adaptee* adaptee)
138     {
139         this->adaptee = adaptee;
140     }
141
142     /*
143      * All following methods should be implemented by each template instance
144      */
145
146     virtual bool toString(std::wostringstream& ostr) = 0;
147     virtual std::wstring getTypeStr() = 0;
148     virtual std::wstring getShortTypeStr() = 0;
149
150 private:
151     Adaptee* adaptee;
152 };
153
154
155 } /* view_scilab */
156 } /* namespace org_scilab_modules_scicos */
157
158 #endif /* BASEADAPTER_HXX_ */