Browse Source

Fix memory errors, improve enum. impl.

Fredrik Svantesson 5 years ago
parent
commit
c4aab0c3ac
4 changed files with 159 additions and 239 deletions
  1. 10
    67
      DOCUMENTATION.md
  2. 21
    98
      src/impl/sysfs.c
  3. 118
    70
      src/light.c
  4. 10
    4
      src/light.h

+ 10
- 67
DOCUMENTATION.md View File

113
 
113
 
114
 In the sourcefile, you need to implement the 6 methods. Make sure to return `true` on success and `false` on failure. If you do not actually implement a function (for example `impl_foo_command`), just return `true`.
114
 In the sourcefile, you need to implement the 6 methods. Make sure to return `true` on success and `false` on failure. If you do not actually implement a function (for example `impl_foo_command`), just return `true`.
115
 
115
 
116
-The job of the enumerator is to identify/enumerate a bunch of different devices (or just one, or even zero if it doesnt find any). You are also responsible to create the device targets for them (i.e, the things that you actually write to on the device). You do this by setting the devices and targets up in `impl_foo_init` and to free these in `impl_foo_free`. The enumerator (this code) owns the memory of the devices and targets, and thus is in charge of allocating and freeing it. 
116
+The job of the enumerator is to identify/enumerate a bunch of different devices (or just one, or even zero if it doesnt find any). You are also responsible to create the device targets for them (i.e, the things that you actually write to on the device). You do this by setting the devices and targets up in `impl_foo_init`. You are not required to do anything in `impl_foo_free`, any allocated memory will be automatically free'd by light, including device/target data that you allocate yourself. You may use `impl_foo_free` to free resources you allocate outside of the light API.
117
 
117
 
118
 ```c
118
 ```c
119
 
119
 
126
 {
126
 {
127
     /* Lets create a single device, with a single target, for simplicity */
127
     /* Lets create a single device, with a single target, for simplicity */
128
     
128
     
129
-    /* Allocate a new device */
130
-    light_device_t *new_device = malloc(sizeof(light_device_t));
129
+    /* Create a new device called new_device_name, we dont need any userdata so pass NULL to the device_data parameter */
130
+    light_device_t *new_device = light_create_device(enumerator, "new_device_name", NULL)
131
     
131
     
132
-    /* Set the name of the new device to "new_device_name" */
133
-    snprintf(leds_device->name, sizeof(leds_device->name), "%s", "new_device_name");
134
-    
135
-    /* Add the newly created device to the enumerator */
136
-    light_add_enumerator_device(enumerator, new_device);
137
-
138
-    
139
-    
140
-    /* Allocate a new device target for the newly created device */
141
-    light_device_target_t *new_target = malloc(sizeof(light_device_target_t));
142
-    
143
-    /* Set the name of the new target */
144
-    snprintf(new_target->name, sizeof(new_target->name), "%s", "new_target_name");
145
-    
146
-    /* Setup the function bindings for this target, i.e. what functions will run internally when you run different commands on this device target */
147
-    new_target->set_value = impl_foo_set;
148
-    new_target->get_value = impl_foo_get;
149
-    new_target->get_max_value = impl_foo_getmax;
150
-    new_target->custom_command = impl_foo_command;
151
-    
152
-    /* Finally add the target to the device */
153
-    light_add_device_target(new_device, new_target);
154
-    
155
-    
156
-    
157
-    /* Optional: Setup data specific to either a device or a target, or both. */ 
132
+    /* Setup userdata specific to the target we will create*/ 
158
     /* Useful to for example reference an ID in a third-party API or likewise */
133
     /* Useful to for example reference an ID in a third-party API or likewise */
134
+    /* NOTE: The userdata will be free()'d automatically on exit, so you do not need to free it yourself */
159
     impl_foo_data_t *custom_data = malloc(sizeof(impl_foo_data_t));
135
     impl_foo_data_t *custom_data = malloc(sizeof(impl_foo_data_t));
160
     custom_data->internal_quack_id = 333;
136
     custom_data->internal_quack_id = 333;
161
     
137
     
162
-    /* You can set it to the device itself, or to a target */
163
-    new_device->device_data = custom_data;
164
-    new_target->device_target_data = custom_data;
165
-
138
+    
139
+    /* Create a new device target called new_target_name, and pass in the functions and userdata that we just allocated */
140
+    light_create_device_target(new_device, "new_target_name", impl_foo_set, impl_foo_get, impl_foo_getmax, impl_foo_command, custom_data)
141
+    
166
     /* Return true because we didnt get any errors! */
142
     /* Return true because we didnt get any errors! */
167
     return true;
143
     return true;
168
 }
144
 }
