From d8743d20b93d34497183d05ccb17519194ec5abb Mon Sep 17 00:00:00 2001 From: Matthias Vogelgesang Date: Tue, 16 Oct 2012 12:27:47 +0200 Subject: Integrate initial unit facility --- src/uca-camera.c | 140 +++++++++++++++++++++++++++++++++++++++++++++---------- src/uca-camera.h | 18 ++++++- test/test-mock.c | 8 ++++ 3 files changed, 140 insertions(+), 26 deletions(-) diff --git a/src/uca-camera.c b/src/uca-camera.c index 091ef54..2cf17ff 100644 --- a/src/uca-camera.c +++ b/src/uca-camera.c @@ -50,7 +50,25 @@ G_DEFINE_TYPE(UcaCamera, uca_camera, G_TYPE_OBJECT) */ GQuark uca_camera_error_quark() { - return g_quark_from_static_string("uca-camera-error-quark"); + return g_quark_from_static_string ("uca-camera-error-quark"); +} + +/** + * UcaUnit: + * @UCA_UNIT_NA: Not applicable + * @UCA_UNIT_METER: SI meter + * @UCA_UNIT_SECOND: SI second + * @UCA_UNIT_PIXEL: Number of pixels in one dimension + * @UCA_UNIT_COUNT: Number + * + * Units should be registered by camera implementations using + * uca_camera_register_unit() and can be queried by client programs with + * uca_camera_get_unit(). + */ + +GQuark uca_unit_quark () +{ + return g_quark_from_static_string ("uca-unit-quark"); } enum { @@ -96,6 +114,12 @@ struct _UcaCameraPrivate { gboolean transfer_async; }; +static void +uca_camera_set_property_unit (GParamSpec *pspec, UcaUnit unit) +{ + g_param_spec_set_qdata (pspec, UCA_UNIT_QUARK, GINT_TO_POINTER (unit)); +} + static void uca_camera_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { @@ -149,7 +173,7 @@ uca_camera_get_property(GObject *object, guint property_id, GValue *value, GPara case PROP_FRAMES_PER_SECOND: { - gdouble exposure_time; + gdouble exposure_time; g_object_get (object, "exposure-time", &exposure_time, NULL); g_value_set_double (value, 1. / exposure_time); @@ -162,11 +186,18 @@ uca_camera_get_property(GObject *object, guint property_id, GValue *value, GPara } static void -uca_camera_class_init(UcaCameraClass *klass) +uca_camera_finalize (GObject *object) +{ + G_OBJECT_CLASS (uca_camera_parent_class)->finalize (object); +} + +static void +uca_camera_class_init (UcaCameraClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS(klass); gobject_class->set_property = uca_camera_set_property; gobject_class->get_property = uca_camera_get_property; + gobject_class->finalize = uca_camera_finalize; klass->start_recording = NULL; klass->stop_recording = NULL; @@ -342,7 +373,7 @@ uca_camera_class_init(UcaCameraClass *klass) } static void -uca_camera_init(UcaCamera *camera) +uca_camera_init (UcaCamera *camera) { camera->grab_func = NULL; @@ -351,26 +382,20 @@ uca_camera_init(UcaCamera *camera) camera->priv->is_readout = FALSE; camera->priv->transfer_async = FALSE; - /* - * This here would be the best place to instantiate the tango server object, - * along these lines: - * - * // I'd prefer if you expose a single C method, so we don't have to - * // compile uca-camera.c with g++ - * tango_handle = tango_server_new(camera); - * - * void tango_server_new(UcaCamera *camera) - * { - * // Do whatever is necessary. In the end you will have some kind of - * // Tango object t which needs to somehow hook up to the properties. A - * // list of all available properties can be enumerated with - * // g_object_class_list_properties(G_OBJECT_CLASS(camera), - * // &n_properties); - * - * // For setting/getting properties, use g_object_get/set_property() or - * // g_object_get/set() whatever is more suitable. - * } - */ + uca_camera_set_property_unit (camera_properties[PROP_SENSOR_WIDTH], UCA_UNIT_PIXEL); + uca_camera_set_property_unit (camera_properties[PROP_SENSOR_HEIGHT], UCA_UNIT_PIXEL); + uca_camera_set_property_unit (camera_properties[PROP_SENSOR_BITDEPTH], UCA_UNIT_COUNT); + uca_camera_set_property_unit (camera_properties[PROP_SENSOR_HORIZONTAL_BINNING], UCA_UNIT_PIXEL); + uca_camera_set_property_unit (camera_properties[PROP_SENSOR_VERTICAL_BINNING], UCA_UNIT_PIXEL); + uca_camera_set_property_unit (camera_properties[PROP_SENSOR_MAX_FRAME_RATE], UCA_UNIT_COUNT); + uca_camera_set_property_unit (camera_properties[PROP_EXPOSURE_TIME], UCA_UNIT_SECOND); + uca_camera_set_property_unit (camera_properties[PROP_FRAMES_PER_SECOND], UCA_UNIT_COUNT); + uca_camera_set_property_unit (camera_properties[PROP_ROI_X], UCA_UNIT_PIXEL); + uca_camera_set_property_unit (camera_properties[PROP_ROI_Y], UCA_UNIT_PIXEL); + uca_camera_set_property_unit (camera_properties[PROP_ROI_WIDTH], UCA_UNIT_PIXEL); + uca_camera_set_property_unit (camera_properties[PROP_ROI_HEIGHT], UCA_UNIT_PIXEL); + uca_camera_set_property_unit (camera_properties[PROP_ROI_WIDTH_MULTIPLIER], UCA_UNIT_COUNT); + uca_camera_set_property_unit (camera_properties[PROP_ROI_HEIGHT_MULTIPLIER], UCA_UNIT_COUNT); } /** @@ -523,7 +548,8 @@ uca_camera_start_readout (UcaCamera *camera, GError **error) * * Set the grab function that is called whenever a frame is readily transfered. */ -void uca_camera_set_grab_func(UcaCamera *camera, UcaCameraGrabFunc func, gpointer user_data) +void +uca_camera_set_grab_func(UcaCamera *camera, UcaCameraGrabFunc func, gpointer user_data) { camera->grab_func = func; camera->user_data = user_data; @@ -600,3 +626,67 @@ uca_camera_grab (UcaCamera *camera, gpointer *data, GError **error) g_static_mutex_unlock (&mutex); } +/** + * uca_camera_register_unit: + * @camera: A #UcaCamera object + * @prop_name: Name of a property + * @unit: #UcaUnit + * + * Associates @prop_name of @camera with a specific @unit. + * + * Since: 1.1 + */ +void +uca_camera_register_unit (UcaCamera *camera, + const gchar *prop_name, + UcaUnit unit) +{ + UcaCameraClass *klass; + GObjectClass *oclass; + GParamSpec *pspec; + + klass = UCA_CAMERA_GET_CLASS (camera); + oclass = G_OBJECT_CLASS (klass); + pspec = g_object_class_find_property (oclass, prop_name); + + if (pspec == NULL) { + g_warning ("Camera does not have property `%s'", prop_name); + return; + } + + uca_camera_set_property_unit (pspec, unit); +} + +/** + * uca_camera_get_unit: + * @camera: A #UcaCamera object + * @prop_name: Name of a property + * + * Returns the unit associated with @prop_name of @camera. + * + * Returns: A #UcaUnit value associated with @prop_name. If there is none, the + * value will be #UCA_UNIT_NA. + * Since: 1.1 + */ +UcaUnit +uca_camera_get_unit (UcaCamera *camera, + const gchar *prop_name) +{ + UcaCameraClass *klass; + GObjectClass *oclass; + GParamSpec *pspec; + gpointer data; + + klass = UCA_CAMERA_GET_CLASS (camera); + oclass = G_OBJECT_CLASS (klass); + pspec = g_object_class_find_property (oclass, prop_name); + + if (pspec == NULL) { + g_warning ("Camera does not have property `%s'", prop_name); + return UCA_UNIT_NA; + } + + data = g_param_spec_get_qdata (pspec, UCA_UNIT_QUARK); + return data == NULL ? UCA_UNIT_NA : GPOINTER_TO_INT (data); +} + diff --git a/src/uca-camera.h b/src/uca-camera.h index 8bc48bc..4aad0b4 100644 --- a/src/uca-camera.h +++ b/src/uca-camera.h @@ -29,8 +29,11 @@ G_BEGIN_DECLS #define UCA_IS_CAMERA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), UCA_TYPE_CAMERA)) #define UCA_CAMERA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), UCA_TYPE_CAMERA, UcaCameraClass)) -#define UCA_CAMERA_ERROR uca_camera_error_quark() +#define UCA_CAMERA_ERROR uca_camera_error_quark() +#define UCA_UNIT_QUARK uca_unit_quark() + GQuark uca_camera_error_quark(void); +GQuark uca_unit_quark(void); typedef enum { UCA_CAMERA_ERROR_NOT_FOUND, @@ -46,6 +49,14 @@ typedef enum { UCA_CAMERA_TRIGGER_EXTERNAL } UcaCameraTrigger; +typedef enum { + UCA_UNIT_NA, + UCA_UNIT_METER, + UCA_UNIT_SECOND, + UCA_UNIT_PIXEL, + UCA_UNIT_COUNT +} UcaUnit; + typedef struct _UcaCamera UcaCamera; typedef struct _UcaCameraClass UcaCameraClass; typedef struct _UcaCameraPrivate UcaCameraPrivate; @@ -136,6 +147,11 @@ void uca_camera_grab (UcaCamera *camera, void uca_camera_set_grab_func (UcaCamera *camera, UcaCameraGrabFunc func, gpointer user_data); +void uca_camera_register_unit (UcaCamera *camera, + const gchar *prop_name, + UcaUnit unit); +UcaUnit uca_camera_get_unit (UcaCamera *camera, + const gchar *prop_name); GType uca_camera_get_type(void); diff --git a/test/test-mock.c b/test/test-mock.c index 17af329..08f24b8 100644 --- a/test/test-mock.c +++ b/test/test-mock.c @@ -168,6 +168,13 @@ test_fps_property (Fixture *fixture, gconstpointer data) g_assert_cmpfloat (frames_per_second, ==, 1.0 / exposure_time); } +static void +test_property_units (Fixture *fixture, gconstpointer data) +{ + g_assert (uca_camera_get_unit (fixture->camera, "sensor-width") == UCA_UNIT_PIXEL); + g_assert (uca_camera_get_unit (fixture->camera, "name") == UCA_UNIT_NA); +} + static void test_binnings_properties (Fixture *fixture, gconstpointer data) { @@ -210,6 +217,7 @@ int main (int argc, char *argv[]) g_test_add ("/properties/recording", Fixture, NULL, fixture_setup, test_recording_property, fixture_teardown); g_test_add ("/properties/binnings", Fixture, NULL, fixture_setup, test_binnings_properties, fixture_teardown); g_test_add ("/properties/frames-per-second", Fixture, NULL, fixture_setup, test_fps_property, fixture_teardown); + g_test_add ("/properties/units", Fixture, NULL, fixture_setup, test_property_units, fixture_teardown); g_test_add ("/signal", Fixture, NULL, fixture_setup, test_signal, fixture_teardown); return g_test_run (); -- cgit v1.2.3