C++: Add UserOwned base template for objects with resources owned by user.

This commit is contained in:
Martin Ling 2014-09-02 21:05:42 +01:00 committed by Bert Vermeulen
parent 541c855e1d
commit 90e89c2a42
2 changed files with 38 additions and 19 deletions

View File

@ -71,9 +71,11 @@ shared_ptr<Context> Context::create()
} }
Context::Context() : Context::Context() :
UserOwned(structure),
session(NULL) session(NULL)
{ {
check(sr_init(&structure)); check(sr_init(&structure));
struct sr_dev_driver **driver_list = sr_driver_list(); struct sr_dev_driver **driver_list = sr_driver_list();
if (driver_list) if (driver_list)
for (int i = 0; driver_list[i]; i++) for (int i = 0; driver_list[i]; i++)
@ -533,7 +535,8 @@ vector<shared_ptr<Channel>> ChannelGroup::get_channels()
} }
Trigger::Trigger(shared_ptr<Context> context, string name) : Trigger::Trigger(shared_ptr<Context> context, string name) :
structure(sr_trigger_new(name.c_str())), context(context) UserOwned(sr_trigger_new(name.c_str())),
context(context)
{ {
for (auto stage = structure->stages; stage; stage = stage->next) for (auto stage = structure->stages; stage; stage = stage->next)
stages.push_back(new TriggerStage((struct sr_trigger_stage *) stage->data)); stages.push_back(new TriggerStage((struct sr_trigger_stage *) stage->data));
@ -690,6 +693,7 @@ EventSource::~EventSource()
} }
Session::Session(shared_ptr<Context> context) : Session::Session(shared_ptr<Context> context) :
UserOwned(structure),
context(context), saving(false) context(context), saving(false)
{ {
check(sr_session_new(&structure)); check(sr_session_new(&structure));
@ -697,6 +701,7 @@ Session::Session(shared_ptr<Context> context) :
} }
Session::Session(shared_ptr<Context> context, string filename) : Session::Session(shared_ptr<Context> context, string filename) :
UserOwned(structure),
context(context), saving(false) context(context), saving(false)
{ {
check(sr_session_load(filename.c_str(), &structure)); check(sr_session_load(filename.c_str(), &structure));
@ -936,7 +941,7 @@ void Session::set_trigger(shared_ptr<Trigger> trigger)
Packet::Packet(shared_ptr<Device> device, Packet::Packet(shared_ptr<Device> device,
const struct sr_datafeed_packet *structure) : const struct sr_datafeed_packet *structure) :
structure(structure), UserOwned(structure),
device(device) device(device)
{ {
switch (structure->type) switch (structure->type)
@ -1168,7 +1173,7 @@ shared_ptr<Input> InputFormat::create_input(
} }
Input::Input(shared_ptr<Context> context, const struct sr_input *structure) : Input::Input(shared_ptr<Context> context, const struct sr_input *structure) :
structure(structure), UserOwned(structure),
context(context), context(context),
device(nullptr) device(nullptr)
{ {
@ -1221,7 +1226,7 @@ shared_ptr<Device> InputDevice::get_shared_from_this()
Option::Option(const struct sr_option *structure, Option::Option(const struct sr_option *structure,
shared_ptr<const struct sr_option *> structure_array) : shared_ptr<const struct sr_option *> structure_array) :
structure(structure), UserOwned(structure),
structure_array(structure_array) structure_array(structure_array)
{ {
} }
@ -1299,7 +1304,7 @@ shared_ptr<Output> OutputFormat::create_output(
Output::Output(shared_ptr<OutputFormat> format, Output::Output(shared_ptr<OutputFormat> format,
shared_ptr<Device> device, map<string, Glib::VariantBase> options) : shared_ptr<Device> device, map<string, Glib::VariantBase> options) :
structure(sr_output_new(format->structure, UserOwned(sr_output_new(format->structure,
map_to_hash_variant(options), device->structure)), map_to_hash_variant(options), device->structure)),
format(format), device(device), options(options) format(format), device(device), options(options)
{ {

View File

@ -192,11 +192,32 @@ protected:
} }
}; };
/* Base template for classes whose resources are owned by the user. */
template <class Class, typename Struct>
class SR_API UserOwned : public enable_shared_from_this<Class>
{
public:
shared_ptr<Class> shared_from_this()
{
auto shared = enable_shared_from_this<Class>::shared_from_this();
if (!shared)
throw Error(SR_ERR_BUG);
return shared;
}
protected:
Struct *structure;
UserOwned<Class, Struct>(Struct *structure) :
structure(structure)
{
}
};
/** Type of log callback */ /** Type of log callback */
typedef function<void(const LogLevel *, string message)> LogCallbackFunction; typedef function<void(const LogLevel *, string message)> LogCallbackFunction;
/** The global libsigrok context */ /** The global libsigrok context */
class SR_API Context : public enable_shared_from_this<Context> class SR_API Context : public UserOwned<Context, struct sr_context>
{ {
public: public:
/** Create new context */ /** Create new context */
@ -241,7 +262,6 @@ public:
* @param header Initial data from stream. */ * @param header Initial data from stream. */
shared_ptr<Input> open_stream(string header); shared_ptr<Input> open_stream(string header);
protected: protected:
struct sr_context *structure;
map<string, Driver *> drivers; map<string, Driver *> drivers;
map<string, InputFormat *> input_formats; map<string, InputFormat *> input_formats;
map<string, OutputFormat *> output_formats; map<string, OutputFormat *> output_formats;
@ -414,7 +434,7 @@ protected:
}; };
/** A trigger configuration */ /** A trigger configuration */
class SR_API Trigger : public enable_shared_from_this<Trigger> class SR_API Trigger : public UserOwned<Trigger, struct sr_trigger>
{ {
public: public:
/** Name of this trigger configuration. */ /** Name of this trigger configuration. */
@ -426,7 +446,6 @@ public:
protected: protected:
Trigger(shared_ptr<Context> context, string name); Trigger(shared_ptr<Context> context, string name);
~Trigger(); ~Trigger();
struct sr_trigger *structure;
shared_ptr<Context> context; shared_ptr<Context> context;
vector<TriggerStage *> stages; vector<TriggerStage *> stages;
/** Deleter needed to allow shared_ptr use with protected destructor. */ /** Deleter needed to allow shared_ptr use with protected destructor. */
@ -566,7 +585,7 @@ protected:
}; };
/** A sigrok session */ /** A sigrok session */
class SR_API Session class SR_API Session : public UserOwned<Session, struct sr_session>
{ {
public: public:
/** Add a device to this session. /** Add a device to this session.
@ -610,7 +629,6 @@ protected:
Session(shared_ptr<Context> context); Session(shared_ptr<Context> context);
Session(shared_ptr<Context> context, string filename); Session(shared_ptr<Context> context, string filename);
~Session(); ~Session();
struct sr_session *structure;
const shared_ptr<Context> context; const shared_ptr<Context> context;
map<const struct sr_dev_inst *, shared_ptr<Device> > devices; map<const struct sr_dev_inst *, shared_ptr<Device> > devices;
vector<DatafeedCallbackData *> datafeed_callbacks; vector<DatafeedCallbackData *> datafeed_callbacks;
@ -632,7 +650,7 @@ protected:
}; };
/** A packet on the session datafeed */ /** A packet on the session datafeed */
class SR_API Packet : public enable_shared_from_this<Packet> class SR_API Packet : public UserOwned<Packet, const struct sr_datafeed_packet>
{ {
public: public:
/** Type of this packet. */ /** Type of this packet. */
@ -643,7 +661,6 @@ protected:
Packet(shared_ptr<Device> device, Packet(shared_ptr<Device> device,
const struct sr_datafeed_packet *structure); const struct sr_datafeed_packet *structure);
~Packet(); ~Packet();
const struct sr_datafeed_packet *structure;
shared_ptr<Device> device; shared_ptr<Device> device;
PacketPayload *payload; PacketPayload *payload;
/** Deleter needed to allow shared_ptr use with protected destructor. */ /** Deleter needed to allow shared_ptr use with protected destructor. */
@ -779,7 +796,7 @@ protected:
}; };
/** An input instance (an input format applied to a file or stream) */ /** An input instance (an input format applied to a file or stream) */
class SR_API Input : public enable_shared_from_this<Input> class SR_API Input : public UserOwned<Input, const struct sr_input>
{ {
public: public:
/** Virtual device associated with this input. */ /** Virtual device associated with this input. */
@ -790,7 +807,6 @@ public:
protected: protected:
Input(shared_ptr<Context> context, const struct sr_input *structure); Input(shared_ptr<Context> context, const struct sr_input *structure);
~Input(); ~Input();
const struct sr_input *structure;
shared_ptr<Context> context; shared_ptr<Context> context;
InputDevice *device; InputDevice *device;
/** Deleter needed to allow shared_ptr use with protected destructor. */ /** Deleter needed to allow shared_ptr use with protected destructor. */
@ -825,7 +841,7 @@ protected:
}; };
/** An option used by an output format */ /** An option used by an output format */
class SR_API Option class SR_API Option : public UserOwned<Option, const struct sr_option>
{ {
public: public:
/** Short name of this option suitable for command line usage. */ /** Short name of this option suitable for command line usage. */
@ -842,7 +858,6 @@ protected:
Option(const struct sr_option *structure, Option(const struct sr_option *structure,
shared_ptr<const struct sr_option *> structure_array); shared_ptr<const struct sr_option *> structure_array);
~Option(); ~Option();
const struct sr_option *structure;
shared_ptr<const struct sr_option *> structure_array; shared_ptr<const struct sr_option *> structure_array;
/** Deleter needed to allow shared_ptr use with protected destructor. */ /** Deleter needed to allow shared_ptr use with protected destructor. */
class Deleter class Deleter
@ -879,7 +894,7 @@ protected:
}; };
/** An output instance (an output format applied to a device) */ /** An output instance (an output format applied to a device) */
class SR_API Output class SR_API Output : public UserOwned<Output, const struct sr_output>
{ {
public: public:
/** Update output with data from the given packet. /** Update output with data from the given packet.
@ -890,7 +905,6 @@ protected:
Output(shared_ptr<OutputFormat> format, Output(shared_ptr<OutputFormat> format,
shared_ptr<Device> device, map<string, Glib::VariantBase> options); shared_ptr<Device> device, map<string, Glib::VariantBase> options);
~Output(); ~Output();
const struct sr_output *structure;
const shared_ptr<OutputFormat> format; const shared_ptr<OutputFormat> format;
const shared_ptr<Device> device; const shared_ptr<Device> device;
const map<string, Glib::VariantBase> options; const map<string, Glib::VariantBase> options;