Friday, January 30, 2009

boilerplate

When I read a blog about boilerplate in Qt, I tried to remember how to write boilerplate code with Gobject. The following code is a frame that I took from 1 year ago I wrote. It is not really hard to understand or write, just need to copy & paste, or use simple tool to auto generate the code. It always need to write more lines in C (GObject) than using C++ for OO. But I don't feel the goodness. I am not feel that is the benifit of C, so I am not sure OO is really good for a Unix developer, so if I can avoid I would avoid the idea of OO in unix platform. (Linux Kernel is not written in OO)


/* macros*/
G_BEGIN_DECLS

#define GST_TYPE_MIDISRC (gst_my_midisrc_get_type())
#define GST_MIDISRC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_MIDISRC,GstMidisrc))
#define GST_MIDISRC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_MIDISRC,GstMidisrcClass))
#define GST_IS_MIDISRC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_MIDISRC))
#define GST_IS_MIDISRC_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_MIDISRC))

/* standard function returning type information */
GType gst_my_midisrc_get_type (void);


/* definition a class of this element */
typedef struct _GstMidisrc GstMidisrc;
struct _GstMidisrc
{
GstBaseSrc parent;
[...]
};

typedef struct _GstMidisrcClass GstMidisrcClass;

struct _GstMidisrcClass
{
GstBaseSrcClass parent_class;
};

G_END_DECLS


Now we can make the boilerplate:

GST_BOILERPLATE (GstMidisrc, gst_my_midisrc, GstBaseSrc, GST_TYPE_BASE_SRC);


After that is the element details.


static GstElementDetails midisrc_details = {
"A Gstreamer Plug-in",
"Src/Audio",
"audio src for GStreamer Plug-in",
""
};

/* set detail with _base_init function when register the plugin */
static void
gst_my_midisrc_base_init (gpointer klass)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);

gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&src_factory));

gst_element_class_set_details (element_class, &midisrc_details);

}


Then implementation:



/* create the class, here we define which function need to be re-implmented from the base class, and add property for the class */
static void
gst_my_midisrc_class_init (GstMidisrcClass *klass)
{

GObjectClass *gobject_class;
GstBaseSrcClass *basesrc_class;
gobject_class = G_OBJECT_CLASS (klass);
basesrc_class = GST_BASE_SRC_CLASS (klass);
gobject_class->set_property = gst_midisrc_set_property;
gobject_class->get_property = gst_midisrc_get_property;


/* basesrc_class->get_caps = gst_midisrc_get_caps;
basesrc_class->set_caps = gst_midisrc_set_caps; */
basesrc_class->start = gst_midisrc_start;
basesrc_class->stop = gst_midisrc_stop;
basesrc_class->create = gst_midisrc_create;

/* install a property for the class as an example */
g_object_class_install_property (
gobject_class, ARG_LOCATION,
g_param_spec_string ("location", "File Location",
"Location of the file to read", NULL, G_PARAM_READWRITE));



}

/* create the object */
static void
gst_my_midisrc_init (GstMidisrc *midisrc, GstMidisrcClass *klass)
{
[...]
}



Now the reset part:


