HawkTracer
0.10.0
|
In this tutorial we will learn how to extend timeline capabilities by defining custom timeline features.
We recommend you to go through the Tutorial: Hello world! tutorial to make sure you have the HawkTracer library properly installed.
We'd like to know how many events we pushed to a specific timeline object.
Please copy the text below to a files named hawktracer-custom-timeline-feature.c
, push-counter-feature.c
and push-counter-feature.h
(you can find those files in the repository as well).
hawktracer-custom-timeline-feature.c
push-counter-feature.h
push-counter-feature.c
We assume you already went through the Tutorial: Hello world! tutorial, so we only focus here on the new part.
We start with defining the feature.
First, we define the structure that holds all the required information about the feature. We agreed that we want to count number of events being pushed to a timeline, therefore we need a counter
field. All the features must inherit from HT_Feature
class, so we need to create base
field of this type as a first one in the structure.
HT_FEATURE_DEFINE() is a helper macro that defines a few helper methods which we use in the implementation. It takes struct name and destroy callback.
We'd like the feature to be easily accessible to our users (including ourselves), so we define push_counter_feature_enable()
that will be used to enable the feature for a specific timeline. As enabling feature might fail because of many reasons, we return HT_ErrorCode to inform our users about exact problem.
We allocate an instance of the object using PushCounterFeature_alloc()
method - the method was auto-generated by HT_FEATURE_DEFINE(). It allocates memory (using ht_alloc()) but also initializes the base
field of the structure. If you want to use allocation method different than ht_alloc(), you need to make sure that you initialize the structure on your own.
Allocating the feature might fail, so we need to handle this scenario correctly.
We need to initialize the data structure. In our case, it means reseting the counter value.
When the feature is initialized, we can attach it to the timeline, using ht_timeline_set_feature. From now on, the timeline manages the memory of the feature (even if the function doesn't complete successfully, it will still release the feature).
We also need to define a method for destroying the feature. As mentioned above, by default HawkTracer uses ht_alloc() method for allocating the memory for the object, therefore we use ht_free() for releasing it. If the feature object allocated additional resources, the method is a right place to release them.
We defined the feature, but without the logic implemented for the feature, it's kind of useless.
We'll define a method which will push an event to a timeline, and at the same time increase the counter of the feature.
Please note we don't pass the feature as an argument to the function. In order to get it, HT_DEFINE_FEATURE() generates PushCounterFeature_from_timeline()
function that gets the feature from the timeline.
The timeline being passed to the function might not have this feature enabled, so we need to check that before executing the logic.
This is the actual logic of the feature - we push the event to the timeline, and increment the counter.
We also define a simple method for returning the counter to the user.
In the previous paragraph we defined the feature. Now, we need to expose an interface to the user so she can use it in her code.
Apart from the three methods we defined in the previous paragraph, there's one extra method we expose to users: HT_ErrorCode PushCounterFeature_register()
- we didn't implement the function, but it was auto-generated by HT_DEFINE_FEATURE(). The feature must be registered before usage, so we need to expose the function so she can register it at any time in her code.
### Using the feature in the code
Before we start, the feature must be registered. The function should be called after ht_init(), but before any usage of the feature.
We enable the feature for the timeline. We defined a nice function that wraps all the initializations, so our user needs to call only one function to attach the feature to the timeline.
Instead of using ht_timeline_push_event() function, we use function defined for our feature, so we can keep track of number of events being pushed to the timeline.
At the end of the program we print the count, so we now how many events we pushed to the timeline.
There's no need for destroying the feature - timeline destructor takes care of releasing the object by calling push_counter_feature_destroy()
function.
After running the program, you should see the following output on the screen: