LV2 Toolkit  1.1.1
 All Classes Namespaces Functions Typedefs Enumerations Enumerator Groups Pages
state.hpp
1 /****************************************************************************
2 
3  state.hpp - support file for writing LV2 plugins in C++
4 
5  Copyright (C) 2012 Michael Fisher <mfisher31@gmail.com>
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 3 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 01222-1307 USA
20 
21  ****************************************************************************/
22 
23 #ifndef LVTK_LV2_STATE_HPP
24 #define LVTK_LV2_STATE_HPP
25 
26 #include <cassert>
27 #include <lv2/lv2plug.in/ns/ext/state/state.h>
28 
29 namespace lvtk {
30 
31  typedef enum {
45  STATE_IS_POD = LV2_STATE_IS_POD,
46 
56  STATE_IS_PORTABLE = LV2_STATE_IS_PORTABLE,
57 
67  STATE_IS_NATIVE = LV2_STATE_IS_NATIVE
68  } StateFlags;
69 
70  typedef enum {
71  STATE_SUCCESS = LV2_STATE_SUCCESS,
72  STATE_ERR_UNKNOWN = LV2_STATE_ERR_UNKNOWN,
73  STATE_ERR_BAD_TYPE = LV2_STATE_ERR_BAD_TYPE,
74  STATE_ERR_BAD_FLAGS = LV2_STATE_ERR_BAD_FLAGS,
75  STATE_ERR_NO_FEATURE = LV2_STATE_ERR_NO_FEATURE,
76  STATE_ERR_NO_PROPERTY = LV2_STATE_ERR_NO_PROPERTY
77  } StateStatus;
78 
79 
84  struct StateRetrieve {
85  StateRetrieve(LV2_State_Retrieve_Function srfunc, LV2_State_Handle handle)
86  : p_handle(handle), p_srfunc(srfunc) { }
87 
96  const void* operator () (uint32_t key, size_t *size = NULL,
97  uint32_t *type = NULL,
98  uint32_t *flags = NULL) const
99  {
100  return p_srfunc(p_handle, key, size, type, flags);
101  }
102 
103  private:
104  LV2_State_Handle p_handle;
105  LV2_State_Retrieve_Function p_srfunc;
106  };
107 
108  /* A little redundant */
109 
114  struct StateStore {
115  StateStore (LV2_State_Store_Function ssfunc, LV2_State_Handle handle)
116  : p_handle(handle), p_ssfunc(ssfunc) { }
117 
127  inline StateStatus operator () (uint32_t key, const void* value,
128  size_t size,
129  uint32_t type,
130  uint32_t flags = 0) const
131  {
132  return (StateStatus) p_ssfunc (p_handle, key, value, size, type, flags);
133  }
134 
135  private:
136  LV2_State_Handle p_handle;
137  LV2_State_Store_Function p_ssfunc;
138  };
139 
146  template <bool Required = true>
147  struct State
148  {
149  template <class Derived>
150  struct I : Extension<Required>
151  {
152 
153  I() : p_make_path (NULL) { }
154 
156  static void
158  {
161  hmap[LV2_STATE__makePath] = &I<Derived>::handle_make_feature;
162  }
163 
165  static void
166  handle_make_feature(void* instance, FeatureData data)
167  {
168  Derived* d = reinterpret_cast<Derived*>(instance);
169  I<Derived>* mixin = static_cast<I<Derived>*>(d);
170  mixin->p_make_path =
171  reinterpret_cast<LV2_State_Make_Path*> (data);
172  }
173 
174  bool
175  check_ok()
176  {
177  if (Required) {
178  this->m_ok = (p_make_path != NULL);
179  } else {
180  this->m_ok = true;
181  }
182 
183  if (LVTK_DEBUG) {
184  std::clog<<" [State] Validation "
185  <<(this->m_ok ? "succeeded" : "failed")<<"."
186  <<std::endl;
187  }
188 
189  return this->m_ok;
190  }
191 
193  static const void*
194  extension_data (const char* uri)
195  {
196  if (!std::strcmp (uri, LV2_STATE__interface))
197  {
198  static LV2_State_Interface state = { &I<Derived>::_save,
199  &I<Derived>::_restore };
200  return &state;
201  }
202  return 0;
203  }
204 
205 
206  /* =============== State C++ Interface ========================== */
207 
208 
210  save (StateStore &store, uint32_t flags,
211  const FeatureVec &features)
212  {
213  return STATE_SUCCESS;
214  }
215 
217  restore (StateRetrieve &retrieve, uint32_t flags,
218  const FeatureVec &features)
219  {
220  return STATE_SUCCESS;
221  }
222 
223  protected:
224 
225 #if 0
226  SAVEME - Map Path is for the State interface methods only.
227 
228  char*
229  abstract_path (const char* absolute_path);
230 
231  char*
232  absolute_path(const char* abstract_path)
233  {
234  return p_map_path->absolute_path (p_map_path->handle, abstract_path);
235  }
236 #endif
237 
248  char*
249  path (const char* path)
250  {
251  assert (p_make_path != NULL);
252  return p_make_path->path (p_make_path->handle, path);
253  }
254 
255 
256  /* ============== LV2 Boiler Plate Implementation ================= */
257 
258  LV2_State_Make_Path * p_make_path;
259 
261  static LV2_State_Status _save(LV2_Handle instance,
262  LV2_State_Store_Function store,
263  LV2_State_Handle handle,
264  uint32_t flags,
265  const LV2_Feature *const * features)
266  {
267  Derived* plugin = reinterpret_cast<Derived*>(instance);
268 
269  StateStore ss (store, handle);
270 
271  FeatureVec feature_set;
272  for (int i = 0; features[i]; ++i) {
273  feature_set.push_back (features[i]);
274  }
275 
276  return (LV2_State_Status)plugin->save(ss, flags, feature_set);
277  }
278 
280  static LV2_State_Status _restore(LV2_Handle instance,
281  LV2_State_Retrieve_Function retrieve,
282  LV2_State_Handle handle,
283  uint32_t flags,
284  const LV2_Feature *const * features)
285  {
286  Derived* plugin = reinterpret_cast<Derived*>(instance);
287 
289  StateRetrieve sr (retrieve, handle);
290 
292  FeatureVec feature_set;
293  for (int i = 0; features[i]; ++i) {
294  feature_set.push_back (features[i]);
295  }
296 
297  return (LV2_State_Status)plugin->restore(sr, flags, feature_set);
298  }
299  };
300  };
301 
302 } /* namespace lvtk */
303 
304 #endif /* LVTK_LV2_STATE_HPP */