Xcos MVC: fix some unneeded dependencies
[scilab.git] / scilab / modules / scicos / src / cpp / Model.cpp
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 #include <string>
14 #include <utility>
15 #include <algorithm>
16
17 #include "Model.hxx"
18 #include "utilities.hxx"
19
20 #include "model/BaseObject.hxx"
21 #include "model/Annotation.hxx"
22 #include "model/Diagram.hxx"
23 #include "model/Block.hxx"
24 #include "model/Link.hxx"
25 #include "model/Port.hxx"
26
27 namespace org_scilab_modules_scicos
28 {
29
30 Model::Model() :
31     lastId(0), allObjects(), datatypes()
32 {
33 }
34
35 Model::~Model()
36 {
37 }
38
39 ScicosID Model::createObject(kind_t k)
40 {
41     /*
42      * Allocate the object per kind
43      */
44     model::BaseObject* o;
45     switch (k)
46     {
47         case ANNOTATION:
48             o = new model::Annotation();
49             break;
50         case DIAGRAM:
51             o = new model::Diagram();
52             break;
53         case BLOCK:
54             o = new model::Block();
55             break;
56         case LINK:
57             o = new model::Link();
58             break;
59         case PORT:
60             o = new model::Port();
61             break;
62     }
63
64     /*
65      * Found the next unused id
66      */
67     lastId++;
68     if (lastId == 0)
69     {
70         lastId++;
71     }
72
73     // full map, detection
74     bool has_looped = false;
75
76     objects_map_t::iterator iter = allObjects.lower_bound(lastId);
77     while (iter != allObjects.end() && !(lastId < iter->first)) // while key is found
78     {
79         // try a valid ID
80         lastId++;
81         if (lastId == 0)
82         {
83             lastId++;
84
85             // if the map is full, return 0;
86             if (has_looped)
87             {
88                 delete o;
89                 return 0;
90             }
91             has_looped = true;
92         }
93
94         // look for it
95         iter = allObjects.lower_bound(lastId);
96     }
97
98     /*
99      * Insert then return
100      */
101     allObjects.insert(iter, std::make_pair(lastId, o));
102     o->id(lastId);
103     return lastId;
104 }
105
106 void Model::deleteObject(ScicosID uid)
107 {
108     objects_map_t::iterator iter = allObjects.lower_bound(uid);
109     if (iter == allObjects.end() || uid < iter->first)
110     {
111         throw std::string("key has not been found");
112     }
113
114     allObjects.erase(iter);
115     delete iter->second;
116 }
117
118 model::BaseObject* Model::getObject(ScicosID uid) const
119 {
120     objects_map_t::const_iterator iter = allObjects.lower_bound(uid);
121     if (iter == allObjects.end() || uid < iter->first)
122     {
123         throw std::string("key has not been found");
124     }
125
126     return iter->second;
127 }
128
129 update_status_t Model::setObject(model::BaseObject* o)
130 {
131     objects_map_t::iterator iter = allObjects.lower_bound(o->id());
132     if (iter == allObjects.end() || o->id() < iter->first)
133     {
134         throw std::string("key has not been found");
135     }
136
137     if (*iter->second == *o)
138     {
139         return NO_CHANGES;
140     }
141
142     o->id(iter->second->id());
143     delete iter->second;
144     iter->second = o;
145     return SUCCESS;
146 }
147
148 model::Datatype* Model::flyweight(const model::Datatype& d)
149 {
150     datatypes_set_t::iterator iter = std::lower_bound(datatypes.begin(), datatypes.end(), &d);
151     if (iter != datatypes.end() && !(d < **iter)) // if d is found
152     {
153         (*iter)->refCount++;
154         return *iter;
155     }
156     else
157     {
158         return *datatypes.insert(iter, new model::Datatype(d));
159     }
160 }
161
162 void Model::erase(model::Datatype* d)
163 {
164     datatypes_set_t::iterator iter = std::lower_bound(datatypes.begin(), datatypes.end(), d);
165     if (iter != datatypes.end() && !(*d < **iter)) // if d is found
166     {
167         (*iter)->refCount--;
168         if ((*iter)->refCount < 0)
169         {
170             datatypes.erase(iter);
171             delete *iter;
172         }
173     }
174 }
175
176 } /* namespace org_scilab_modules_scicos */