/* set property sample */
static gboolean
gst_midisrc_set_location (GstMidisrc * src, const gchar * location)
{
/* the element must be stopped in order to do this */
GST_STATE_LOCK (src);
{
GstState state;

state = GST_STATE (src);
if (state != GST_STATE_READY && state != GST_STATE_NULL)
goto wrong_state;
}
GST_STATE_UNLOCK (src);

g_free (src->filename);
g_free (src->uri);

/* clear the filename if we get a NULL (is that possible?) */
if (location == NULL) {
src->filename = NULL;
src->uri = NULL;
} else {
src->filename = g_strdup (location);
}
return TRUE;

/* ERROR */
wrong_state:
{
GST_DEBUG_OBJECT (src, "setting location in wrong state");
GST_STATE_UNLOCK (src);
return FALSE;
}
}
static void
gst_midisrc_set_property (GObject * object,
guint prop_id, const GValue * value, GParamSpec * pspec)
{
GstMidisrc *midisrc;
int tmp = 0;
g_return_if_fail (GST_IS_MIDISRC (object));
midisrc = GST_MIDISRC (object);

switch (prop_id) {
case ARG_LOCATION:
gst_midisrc_set_location(midisrc, g_value_get_string (value));
printf("set location done!\n");
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}

static void
gst_midisrc_get_property (GObject * object,
guint prop_id, GValue * value, GParamSpec * pspec)
{
GstMidisrc *midisrc;

g_return_if_fail (GST_IS_MIDISRC (object));
midisrc = GST_MIDISRC (object);

switch (prop_id) {
case ARG_LOCATION:
g_value_set_string(value, midisrc->filename);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}

static gboolean
gst_midisrc_start (GstBaseSrc * src)
{
GstMidisrc *midisrc = GST_MIDISRC (src);
[...]
}

static GstFlowReturn
gst_midisrc_create (GstBaseSrc * src,
guint64 offset,
guint length,
GstBuffer ** buffer)
{
GstMidisrc *midisrc = GST_MIDISRC (src);
if (midisrc->eos_reached)
return GST_FLOW_UNEXPECTED;
return( gst_midisrc_get_read (src, buffer));
}

static GstFlowReturn
gst_midisrc_get_read (GstBaseSrc * basesrc, GstBuffer ** buffer)
{
GstFlowReturn res;
GstMidisrc *midisrc = GST_MIDISRC (basesrc);
[...]

[...]
}


I would like to put my time on learning Git (I was heard git is written by a Unix kernal developer), for desktops, such as gnome or KDE I don't have a lot of interests, I may feel KDE is better since it is written in C++, but who knows.

Wednesday, January 21, 2009

smb4k on Ubuntu

smb4k does not work well on Ubuntu, but it is Ok with Fedora. When I try to mount my Windows share folder, I get this error:

smbmnt must be installed suid root for direct user mount.


I use google to know how to fix. Here is the command:

$ sudo chmod u+s `which smbmnt`
$ sudo chmod u+s `which smbumount`

Tuesday, January 20, 2009

create a patch with cvs

Here is the command from a Linux shell:

$ cvs diff -u8pN /path/foo > markc_20090120.patch

Monday, January 19, 2009

0 Usually I use this blog to take notes on computer programming, and there's not really my thoughts. I would change this style and use the blog to write more my thoughts.

1 Last Friday, my wife and I went to TD bank to sign our new house mortgage paper. Our new house mortgage is $1400 CAD/month, compared to our current town house $600CAD (mortgage) + $200 (condo fees). What a difference! Our current living is convenient, just not luxury. The community is not very good but at least safe. We will move to Kincore in the north west, is it really make a difference? But the pressure in finance is some thing that I started to feel, we currently use the money in three ways. First, the living cost (house mortgage & condo fees, cost for two cars, food & electricity & water & gas etc). Second, some money to my parents in China although they don't need it (the money just gave them some more security feelings). Third, money donated to the monastery or other charity. Now I am starting to think do I have enough money for donation or support my parents? we need to calculate to make the balance.

2 Last Sunday, I did not get up early to go to the monastery for the morning ceremony at 8:00. Instead, I stayed in the bed for resting --. And I decide not go to monastery the day. Now I feel that was a good decision. In the afternoon, we went to the zoo for several hours. The weather was very good with sun shine that we did not feel cold wind, the snow is melting. The boy was happy to see the animals again, and we had really a good time to stay as a family that all of us enjoyed. I think spending the time with family is somewhat better than going to the monastery chanting and bowing to the Buddha & Bodhisattva. The goal is to get rid of the hatred/greed/desire etc in mind no matter what methods to choose.

Thursday, January 15, 2009

Do you remember when?

As a programmer, I have passed my mid of thirties, so I can not be called "young" at this age. As a programmer, am I success or do I feel I was success? I am not quite sure, it is just a career that I've took for the past 13 years. 13 years, that's a long time, I don't have anything that I can be very pride of, (am I not talented or blessed) but I do have a lot of experience and programming skills. Now, I spend more my personal time on Buddhist meditation, I am more consider myself as a Buddhist than a programmer. But to be a programmer, I know I should spent some of my personal time on programming.

I am not cheer up as a programmer right now. The economy or the immigrant life is some reasons. But my attitude need to flesh up, and I need to do some replaning to take the charge of on my programming career.

I like the following video:


A programmer works on beauty of code.
A gymnast works on beauty of body.
A Buddhist works on beauty of mind.
All takes hard work!