169
 
145
 
170
 bool impl_foo_free(light_device_enumerator_t *enumerator)
146
 bool impl_foo_free(light_device_enumerator_t *enumerator)
171
 {
147
 {
172
-    /* We are responsible to free the memory we allocated in init, so lets do that */
173
-    
174
-    /* Iterate through the devices in the enumerator */
175
-    for(uint64_t d = 0; d < enumerator->num_devices; d++)
176
-    {
177
-        light_device_t *curr_device = enumerator->devices[d];
178
-
179
-        /* Iterate throug hthe targets in the device */
180
-        for(uint64_t t = 0; t < curr_device->num_targets; t++)
181
-        {
182
-            light_device_target_t *curr_target = curr_device->targets[t];
183
-            
184
-            /* If we allocated any target data, free it here */
185
-            if(curr_target->device_target_data != NULL)
186
-            {
187
-                free(curr_target->device_target_data);
188
-            }
189
-            
190
-            free(curr_target);
191
-        }
192
-
193
-        /* If we allocated any device data, free it here */
194
-        if(curr_device->device_data != NULL)
195
-        {
196
-            free(curr_device->device_data);
197
-        }
198
-        
199
-        /* We need to 'dispose' of the device when we are done with it, to free some internal memory. Always do this when you are about to free a device that you allocated. */
200
-        light_dispose_device(curr_device);
201
-        
202
-        /* Free the device */
203
-        free(curr_device);
204
-    }
205
-    
148
+    /* We dont need to do anything here, but if we want to, we can free some third-party API resources */
206
     return true;
149
     return true;
207
 }
150
 }
208
 
151
 

+ 21
- 98
src/impl/sysfs.c View File

10
 static bool _impl_sysfs_init_leds(light_device_enumerator_t *enumerator)
10
 static bool _impl_sysfs_init_leds(light_device_enumerator_t *enumerator)
11
 {
11
 {
12
     // Create a new backlight device
12
     // Create a new backlight device
13
-    light_device_t *leds_device = malloc(sizeof(light_device_t));
14
-    snprintf(leds_device->name, sizeof(leds_device->name), "%s", "leds");
15
-    
16
-    // Add it to the enumerator 
17
-    light_add_enumerator_device(enumerator, leds_device);
18
-    
13
+    light_device_t *leds_device = light_create_device(enumerator, "leds", NULL);
14
+
19
     // Iterate through the led controllers and create a device_target for each controller 
15
     // Iterate through the led controllers and create a device_target for each controller 
20
     DIR *leds_dir;
16
     DIR *leds_dir;
21
     struct dirent *curr_entry;
17
     struct dirent *curr_entry;
34
             continue;
30
             continue;
35
         }
31
         }
36
         
32
         
37
-        // Create a new device target for the controller 
38
-        light_device_target_t *led_controller = malloc(sizeof(light_device_target_t));
39
-        snprintf(led_controller->name, sizeof(led_controller->name), "%s", curr_entry->d_name);
40
-        
41
-        // Setup the function bindings
42
-        led_controller->set_value = impl_sysfs_set;
43
-        led_controller->get_value = impl_sysfs_get;
44
-        led_controller->get_max_value = impl_sysfs_getmax;
45
-        led_controller->custom_command = impl_sysfs_command;
46
-        
47
         // Setup the target data 
33
         // Setup the target data 
48
         impl_sysfs_data_t *dev_data = malloc(sizeof(impl_sysfs_data_t));
34
         impl_sysfs_data_t *dev_data = malloc(sizeof(impl_sysfs_data_t));
49
-        led_controller->device_target_data = dev_data;
50
         snprintf(dev_data->brightness, sizeof(dev_data->brightness), "/sys/class/leds/%s/brightness", curr_entry->d_name);
35
         snprintf(dev_data->brightness, sizeof(dev_data->brightness), "/sys/class/leds/%s/brightness", curr_entry->d_name);
51
         snprintf(dev_data->max_brightness, sizeof(dev_data->max_brightness), "/sys/class/leds/%s/max_brightness", curr_entry->d_name);
36
         snprintf(dev_data->max_brightness, sizeof(dev_data->max_brightness), "/sys/class/leds/%s/max_brightness", curr_entry->d_name);
52
         
37
         
53
-        // Add it to the device
54
-        light_add_device_target(leds_device, led_controller);
38
+        // Create a new device target for the controller 
39
+        light_create_device_target(leds_device, curr_entry->d_name, impl_sysfs_set, impl_sysfs_get, impl_sysfs_getmax, impl_sysfs_command, dev_data);
55
     }
40
     }
56
     
41
     
57
     closedir(leds_dir);
42
     closedir(leds_dir);
62
 static bool _impl_sysfs_init_backlight(light_device_enumerator_t *enumerator)
47
 static bool _impl_sysfs_init_backlight(light_device_enumerator_t *enumerator)
63
 {
48
 {
64
     // Create a new backlight device
49
     // Create a new backlight device
65
-    light_device_t *backlight_device = malloc(sizeof(light_device_t));
66
-    snprintf(backlight_device->name, sizeof(backlight_device->name), "%s", "backlight");
67
-    
68
-    // Add it to the enumerator 
69
-    light_add_enumerator_device(enumerator, backlight_device);
70
-    
50
+    light_device_t *backlight_device = light_create_device(enumerator, "backlight", NULL);
51
+
71
     // Iterate through the backlight controllers and create a device_target for each controller 
52
     // Iterate through the backlight controllers and create a device_target for each controller 
72
     DIR *backlight_dir;
53
     DIR *backlight_dir;
73
     struct dirent *curr_entry;
54
     struct dirent *curr_entry;
90
             continue;
71
             continue;
91
         }
72
         }
92
         
73
         
93
-        // Create a new device target for the controller 
94
-        light_device_target_t *backlight_controller = malloc(sizeof(light_device_target_t));
95
-        snprintf(backlight_controller->name, sizeof(backlight_controller->name), "%s", curr_entry->d_name);
96
-        
97
-        // Setup the function bindings
98
-        backlight_controller->set_value = impl_sysfs_set;
99
-        backlight_controller->get_value = impl_sysfs_get;
100
-        backlight_controller->get_max_value = impl_sysfs_getmax;
101
-        backlight_controller->custom_command = impl_sysfs_command;
102
-        
103
         // Setup the target data 
74
         // Setup the target data 
104
         impl_sysfs_data_t *dev_data = malloc(sizeof(impl_sysfs_data_t));
75
         impl_sysfs_data_t *dev_data = malloc(sizeof(impl_sysfs_data_t));
105
-        backlight_controller->device_target_data = dev_data;
106
         snprintf(dev_data->brightness, sizeof(dev_data->brightness), "/sys/class/backlight/%s/brightness", curr_entry->d_name);
76
         snprintf(dev_data->brightness, sizeof(dev_data->brightness), "/sys/class/backlight/%s/brightness", curr_entry->d_name);
107
         snprintf(dev_data->max_brightness, sizeof(dev_data->max_brightness), "/sys/class/backlight/%s/max_brightness", curr_entry->d_name);
77
         snprintf(dev_data->max_brightness, sizeof(dev_data->max_brightness), "/sys/class/backlight/%s/max_brightness", curr_entry->d_name);
108
         
78
         
79
+        // Create a new device target for the controller 
80
+        light_create_device_target(backlight_device, curr_entry->d_name, impl_sysfs_set, impl_sysfs_get, impl_sysfs_getmax, impl_sysfs_command, dev_data);
81
+        
109
         // Read the max brightness to get the best one
82
         // Read the max brightness to get the best one
110
         uint64_t curr_value = 0;
83
         uint64_t curr_value = 0;
111
         if(light_file_read_uint64(dev_data->max_brightness, &curr_value))
84
         if(light_file_read_uint64(dev_data->max_brightness, &curr_value))
113
             if(curr_value > best_value)
86
             if(curr_value > best_value)
114
             {
87
             {
115
                 best_value = curr_value;
88
                 best_value = curr_value;
116
-                snprintf(best_controller, sizeof(best_controller), "%s", backlight_controller->name);
89
+                snprintf(best_controller, sizeof(best_controller), "%s", curr_entry->d_name);
117
             }
90
             }
118
         }
91
         }
119
-        
120
-        // Add it to the device
121
-        light_add_device_target(backlight_device, backlight_controller);
122
     }
92
     }
123
     
93
     
124
     closedir(backlight_dir);
94
     closedir(backlight_dir);
125
     
95
     
126
-    // Create an auto controller 
127
-    light_device_target_t *auto_controller = malloc(sizeof(light_device_target_t));
128
-    snprintf(auto_controller->name, sizeof(auto_controller->name), "%s", "auto");
129
-    
130
-    // Setup the function bindings
131
-    auto_controller->set_value = impl_sysfs_set;
132
-    auto_controller->get_value = impl_sysfs_get;
133
-    auto_controller->get_max_value = impl_sysfs_getmax;
134
-    auto_controller->custom_command = impl_sysfs_command;
135
-    
136
-    // Setup the target data 
137
-    impl_sysfs_data_t *dev_data = malloc(sizeof(impl_sysfs_data_t));
138
-    auto_controller->device_target_data = dev_data;
139
-    snprintf(dev_data->brightness, sizeof(dev_data->brightness), "/sys/class/backlight/%s/brightness", best_controller);
140
-    snprintf(dev_data->max_brightness, sizeof(dev_data->max_brightness), "/sys/class/backlight/%s/max_brightness", best_controller);
141
-    
142
-    // Add it to the device
143
-    light_add_device_target(backlight_device, auto_controller);
96
+    // If we found at least one usable controller, create an auto target mapped to that controller
97
+    if(best_value > 0)
98
+    {
99
+        // Setup the target data 
100
+        impl_sysfs_data_t *dev_data = malloc(sizeof(impl_sysfs_data_t));
101
+        snprintf(dev_data->brightness, sizeof(dev_data->brightness), "/sys/class/backlight/%s/brightness", best_controller);
102
+        snprintf(dev_data->max_brightness, sizeof(dev_data->max_brightness), "/sys/class/backlight/%s/max_brightness", best_controller);
103
+        
104
+        // Create a new device target for the controller 
105
+        light_create_device_target(backlight_device, "auto", impl_sysfs_set, impl_sysfs_get, impl_sysfs_getmax, impl_sysfs_command, dev_data);
106
+    }
144
     
107
     
145
     return true;
108
     return true;
146
 }
109
 }
158
 
121
 
159
 bool impl_sysfs_free(light_device_enumerator_t *enumerator)
122
 bool impl_sysfs_free(light_device_enumerator_t *enumerator)
160
 {
123
 {
161
-    // Iterate through the devices in the enumerator
162
-    for(uint64_t d = 0; d < enumerator->num_devices; d++)
163
-    {
164
-        light_device_t *curr_device = enumerator->devices[d];
165
-        
166
-        // If the given device points to NULL, we can safely skip it
167
-        if(curr_device == NULL)
168
-        {
169
-            continue;
170
-        }
171
-        
172
-        for(uint64_t t = 0; t < curr_device->num_targets; t++)
173
-        {
174
-            light_device_target_t *curr_target = curr_device->targets[t];
175
-            
176
-            if(curr_target == NULL)
177
-            {
178
-                continue;
179
-            }
180
-            
181
-            if(curr_target->device_target_data != NULL)
182
-            {
183
-                free(curr_target->device_target_data);
184
-            }
185
-            
186
-            free(curr_target);
187
-        }
188
-        
189
-        // If the given device has any device_data, free it
190
-        if(curr_device->device_data != NULL)
191
-        {
192
-            free(curr_device->device_data);
193
-        }
194
-                
195
-        light_dispose_device(curr_device);    
196
-
197
-        // Free the device
198
-        free(curr_device);
199
-    }
200
-    
201
     return true;
124
     return true;
202
 }
125
 }
203
 
126
 

+ 118
- 70
src/light.c View File

16
 
16
 
17
 /* Static helper functions for this file only, prefix with _ */
17
 /* Static helper functions for this file only, prefix with _ */
18
 
18
 
19
+
20
+static void _light_add_enumerator_device(light_device_enumerator_t *enumerator, light_device_t *new_device)
21
+{
22
+    // Create a new device array 
23
+    uint64_t new_num_devices = enumerator->num_devices + 1;
24
+    light_device_t **new_devices = malloc(new_num_devices * sizeof(light_device_t*));
25
+    
26
+    // Copy old device array to new one
27
+    for(uint64_t i = 0; i < enumerator->num_devices; i++)
28
+    {
29
+        new_devices[i] = enumerator->devices[i];
30
+    }
31
+    
32
+    // Set the new device
33
+    new_devices[enumerator->num_devices] = new_device;
34
+    
35
+    // Free the old devices array, if needed
36
+    if(enumerator->devices != NULL)
37
+    {
38
+        free(enumerator->devices);
39
+    }
40
+    
41
+    // Replace the devices array with the new one
42
+    enumerator->devices = new_devices;
43
+    enumerator->num_devices = new_num_devices;
44
+}
45
+
46
+static void _light_add_device_target(light_device_t *device, light_device_target_t *new_target)
47
+{
48
+    // Create a new targets array 
49
+    uint64_t new_num_targets = device->num_targets + 1;
50
+    light_device_target_t **new_targets = malloc(new_num_targets * sizeof(light_device_target_t*));
51
+    
52
+    // Copy old targets array to new one
53
+    for(uint64_t i = 0; i < device->num_targets; i++)
54
+    {
55
+        new_targets[i] = device->targets[i];
56
+    }
57
+    
58
+    // Set the new target
59
+    new_targets[device->num_targets] = new_target;
60
+    
61
+    // Free the old targets array, if needed
62
+    if(device->targets != NULL)
63
+    {
64
+        free(device->targets);
65
+    }
66
+    
67
+    // Replace the targets array with the new one
68
+    device->targets= new_targets;
69
+    device->num_targets = new_num_targets;
70
+}
71
+
19
 static void _light_get_target_path(light_context_t* ctx, char* output_path, size_t output_size)
72
 static void _light_get_target_path(light_context_t* ctx, char* output_path, size_t output_size)
20
 {
73
 {
21
     snprintf(output_path, output_size,
74
     snprintf(output_path, output_size,
39
             );
92
             );
40
 }
93
 }
41
 
94
 
42
-
43
 static uint64_t _light_get_min_cap(light_context_t *ctx)
95
 static uint64_t _light_get_min_cap(light_context_t *ctx)
44
 {
96
 {
45
     char target_path[NAME_MAX];
97
     char target_path[NAME_MAX];
435
     }
487
     }
436
     
488
     
437
     // Allocate the new enumerator
489
     // Allocate the new enumerator
438
-    new_enumerators[ctx->num_enumerators] = malloc(sizeof(light_device_enumerator_t*));
490
+    new_enumerators[ctx->num_enumerators] = malloc(sizeof(light_device_enumerator_t));
439
     light_device_enumerator_t *returner = new_enumerators[ctx->num_enumerators];
491
     light_device_enumerator_t *returner = new_enumerators[ctx->num_enumerators];
440
     
492
     
441
     returner->devices = NULL;
493
     returner->devices = NULL;
473
     return success;
525
     return success;
474
 }
526
 }
475
 
527
 
476
-void light_dispose_device(light_device_t *device)
477
-{
478
-    if(device->targets != NULL)
479
-    {
480
-        free(device->targets);
481
-        device->targets = NULL;
482
-    }
483
-    
484
-    device->num_targets = 0;
485
-}
486
-
487
 bool light_free_enumerators(light_context_t *ctx)
