1 | |
2 | // |
3 | // This source file is part of appleseed. |
4 | // Visit http://appleseedhq.net/ for additional information and resources. |
5 | // |
6 | // This software is released under the MIT license. |
7 | // |
8 | // Copyright (c) 2012-2013 Esteban Tovagliari, Jupiter Jazz Limited |
9 | // Copyright (c) 2014-2017 Esteban Tovagliari, The appleseedhq Organization |
10 | // |
11 | // Permission is hereby granted, free of charge, to any person obtaining a copy |
12 | // of this software and associated documentation files (the "Software"), to deal |
13 | // in the Software without restriction, including without limitation the rights |
14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
15 | // copies of the Software, and to permit persons to whom the Software is |
16 | // furnished to do so, subject to the following conditions: |
17 | // |
18 | // The above copyright notice and this permission notice shall be included in |
19 | // all copies or substantial portions of the Software. |
20 | // |
21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
27 | // THE SOFTWARE. |
28 | // |
29 | |
30 | #ifndef APPLESEED_PYTHON_BINDENTITYCONTAINERS_H |
31 | #define APPLESEED_PYTHON_BINDENTITYCONTAINERS_H |
32 | |
33 | // appleseed.python headers. |
34 | #include "pyseed.h" // has to be first, to avoid redefinition warnings |
35 | #include "dict2dict.h" |
36 | |
37 | // appleseed.renderer headers. |
38 | #include "renderer/modeling/entity/entitymap.h" |
39 | #include "renderer/modeling/entity/entityvector.h" |
40 | |
41 | // appleseed.foundation headers. |
42 | #include "foundation/utility/autoreleaseptr.h" |
43 | |
44 | // Standard headers. |
45 | #include <cstddef> |
46 | #include <string> |
47 | |
48 | namespace detail |
49 | { |
50 | template <typename T> |
51 | T* typed_entity_vector_get_item(renderer::TypedEntityVector<T>& vec, const int relative_index) |
52 | { |
53 | const size_t index = |
54 | static_cast<size_t>( |
55 | relative_index >= 0 ? relative_index : vec.size() + relative_index); |
56 | |
57 | if (index >= vec.size()) |
58 | { |
59 | PyErr_SetString(PyExc_IndexError, "Invalid index in appleseed.EntityVector" ); |
60 | boost::python::throw_error_already_set(); |
61 | } |
62 | |
63 | return vec.get_by_index(index); |
64 | } |
65 | |
66 | template <typename T> |
67 | boost::python::object typed_entity_vector_remove(renderer::TypedEntityVector<T>& vec, T* entity) |
68 | { |
69 | foundation::auto_release_ptr<T> e = vec.remove(entity); |
70 | return boost::python::object(e); |
71 | } |
72 | |
73 | template <typename T> |
74 | T* typed_entity_map_get_item(renderer::TypedEntityMap<T>& map, const std::string& key) |
75 | { |
76 | return map.get_by_name(key.c_str()); |
77 | } |
78 | |
79 | template <typename T> |
80 | boost::python::object typed_entity_map_remove(renderer::TypedEntityMap<T>* map, T* entity) |
81 | { |
82 | foundation::auto_release_ptr<T> e = map->remove(entity); |
83 | return boost::python::object(e); |
84 | } |
85 | |
86 | template <typename T> |
87 | boost::python::object typed_entity_map_remove_by_uid(renderer::TypedEntityMap<T>* map, const foundation::UniqueID id) |
88 | { |
89 | foundation::auto_release_ptr<T> e = map->remove(id); |
90 | return boost::python::object(e); |
91 | } |
92 | |
93 | template <typename T> |
94 | boost::python::object typed_entity_map_get_iter(renderer::TypedEntityMap<T>* map) |
95 | { |
96 | boost::python::dict items; |
97 | |
98 | typedef typename renderer::TypedEntityMap<T>::iterator iterator; |
99 | |
100 | for (iterator it(map->begin()), e(map->end()); it != e; ++it) |
101 | items[it->get_name()] = boost::python::ptr(&(*it)); |
102 | |
103 | return items.attr("__iter__" )(); |
104 | } |
105 | |
106 | template <typename T> |
107 | boost::python::list typed_entity_map_get_keys(renderer::TypedEntityMap<T>* map) |
108 | { |
109 | boost::python::list items; |
110 | |
111 | typedef typename renderer::TypedEntityMap<T>::iterator iterator; |
112 | |
113 | for (iterator it(map->begin()), e(map->end()); it != e; ++it) |
114 | items.append(it->get_name()); |
115 | |
116 | return items; |
117 | } |
118 | |
119 | template <typename T> |
120 | boost::python::list typed_entity_map_get_values(renderer::TypedEntityMap<T>* map) |
121 | { |
122 | boost::python::list items; |
123 | |
124 | typedef typename renderer::TypedEntityMap<T>::iterator iterator; |
125 | |
126 | for (iterator it(map->begin()), e(map->end()); it != e; ++it) |
127 | items.append(boost::python::ptr(&(*it))); |
128 | |
129 | return items; |
130 | } |
131 | } |
132 | |
133 | template <typename T> |
134 | void bind_typed_entity_vector(const char* name) |
135 | { |
136 | boost::python::class_<renderer::TypedEntityVector<T>, boost::python::bases<renderer::EntityVector>, boost::noncopyable>(name) |
137 | .def("__getitem__" , detail::typed_entity_vector_get_item<T>, boost::python::return_value_policy<boost::python::reference_existing_object>()) |
138 | .def("get_by_uid" , &renderer::TypedEntityVector<T>::get_by_uid, boost::python::return_value_policy<boost::python::reference_existing_object>()) |
139 | .def("get_by_name" , &renderer::TypedEntityVector<T>::get_by_name, boost::python::return_value_policy<boost::python::reference_existing_object>()) |
140 | |
141 | .def("insert" , &renderer::TypedEntityVector<T>::insert) |
142 | .def("remove" , &detail::typed_entity_vector_remove<T>) |
143 | |
144 | .def("__iter__" , boost::python::iterator<renderer::TypedEntityVector<T>, boost::python::return_internal_reference<> >()); |
145 | } |
146 | |
147 | template <typename T> |
148 | void bind_typed_entity_map(const char* name) |
149 | { |
150 | boost::python::class_<renderer::TypedEntityMap<T>, boost::python::bases<renderer::EntityMap>, boost::noncopyable>(name) |
151 | .def("__getitem__" , detail::typed_entity_map_get_item<T>, boost::python::return_value_policy<boost::python::reference_existing_object>()) |
152 | .def("get_by_uid" , &renderer::TypedEntityMap<T>::get_by_uid, boost::python::return_value_policy<boost::python::reference_existing_object>()) |
153 | .def("get_by_name" , &renderer::TypedEntityMap<T>::get_by_name, boost::python::return_value_policy<boost::python::reference_existing_object>()) |
154 | |
155 | .def("insert" , &renderer::TypedEntityMap<T>::insert) |
156 | .def("remove" , &detail::typed_entity_map_remove<T>) |
157 | .def("remove_by_uid" , &detail::typed_entity_map_remove_by_uid<T>) |
158 | |
159 | .def("__iter__" , &detail::typed_entity_map_get_iter<T>) |
160 | |
161 | .def("keys" , &detail::typed_entity_map_get_keys<T>) |
162 | .def("values" , &detail::typed_entity_map_get_values<T>); |
163 | } |
164 | |
165 | #endif // !APPLESEED_PYTHON_BINDENTITYCONTAINERS_H |
166 | |