Ardour  9.8-262-gcc2b139c48
stateful.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2000-2015 Paul Davis <paul@linuxaudiosystems.com>
3  * Copyright (C) 2006 Hans Fugal <hans@fugal.net>
4  * Copyright (C) 2007-2015 Tim Mayberry <mojofunk@gmail.com>
5  * Copyright (C) 2009-2011 Carl Hetherington <carl@carlh.net>
6  * Copyright (C) 2015 Robin Gareus <robin@gareus.org>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program; if not, write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21  */
22 
23 #pragma once
24 
25 #include <atomic>
26 #include <string>
27 #include <list>
28 #include <cassert>
29 
30 #include "pbd/libpbd_visibility.h"
31 #include "pbd/id.h"
32 #include "pbd/xml++.h"
33 #include "pbd/property_basics.h"
34 #include "pbd/signals.h"
35 
36 class XMLNode;
37 
38 namespace PBD {
39 
40 namespace sys {
41  class path;
42 }
43 
44 class PropertyList;
45 class OwnedPropertyList;
46 
48 class /*LIBPBD_API*/ Stateful {
49  public:
51  LIBPBD_API virtual ~Stateful();
52 
53  LIBPBD_API virtual XMLNode& get_state () const = 0;
54  LIBPBD_API virtual int set_state (const XMLNode&, int version) = 0;
55 
56  LIBPBD_API virtual bool apply_change (PropertyBase const &);
58 
59  LIBPBD_API const OwnedPropertyList& properties() const { return *_properties; }
60 
62 
63  /* Extra XML node: so that 3rd parties can attach state to the XMLNode
64  representing the state of this object.
65  */
66 
68  LIBPBD_API XMLNode *extra_xml (const std::string& str, bool add_if_missing = false);
70 
71  LIBPBD_API const PBD::ID& id() const { return _id; }
72  LIBPBD_API bool set_id (const XMLNode&);
73  LIBPBD_API void set_id (const std::string&);
75 
76  /* RAII structure to manage thread-local ID regeneration. */
78 #if defined (MINGW_NATIVE_TLS) || defined (COMPILER_MSVC)
79  /* Due to Native TLS recently being added, errors come from
80  * thread_local variables during external linkage.
81  * See https://github.com/msys2/MINGW-packages/issues/29272 */
83  _old_val = _regenerate_xml_or_string_ids_ref ();
84  _regenerate_xml_or_string_ids_ref () = true;
85  }
87  _regenerate_xml_or_string_ids_ref () = _old_val;
88  }
89 #else
93  }
96  }
97 #endif
98  private:
99  bool _old_val;
100  };
101 
102  /* history management */
103 
107  LIBPBD_API virtual void rdiff (std::vector<PBD::Command*> &) const;
108  LIBPBD_API bool changed() const;
109 
110  /* create a property list from an XMLNode */
112 
113  /* How stateful's notify of changes to their properties */
114  /*LIBPBD_API*/ PBD::Signal<void(const PropertyChange&)> PropertyChanged;
115 
118 
121 
122  LIBPBD_API bool property_changes_suspended() const { return _stateful_frozen.load() > 0; }
123 
124  protected:
125 
126  LIBPBD_API void add_instant_xml (XMLNode&, const std::string& directory_path);
127  LIBPBD_API XMLNode *instant_xml (const std::string& str, const std::string& directory_path);
129 
131 
132  /* derived classes can implement this to do cross-checking
133  of property values after either a PropertyList or XML
134  driven property change.
135  */
136  LIBPBD_API virtual void post_set (const PropertyChange&) { };
137 
142 
143  std::string _xml_node_name;
145 
146  LIBPBD_API virtual void send_change (const PropertyChange&);
150  LIBPBD_API virtual void mid_thaw (const PropertyChange&) { }
151 
153 
154  private:
155  friend struct ForceIDRegeneration;
156  static thread_local bool _regenerate_xml_or_string_ids;
157 #if defined (MINGW_NATIVE_TLS) || defined (COMPILER_MSVC)
158  static LIBPBD_API bool& _regenerate_xml_or_string_ids_ref ();
159 #endif
160 
162  std::atomic<int> _stateful_frozen;
163 };
164 
165 } // namespace PBD
166 
Definition: id.h:33
void add_property(PropertyBase &s)
const PBD::ID & id() const
Definition: stateful.h:71
bool set_id(const XMLNode &)
virtual PropertyList * property_factory(const XMLNode &) const
std::atomic< int > _stateful_frozen
Definition: stateful.h:162
virtual XMLNode & get_state() const =0
PropertyChange set_values(XMLNode const &)
PropertyChange apply_changes(PropertyList const &)
virtual void send_change(const PropertyChange &)
virtual ~Stateful()
void clear_changes()
virtual void suspend_property_changes()
virtual void resume_property_changes()
virtual int set_state(const XMLNode &, int version)=0
const OwnedPropertyList & properties() const
Definition: stateful.h:59
PBD::Signal< void(const PropertyChange &)> PropertyChanged
Definition: stateful.h:114
XMLNode * _instant_xml
Definition: stateful.h:139
static int loading_state_version
Definition: stateful.h:117
virtual bool apply_change(PropertyBase const &)
bool regenerate_xml_or_string_ids() const
XMLNode * _extra_xml
Definition: stateful.h:136
std::string _xml_node_name
name of node to use for this object in XML
Definition: stateful.h:143
virtual void post_set(const PropertyChange &)
Definition: stateful.h:136
void save_extra_xml(const XMLNode &)
PropertyList * get_changes_as_properties(PBD::Command *) const
void add_instant_xml(XMLNode &, const std::string &directory_path)
virtual void rdiff(std::vector< PBD::Command * > &) const
bool property_changes_suspended() const
Definition: stateful.h:122
PBD::Mutex _lock
Definition: stateful.h:141
virtual void clear_owned_changes()
bool changed() const
virtual void mid_thaw(const PropertyChange &)
Definition: stateful.h:150
void set_id(const std::string &)
XMLNode * instant_xml(const std::string &str, const std::string &directory_path)
PBD::PropertyChange _pending_changed
Definition: stateful.h:140
void add_extra_xml(XMLNode &)
static int current_state_version
Definition: stateful.h:116
void add_properties(XMLNode &) const
XMLNode * extra_xml(const std::string &str, bool add_if_missing=false)
PBD::ID _id
Definition: stateful.h:161
static thread_local bool _regenerate_xml_or_string_ids
Definition: stateful.h:156
OwnedPropertyList * _properties
Definition: stateful.h:144
Definition: xml++.h:114
#define LIBPBD_API
Definition: axis_view.h:42