528
 bool light_free_enumerators(light_context_t *ctx)
488
 {
529
 {
489
     bool success = true;
530
     bool success = true;
490
     for(uint64_t i = 0; i < ctx->num_enumerators; i++)
531
     for(uint64_t i = 0; i < ctx->num_enumerators; i++)
491
     {
532
     {
492
         light_device_enumerator_t * curr_enumerator = ctx->enumerators[i];
533
         light_device_enumerator_t * curr_enumerator = ctx->enumerators[i];
534
+        
493
         if(!curr_enumerator->free(curr_enumerator))
535
         if(!curr_enumerator->free(curr_enumerator))
494
         {
536
         {
495
             success = false;
537
             success = false;
497
         
539
         
498
         if(curr_enumerator->devices != NULL)
540
         if(curr_enumerator->devices != NULL)
499
         {
541
         {
542
+            for(uint64_t d = 0; d < curr_enumerator->num_devices; d++)
543
+            {
544
+                light_delete_device(curr_enumerator->devices[d]);
545
+            }
546
+            
500
             free(curr_enumerator->devices);
547
             free(curr_enumerator->devices);
501
             curr_enumerator->devices = NULL;
548
             curr_enumerator->devices = NULL;
502
         }
549
         }
511
     return success;
558
     return success;
512
 }
559
 }
513
 
560
 
514
-void light_add_enumerator_device(light_device_enumerator_t *enumerator, light_device_t *new_device)
515
-{
516
-    // Create a new device array 
517
-    uint64_t new_num_devices = enumerator->num_devices + 1;
518
-    light_device_t **new_devices = malloc(new_num_devices * sizeof(light_device_t*));
519
-    
520
-    // Copy old device array to new one
521
-    for(uint64_t i = 0; i < enumerator->num_devices; i++)
522
-    {
523
-        new_devices[i] = enumerator->devices[i];
524
-    }
525
-    
526
-    // Set the new device
527
-    new_devices[enumerator->num_devices] = new_device;
528
-    
529
-    // Free the old devices array, if needed
530
-    if(enumerator->devices != NULL)
531
-    {
532
-        free(enumerator->devices);
533
-    }
534
-    
535
-    // Replace the devices array with the new one
536
-    enumerator->devices = new_devices;
537
-    enumerator->num_devices = new_num_devices;
538
-    
539
-    new_device->enumerator = enumerator;
540
-}
541
-
542
-void light_add_device_target(light_device_t *device, light_device_target_t *new_target)
543
-{
544
-    // Create a new targets array 
545
-    uint64_t new_num_targets = device->num_targets + 1;
546
-    light_device_target_t **new_targets = malloc(new_num_targets * sizeof(light_device_target_t*));
547
-    
548
-    // Copy old targets array to new one
549
-    for(uint64_t i = 0; i < device->num_targets; i++)
550
-    {
551
-        new_targets[i] = device->targets[i];
552
-    }
553
-    
554
-    // Set the new target
555
-    new_targets[device->num_targets] = new_target;
556
-    
557
-    // Free the old targets array, if needed
558
-    if(device->targets != NULL)
559
-    {
560
-        free(device->targets);
561
-    }
562
-    
563
-    // Replace the targets array with the new one
564
-    device->targets= new_targets;
565
-    device->num_targets = new_num_targets;
566
-    
567
-    new_target->device = device;
568
-}
569
-
570
-
571
 bool light_split_target_path(char const *in_path, light_target_path_t *out_path)
561
 bool light_split_target_path(char const *in_path, light_target_path_t *out_path)
572
 {
562
 {
573
     char const * begin = in_path;
563
     char const * begin = in_path;
966
     return true;
956
     return true;
967
 }
957
 }
968
 
958
 
959
+light_device_t *light_create_device(light_device_enumerator_t *enumerator, char const *name, void *device_data)
960
+{
961
+    light_device_t *new_device = malloc(sizeof(light_device_t));
962
+    new_device->enumerator = enumerator;
963
+    new_device->targets = NULL;
964
+    new_device->num_targets = 0;
965
+    new_device->device_data = device_data;
966
+    
967
+    snprintf(new_device->name, sizeof(new_device->name), "%s", name);
968
+    
969
+    _light_add_enumerator_device(enumerator, new_device);
970
+    
971
+    return new_device;
972
+}
969
 
973
 
974
+void light_delete_device(light_device_t *device)
975
+{
976
+    for(uint64_t i = 0; i < device->num_targets; i++)
977
+    {
978
+        light_delete_device_target(device->targets[i]);
979
+    }
980
+    
981
+    if(device->targets != NULL)
982
+    {
983
+        free(device->targets);
984
+    }
985
+    
986
+    if(device->device_data != NULL)
987
+    {
988
+        free(device->device_data);
989
+    }
990
+    
991
+    free(device);
992
+}
970
 
993
 
994
+light_device_target_t *light_create_device_target(light_device_t *device, char const *name, LFUNCVALSET setfunc, LFUNCVALGET getfunc, LFUNCMAXVALGET getmaxfunc, LFUNCCUSTOMCMD cmdfunc, void *target_data)
995
+{
996
+    light_device_target_t *new_target = malloc(sizeof(light_device_target_t));
997
+    new_target->device = device;
998
+    new_target->set_value = setfunc;
999
+    new_target->get_value = getfunc;
1000
+    new_target->get_max_value = getmaxfunc;
1001
+    new_target->custom_command = cmdfunc;
1002
+    new_target->device_target_data = target_data;
1003
+    
1004
+    snprintf(new_target->name, sizeof(new_target->name), "%s", name);
1005
+    
1006
+    _light_add_device_target(device, new_target);
1007
+    
1008
+    return new_target;
1009
+}
971
 
1010
 
1011
+void light_delete_device_target(light_device_target_t *device_target)
1012
+{
1013
+    if(device_target->device_target_data != NULL)
1014
+    {
1015
+        free(device_target->device_target_data);
1016
+    }
1017
+    
1018
+    free(device_target);
1019
+}

+ 10
- 4
src/light.h View File

119
 /* Frees all the device enumerators (and its devices, targets) */
119
 /* Frees all the device enumerators (and its devices, targets) */
120
 bool light_free_enumerators(light_context_t *ctx);
120
 bool light_free_enumerators(light_context_t *ctx);
121
 
121
 
122
-void light_add_enumerator_device(light_device_enumerator_t *enumerator, light_device_t *new_device);
122
+/* Use this to create a device. Will automatically be added to enumerator. */
123
+light_device_t *light_create_device(light_device_enumerator_t *enumerator, char const *name, void *device_data);
123
 
124
 
124
-void light_add_device_target(light_device_t *device, light_device_target_t *new_target);
125
+/* Use this to delete a device. */
126
+void light_delete_device(light_device_t *device);
127
+
128
+/* Use this to create a device target. Will automatically be added to device. */
129
+light_device_target_t *light_create_device_target(light_device_t *device, char const *name, LFUNCVALSET setfunc, LFUNCVALGET getfunc, LFUNCMAXVALGET getmaxfunc, LFUNCCUSTOMCMD cmdfunc, void *target_data);
130
+
131
+/* Use this to delete a device target. */
132
+void light_delete_device_target(light_device_target_t *device_target);
125
 
133
 
126
 typedef struct _light_target_path_t light_target_path_t;
134
 typedef struct _light_target_path_t light_target_path_t;
127
 struct _light_target_path_t 
135
 struct _light_target_path_t 
136
 /* Returns the found device target, or null. Name should be enumerator/device/target */
144
 /* Returns the found device target, or null. Name should be enumerator/device/target */
137
 light_device_target_t* light_find_device_target(light_context_t *ctx, char const * name);
145
 light_device_target_t* light_find_device_target(light_context_t *ctx, char const * name);
138
 
146
 
139
-/* Frees any runtime-allocated data inside a device. Call this before you free a device. */
140
-void light_dispose_device(light_device_t *device);