diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2006-12-22 16:09:43 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2006-12-22 16:09:43 +0000 |
commit | 6d4e6dc580c18ee940a30345656c70c054a6fa2d (patch) | |
tree | a2812be9279504cca1db6f3c9d0b70bf84d52639 | |
parent | 585e49184209f6f1679ddb6ee628efd02f7cbb0d (diff) |
start using global, 100% generic enum to/from string object
git-svn-id: svn://localhost/ardour2/trunk@1246 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r-- | libs/ardour/SConscript | 1 | ||||
-rw-r--r-- | libs/ardour/ardour/types.h | 2 | ||||
-rw-r--r-- | libs/ardour/audioregion.cc | 11 | ||||
-rw-r--r-- | libs/ardour/enums.cc | 321 | ||||
-rw-r--r-- | libs/ardour/globals.cc | 4 | ||||
-rw-r--r-- | libs/ardour/session.cc | 1 | ||||
-rw-r--r-- | libs/ardour/session_state.cc | 1 | ||||
-rw-r--r-- | libs/pbd/SConscript | 1 | ||||
-rw-r--r-- | libs/pbd/enumwriter.cc | 194 | ||||
-rw-r--r-- | libs/pbd/pbd/enumwriter.h | 74 |
10 files changed, 606 insertions, 4 deletions
diff --git a/libs/ardour/SConscript b/libs/ardour/SConscript index 2b23f4ffac..9f77f0af9c 100644 --- a/libs/ardour/SConscript +++ b/libs/ardour/SConscript @@ -48,6 +48,7 @@ crossfade.cc curve.cc cycle_timer.cc default_click.cc +enums.cc gain.cc gdither.cc globals.cc diff --git a/libs/ardour/ardour/types.h b/libs/ardour/ardour/types.h index 32b3231c4e..27ff8e93da 100644 --- a/libs/ardour/ardour/types.h +++ b/libs/ardour/ardour/types.h @@ -324,7 +324,7 @@ namespace ARDOUR { }; enum ShuttleUnits { - Percentage, + Percentage, Semitones }; diff --git a/libs/ardour/audioregion.cc b/libs/ardour/audioregion.cc index 32bd6cd685..7d3c1fc549 100644 --- a/libs/ardour/audioregion.cc +++ b/libs/ardour/audioregion.cc @@ -32,6 +32,7 @@ #include <pbd/basename.h> #include <pbd/xml++.h> #include <pbd/stacktrace.h> +#include <pbd/enumwriter.h> #include <ardour/audioregion.h> #include <ardour/session.h> @@ -601,8 +602,10 @@ AudioRegion::state (bool full) char buf2[64]; LocaleGuard lg (X_("POSIX")); - snprintf (buf, sizeof (buf), "0x%x", (int) _flags); - node.add_property ("flags", buf); + // snprintf (buf, sizeof (buf), "0x%x", (int) _flags); + // node.add_property ("flags", buf); + node.add_property ("flags", enum_2_string (_flags)); + snprintf (buf, sizeof(buf), "%.12g", _scale_amplitude); node.add_property ("scale-gain", buf); @@ -683,7 +686,9 @@ AudioRegion::set_live_state (const XMLNode& node, Change& what_changed, bool sen uint32_t old_flags = _flags; if ((prop = node.property ("flags")) != 0) { - _flags = Flag (strtol (prop->value().c_str(), (char **) 0, 16)); + _flags = Flag (string_2_enum (prop->value(), _flags)); + + //_flags = Flag (strtol (prop->value().c_str(), (char **) 0, 16)); _flags = Flag (_flags & ~Region::LeftOfSplit); _flags = Flag (_flags & ~Region::RightOfSplit); diff --git a/libs/ardour/enums.cc b/libs/ardour/enums.cc new file mode 100644 index 0000000000..293fface5a --- /dev/null +++ b/libs/ardour/enums.cc @@ -0,0 +1,321 @@ +#include <pbd/enumwriter.h> + +#include <ardour/types.h> +#include <ardour/session.h> +#include <ardour/location.h> +#include <ardour/audiofilesource.h> +#include <ardour/diskstream.h> +#include <ardour/audioregion.h> +#include <ardour/route_group.h> +#include <ardour/panner.h> + +using namespace std; +using namespace PBD; +using namespace ARDOUR; + +void +setup_enum_writer () +{ + EnumWriter* enum_writer = new EnumWriter(); + vector<int> i; + vector<string> s; + + + OverlapType _OverlapType; + AlignStyle _AlignStyle; + MeterPoint _MeterPoint; + TrackMode _TrackMode; + MeterFalloff _MeterFalloff; + MeterHold _MeterHold; + EditMode _EditMode; + RegionPoint _RegionPoint; + Placement _Placement; + MonitorModel _MonitorModel; + CrossfadeModel _CrossfadeModel; + LayerModel _LayerModel; + SoloModel _SoloModel; + SampleFormat _SampleFormat; + HeaderFormat _HeaderFormat; + PluginType _PluginType; + SlaveSource _SlaveSource; + ShuttleBehaviour _ShuttleBehaviour; + ShuttleUnits _ShuttleUnits; + mute_type _mute_type; + Session::RecordState _Session_RecordState; + Session::Event::Type _Session_Event_Type; + Session::SmpteFormat _Session_SmpteFormat; + Session::PullupFormat _Session_PullupFormat; + AudioRegion::FadeShape _AudioRegion_FadeShape; + Panner::LinkDirection _Panner_LinkDirection; + IOChange _IOChange; + AutomationType _AutomationType; + AutoState _AutoState; + AutoStyle _AutoStyle; + AutoConnectOption _AutoConnectOption; + Session::StateOfTheState _Session_StateOfTheState; + Route::Flag _Route_Flag; + AudioFileSource::Flag _AudioFileSource_Flag; + Diskstream::Flag _Diskstream_Flag; + Location::Flags _Location_Flags; + RouteGroup::Flag _RouteGroup_Flag; + Region::Flag _Region_Flag; + +#define REGISTER(e) enum_writer->register_distinct (typeid(e).name(), i, s); i.clear(); s.clear() +#define REGISTER_BITS(e) enum_writer->register_bits (typeid(e).name(), i, s); i.clear(); s.clear() +#define REGISTER_ENUM(e) i.push_back (e); s.push_back (#e) +#define REGISTER_CLASS_ENUM(t,e) i.push_back (t::e); s.push_back (#e) + + REGISTER_ENUM (NoChange); + REGISTER_ENUM (ConfigurationChanged); + REGISTER_ENUM (ConnectionsChanged); + REGISTER_BITS (_IOChange); + + REGISTER_ENUM (OverlapNone); + REGISTER_ENUM (OverlapInternal); + REGISTER_ENUM (OverlapStart); + REGISTER_ENUM (OverlapEnd); + REGISTER_ENUM (OverlapExternal); + REGISTER (_OverlapType); + + REGISTER_ENUM (GainAutomation); + REGISTER_ENUM (PanAutomation); + REGISTER_ENUM (PluginAutomation); + REGISTER_ENUM (SoloAutomation); + REGISTER_ENUM (MuteAutomation); + REGISTER_BITS (_AutomationType); + + REGISTER_ENUM (Off); + REGISTER_ENUM (Write); + REGISTER_ENUM (Touch); + REGISTER_ENUM (Play); + REGISTER_BITS (_AutoState); + + REGISTER_ENUM (Absolute); + REGISTER_ENUM (Trim); + REGISTER_BITS (_AutoStyle); + + REGISTER_ENUM (CaptureTime); + REGISTER_ENUM (ExistingMaterial); + REGISTER (_AlignStyle); + + REGISTER_ENUM (MeterInput); + REGISTER_ENUM (MeterPreFader); + REGISTER_ENUM (MeterPostFader); + REGISTER (_MeterPoint); + + REGISTER_ENUM (Normal); + REGISTER_ENUM (Destructive); + REGISTER (_TrackMode); + + REGISTER_ENUM (MeterFalloffOff); + REGISTER_ENUM (MeterFalloffSlowest); + REGISTER_ENUM (MeterFalloffSlow); + REGISTER_ENUM (MeterFalloffMedium); + REGISTER_ENUM (MeterFalloffFast); + REGISTER_ENUM (MeterFalloffFaster); + REGISTER_ENUM (MeterFalloffFastest); + REGISTER (_MeterFalloff); + + REGISTER_ENUM (MeterHoldOff); + REGISTER_ENUM (MeterHoldShort); + REGISTER_ENUM (MeterHoldMedium); + REGISTER_ENUM (MeterHoldLong); + REGISTER (_MeterHold); + + REGISTER_ENUM (Slide); + REGISTER_ENUM (Splice); + REGISTER (_EditMode); + + REGISTER_ENUM (Start); + REGISTER_ENUM (End); + REGISTER_ENUM (SyncPoint); + REGISTER (_RegionPoint); + + + REGISTER_ENUM (PreFader); + REGISTER_ENUM (PostFader); + REGISTER (_Placement); + + REGISTER_ENUM (HardwareMonitoring); + REGISTER_ENUM (SoftwareMonitoring); + REGISTER_ENUM (ExternalMonitoring); + REGISTER (_MonitorModel); + + REGISTER_ENUM (FullCrossfade); + REGISTER_ENUM (ShortCrossfade); + REGISTER (_CrossfadeModel); + + REGISTER_ENUM (LaterHigher); + REGISTER_ENUM (MoveAddHigher); + REGISTER_ENUM (AddHigher); + REGISTER (_LayerModel); + + REGISTER_ENUM (InverseMute); + REGISTER_ENUM (SoloBus); + REGISTER (_SoloModel); + + REGISTER_ENUM (AutoConnectPhysical); + REGISTER_ENUM (AutoConnectMaster); + REGISTER_BITS (_AutoConnectOption); + + REGISTER_ENUM (FormatFloat); + REGISTER_ENUM (FormatInt24); + REGISTER (_SampleFormat); + + REGISTER_ENUM (BWF); + REGISTER_ENUM (WAVE); + REGISTER_ENUM (WAVE64); + REGISTER_ENUM (CAF); + REGISTER_ENUM (AIFF); + REGISTER_ENUM (iXML); + REGISTER_ENUM (RF64); + REGISTER (_HeaderFormat); + + REGISTER_ENUM (AudioUnit); + REGISTER_ENUM (LADSPA); + REGISTER_ENUM (VST); + REGISTER (_PluginType); + + REGISTER_ENUM (None); + REGISTER_ENUM (MTC); + REGISTER_ENUM (JACK); + REGISTER (_SlaveSource); + + REGISTER_ENUM (Sprung); + REGISTER_ENUM (Wheel); + REGISTER (_ShuttleBehaviour); + + REGISTER_ENUM (Percentage); + REGISTER_ENUM (Semitones); + REGISTER (_ShuttleUnits); + + REGISTER_CLASS_ENUM (Session, Disabled); + REGISTER_CLASS_ENUM (Session, Enabled); + REGISTER_CLASS_ENUM (Session, Recording); + REGISTER (_Session_RecordState); + + REGISTER_CLASS_ENUM (Session::Event, SetTransportSpeed); + REGISTER_CLASS_ENUM (Session::Event, SetDiskstreamSpeed); + REGISTER_CLASS_ENUM (Session::Event, Locate); + REGISTER_CLASS_ENUM (Session::Event, LocateRoll); + REGISTER_CLASS_ENUM (Session::Event, SetLoop); + REGISTER_CLASS_ENUM (Session::Event, PunchIn); + REGISTER_CLASS_ENUM (Session::Event, PunchOut); + REGISTER_CLASS_ENUM (Session::Event, RangeStop); + REGISTER_CLASS_ENUM (Session::Event, RangeLocate); + REGISTER_CLASS_ENUM (Session::Event, Overwrite); + REGISTER_CLASS_ENUM (Session::Event, SetSlaveSource); + REGISTER_CLASS_ENUM (Session::Event, Audition); + REGISTER_CLASS_ENUM (Session::Event, InputConfigurationChange); + REGISTER_CLASS_ENUM (Session::Event, SetAudioRange); + REGISTER_CLASS_ENUM (Session::Event, SetPlayRange); + REGISTER_CLASS_ENUM (Session::Event, StopOnce); + REGISTER_CLASS_ENUM (Session::Event, AutoLoop); + REGISTER (_Session_Event_Type); + + REGISTER_CLASS_ENUM (Session, Clean); + REGISTER_CLASS_ENUM (Session, Dirty); + REGISTER_CLASS_ENUM (Session, CannotSave); + REGISTER_CLASS_ENUM (Session, Deletion); + REGISTER_CLASS_ENUM (Session, InitialConnecting); + REGISTER_CLASS_ENUM (Session, Loading); + REGISTER_CLASS_ENUM (Session, InCleanup); + REGISTER_BITS (_Session_StateOfTheState); + + REGISTER_CLASS_ENUM (Session, smpte_23976); + REGISTER_CLASS_ENUM (Session, smpte_24); + REGISTER_CLASS_ENUM (Session, smpte_24976); + REGISTER_CLASS_ENUM (Session, smpte_25); + REGISTER_CLASS_ENUM (Session, smpte_2997); + REGISTER_CLASS_ENUM (Session, smpte_2997drop); + REGISTER_CLASS_ENUM (Session, smpte_30); + REGISTER_CLASS_ENUM (Session, smpte_30drop); + REGISTER_CLASS_ENUM (Session, smpte_5994); + REGISTER_CLASS_ENUM (Session, smpte_60); + REGISTER (_Session_SmpteFormat); + + REGISTER_CLASS_ENUM (Session, pullup_Plus4Plus1); + REGISTER_CLASS_ENUM (Session, pullup_Plus4); + REGISTER_CLASS_ENUM (Session, pullup_Plus4Minus1); + REGISTER_CLASS_ENUM (Session, pullup_Plus1); + REGISTER_CLASS_ENUM (Session, pullup_None); + REGISTER_CLASS_ENUM (Session, pullup_Minus1); + REGISTER_CLASS_ENUM (Session, pullup_Minus4Plus1); + REGISTER_CLASS_ENUM (Session, pullup_Minus4); + REGISTER_CLASS_ENUM (Session, pullup_Minus4Minus1); + REGISTER (_Session_PullupFormat); + + REGISTER_ENUM (PRE_FADER); + REGISTER_ENUM (POST_FADER); + REGISTER_ENUM (CONTROL_OUTS); + REGISTER_ENUM (MAIN_OUTS); + REGISTER (_mute_type); + + REGISTER_CLASS_ENUM (Route, Hidden); + REGISTER_CLASS_ENUM (Route, MasterOut); + REGISTER_CLASS_ENUM (Route, ControlOut); + REGISTER_BITS (_Route_Flag); + + REGISTER_CLASS_ENUM (AudioFileSource, Writable); + REGISTER_CLASS_ENUM (AudioFileSource, CanRename); + REGISTER_CLASS_ENUM (AudioFileSource, Broadcast); + REGISTER_CLASS_ENUM (AudioFileSource, Removable); + REGISTER_CLASS_ENUM (AudioFileSource, RemovableIfEmpty); + REGISTER_CLASS_ENUM (AudioFileSource, RemoveAtDestroy); + REGISTER_CLASS_ENUM (AudioFileSource, NoPeakFile); + REGISTER_CLASS_ENUM (AudioFileSource, Destructive); + REGISTER_BITS (_AudioFileSource_Flag); + + REGISTER_CLASS_ENUM (AudioRegion, Linear); + REGISTER_CLASS_ENUM (AudioRegion, Fast); + REGISTER_CLASS_ENUM (AudioRegion, Slow); + REGISTER_CLASS_ENUM (AudioRegion, LogA); + REGISTER_CLASS_ENUM (AudioRegion, LogB); + REGISTER (_AudioRegion_FadeShape); + + REGISTER_CLASS_ENUM (Diskstream, Recordable); + REGISTER_CLASS_ENUM (Diskstream, Hidden); + REGISTER_CLASS_ENUM (Diskstream, Destructive); + REGISTER_BITS (_Diskstream_Flag); + + REGISTER_CLASS_ENUM (Location, IsMark); + REGISTER_CLASS_ENUM (Location, IsAutoPunch); + REGISTER_CLASS_ENUM (Location, IsAutoLoop); + REGISTER_CLASS_ENUM (Location, IsHidden); + REGISTER_CLASS_ENUM (Location, IsCDMarker); + REGISTER_CLASS_ENUM (Location, IsEnd); + REGISTER_CLASS_ENUM (Location, IsRangeMarker); + REGISTER_CLASS_ENUM (Location, IsStart); + REGISTER_BITS (_Location_Flags); + + + REGISTER_CLASS_ENUM (RouteGroup, Relative); + REGISTER_CLASS_ENUM (RouteGroup, Active); + REGISTER_CLASS_ENUM (RouteGroup, Hidden); + REGISTER_BITS (_RouteGroup_Flag); + + REGISTER_CLASS_ENUM (Panner, SameDirection); + REGISTER_CLASS_ENUM (Panner, OppositeDirection); + REGISTER (_Panner_LinkDirection); + + REGISTER_CLASS_ENUM (Region, Muted); + REGISTER_CLASS_ENUM (Region, Opaque); + REGISTER_CLASS_ENUM (Region, EnvelopeActive); + REGISTER_CLASS_ENUM (Region, DefaultFadeIn); + REGISTER_CLASS_ENUM (Region, DefaultFadeOut); + REGISTER_CLASS_ENUM (Region, Locked); + REGISTER_CLASS_ENUM (Region, Automatic); + REGISTER_CLASS_ENUM (Region, WholeFile); + REGISTER_CLASS_ENUM (Region, FadeIn); + REGISTER_CLASS_ENUM (Region, FadeOut); + REGISTER_CLASS_ENUM (Region, Copied); + REGISTER_CLASS_ENUM (Region, Import); + REGISTER_CLASS_ENUM (Region, External); + REGISTER_CLASS_ENUM (Region, SyncMarked); + REGISTER_CLASS_ENUM (Region, LeftOfSplit); + REGISTER_CLASS_ENUM (Region, RightOfSplit); + REGISTER_CLASS_ENUM (Region, Hidden); + REGISTER_CLASS_ENUM (Region, DoNotSaveState); + REGISTER_BITS (_Region_Flag); + +} diff --git a/libs/ardour/globals.cc b/libs/ardour/globals.cc index c68951e525..274b0f1d3c 100644 --- a/libs/ardour/globals.cc +++ b/libs/ardour/globals.cc @@ -274,10 +274,14 @@ setup_hardware_optimization (bool try_optimization) int ARDOUR::init (bool use_vst, bool try_optimization) { + extern void setup_enum_writer (); + (void) bindtextdomain(PACKAGE, LOCALEDIR); PBD::ID::init (); + setup_enum_writer (); + lrdf_init(); Library = new AudioLibrary; diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 962e8487bf..45be26c598 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -2682,6 +2682,7 @@ Session::add_source (boost::shared_ptr<Source> source) source->GoingAway.connect (sigc::bind (mem_fun (this, &Session::remove_source), boost::weak_ptr<Source> (source))); set_dirty(); } + } } diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 986656af5a..fb15de15c4 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -1429,6 +1429,7 @@ Session::load_sources (const XMLNode& node) if ((source = XMLSourceFactory (**niter)) == 0) { error << _("Session: cannot create Source from XML description.") << endmsg; } + } return 0; diff --git a/libs/pbd/SConscript b/libs/pbd/SConscript index f474834fd8..b16880b286 100644 --- a/libs/pbd/SConscript +++ b/libs/pbd/SConscript @@ -23,6 +23,7 @@ base_ui.cc convert.cc command.cc controllable.cc +enumwriter.cc dmalloc.cc error.cc id.cc diff --git a/libs/pbd/enumwriter.cc b/libs/pbd/enumwriter.cc new file mode 100644 index 0000000000..c42cc3a5c2 --- /dev/null +++ b/libs/pbd/enumwriter.cc @@ -0,0 +1,194 @@ +/* + Copyright (C) 2006 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#include <pbd/enumwriter.h> +#include <pbd/error.h> +#include <pbd/compose.h> + +using namespace std; +using namespace PBD; + +#include "i18n.h" + +EnumWriter* EnumWriter::_instance = 0; + +EnumWriter::EnumWriter () +{ + if (_instance == 0) { + _instance = this; + } +} + +EnumWriter::~EnumWriter () +{ +} + +void +EnumWriter::register_distinct (string type, vector<int> v, vector<string> s) +{ + pair<string,EnumRegistration> newpair; + pair<Registry::iterator,bool> result; + + newpair.first = type; + newpair.second = EnumRegistration (v, s, false); + + result = registry.insert (newpair); + + if (!result.second) { + warning << string_compose (_("enum type \"%1\" already registered with the enum writer"), type) << endmsg; + } +} + +void +EnumWriter::register_bits (string type, vector<int> v, vector<string> s) +{ + pair<string,EnumRegistration> newpair; + pair<Registry::iterator,bool> result; + + newpair.first = type; + newpair.second = EnumRegistration (v, s, true); + + result = registry.insert (newpair); + + if (!result.second) { + warning << _("enum type \"%1\" already registered with the enum writer") << endmsg; + } +} + +string +EnumWriter::write (string type, int value) +{ + Registry::iterator x = registry.find (type); + + if (x == registry.end()) { + error << string_compose (_("EnumWriter: unknown enumeration type \"%1\""), type) << endmsg; + throw unknown_enumeration(); + } + + if (x->second.bitwise) { + return write_bits (x->second, value); + } else { + return write_distinct (x->second, value); + } +} + +int +EnumWriter::read (string type, string value) +{ + Registry::iterator x = registry.find (type); + + if (x == registry.end()) { + error << string_compose (_("EnumWriter: unknown enumeration type \"%1\""), type) << endmsg; + throw unknown_enumeration(); + } + + if (x->second.bitwise) { + return read_bits (x->second, value); + } else { + return read_distinct (x->second, value); + } +} + +string +EnumWriter::write_bits (EnumRegistration& er, int value) +{ + vector<int>::iterator i; + vector<string>::iterator s; + string result; + + for (i = er.values.begin(), s = er.names.begin(); i != er.values.end(); ++i, ++s) { + if (value & (*i)) { + if (!result.empty()) { + result += ','; + } + result += (*s); + } + } + + return result; +} + +string +EnumWriter::write_distinct (EnumRegistration& er, int value) +{ + vector<int>::iterator i; + vector<string>::iterator s; + + for (i = er.values.begin(), s = er.names.begin(); i != er.values.end(); ++i, ++s) { + if (value == (*i)) { + return (*s); + } + } + + return string(); +} + +int +EnumWriter::read_bits (EnumRegistration& er, string str) +{ + vector<int>::iterator i; + vector<string>::iterator s; + int result = 0; + bool found = false; + string::size_type comma; + + do { + + comma = str.find_first_of (','); + string segment = str.substr (0, comma); + + for (i = er.values.begin(), s = er.names.begin(); i != er.values.end(); ++i, ++s) { + if (segment == (*s)) { + result |= (*i); + found = true; + } + } + + if (comma == string::npos) { + break; + } + + str = str.substr (comma+1); + + } while (true); + + if (!found) { + throw unknown_enumeration(); + } + + return result; +} + +int +EnumWriter::read_distinct (EnumRegistration& er, string str) +{ + vector<int>::iterator i; + vector<string>::iterator s; + + for (i = er.values.begin(), s = er.names.begin(); i != er.values.end(); ++i, ++s) { + if (str == (*s)) { + return (*i); + } + } + + throw unknown_enumeration(); +} + + diff --git a/libs/pbd/pbd/enumwriter.h b/libs/pbd/pbd/enumwriter.h new file mode 100644 index 0000000000..356a0a1acc --- /dev/null +++ b/libs/pbd/pbd/enumwriter.h @@ -0,0 +1,74 @@ +/* + Copyright (C) 2006 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#include <map> +#include <string> +#include <vector> +#include <exception> + + +namespace PBD { + +class unknown_enumeration : public std::exception { + public: + virtual const char *what() const throw() { return "unknown enumerator in PBD::EnumWriter"; } +}; + +class EnumWriter { + public: + EnumWriter (); + ~EnumWriter (); + + static EnumWriter& instance() { return *_instance; } + + void register_distinct (std::string type, std::vector<int>, std::vector<std::string>); + void register_bits (std::string type, std::vector<int>, std::vector<std::string>); + + std::string write (std::string type, int value); + int read (std::string type, std::string value); + + private: + struct EnumRegistration { + std::vector<int> values; + std::vector<std::string> names; + bool bitwise; + + EnumRegistration() {} + EnumRegistration (std::vector<int>& v, std::vector<std::string>& s, bool b) + : values (v), names (s), bitwise (b) {} + }; + + typedef std::map<std::string, EnumRegistration> Registry; + Registry registry; + + std::string write_bits (EnumRegistration&, int value); + std::string write_distinct (EnumRegistration&, int value); + + int read_bits (EnumRegistration&, std::string value); + int read_distinct (EnumRegistration&, std::string value); + + static EnumWriter* _instance; +}; + +} + +#define enum_2_string(e) (PBD::EnumWriter::instance().write (typeid(e).name(), e)) +#define string_2_enum(str,e) (PBD::EnumWriter::instance().read (typeid(e).name(), (str))) + |