Created
April 22, 2013 11:30
-
-
Save jiyeqian/5434075 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <assert.h> | |
#include "queue.h" | |
typedef struct Node { | |
void *element; | |
LIST_ENTRY ( Node ) linker; | |
} Node; | |
typedef LIST_HEAD ( Head, Node ) Head; | |
typedef Node* ( *Alloc_func ) ( void *data ); | |
typedef void ( *Free_func ) ( Node *node ); | |
typedef struct List { | |
Head *head; | |
char *name; | |
unsigned card; | |
Alloc_func malloc_node_func; | |
Free_func free_node_func; | |
} List; | |
typedef enum BOOL { | |
NO = 0, | |
YES = 1 | |
} BOOL; | |
typedef BOOL ( *is_remove_func ) ( Node *node ); | |
extern List* malloc_list ( const char *name, | |
Alloc_func malloc_node_func, Free_func free_node_func ) | |
{ | |
List *list = (List*) calloc ( 1, sizeof ( List ) ); | |
if ( list == NULL ) { | |
return NULL; | |
} | |
list->head = (Head*) calloc ( 1, sizeof ( Head ) ); | |
if ( list->head == NULL ) { | |
free ( list ); | |
return NULL; | |
} | |
LIST_INIT ( list->head ); | |
list->name = | |
(char*) calloc ( 1, ( 1 + strlen ( name ) ) * sizeof ( char ) ); | |
if ( list->name == NULL ) { | |
free ( list->head ); | |
free ( list ); | |
return NULL; | |
} | |
strcpy ( list->name, name ); | |
if ( malloc_node_func == NULL || free_node_func == NULL ) { | |
free ( list->name ); | |
free ( list->head ); | |
free ( list ); | |
return NULL; | |
} | |
list->malloc_node_func = malloc_node_func; | |
list->free_node_func = free_node_func; | |
return list; | |
} | |
extern void free_list ( List *list ) | |
{ | |
assert ( list != NULL ); | |
if ( list->head != NULL ) { | |
free ( list->head ); | |
} | |
if ( list->name != NULL ) { | |
free ( list->name ); | |
} | |
free ( list ); | |
} | |
extern Node* insert_head ( List *list, void *data ) { | |
assert ( data != NULL ); | |
Node *node = list->malloc_node_func ( data ); | |
if ( node == NULL ) { | |
return NULL; | |
} | |
LIST_INSERT_HEAD ( list->head, node, linker ); | |
list->card++; | |
return node; | |
} | |
extern void remove_node ( List *list, Node *node ) | |
{ | |
assert ( node != NULL ); | |
LIST_REMOVE ( node, linker ); | |
list->card--; | |
list->free_node_func ( node ); | |
} | |
extern void remove_node_if ( List *list, is_remove_func rm ) | |
{ | |
assert ( rm != NULL ); | |
Node *node, *tmp_node; | |
LIST_FOREACH_SAFE ( node, list->head, linker, tmp_node ) { | |
if ( rm ( node ) ) { | |
remove_node ( list, node ); | |
} | |
} | |
} | |
extern void remove_head ( List *list ) | |
{ | |
Node *node = LIST_FIRST ( list->head ); | |
assert ( node != NULL ); | |
remove_node ( list, node ); | |
} | |
extern void remove_all_nodes ( List *list ) | |
{ | |
while ( LIST_FIRST(list->head) != NULL ) { | |
remove_head ( list ); | |
} | |
/* Node *node = NULL, *tmp_node = NULL; */ | |
/* LIST_FOREACH_SAFE ( node, list->head, linker, tmp_node ) { */ | |
/* LIST_REMOVE ( node, linker ); */ | |
/* list->free_node_func ( node ); */ | |
/* } */ | |
} | |
//////////////////////////////////// | |
typedef struct Point { | |
int x; | |
int y; | |
} Point; | |
typedef struct Scene { | |
unsigned total_cars; // 該場景中的車輛數目 | |
void *image; | |
} Scene; | |
typedef struct Car { | |
unsigned id; | |
struct CvRect { | |
int x; | |
int y; | |
int width; | |
int height; | |
} location; // 車輛在*圖中的位置及大小 | |
unsigned lane_id; // 車輛所在的車道 | |
unsigned confidence; // 該對象為車輛的置信度:0~100 | |
List *trace; // 車輛的行駛軌跡(每次檢出位置中心的連線) | |
List *scenes; // 指向圖像鏈錶鏈首,為了刪除圖片方便 | |
Node *behind_stopline; // 車輛在停止線前的圖像節點 | |
Node *over_stopline; // 車輛在停止線上的圖像 | |
Node *ahead_stopline; // 車輛越過停止線后的圖像 | |
} Car; | |
static Node* malloc_trace_point ( void *data ) | |
{ | |
Node *node = (Node*) calloc ( 1, sizeof ( Node ) ); | |
if ( node == NULL ) { | |
return NULL; | |
} | |
Point *point = (Point*) calloc ( 1, sizeof ( Point ) ); | |
if ( point == NULL ) { | |
free ( node ); | |
return NULL; | |
} | |
node->element = point; | |
return node; | |
} | |
static void free_trace_point ( Node *node ) | |
{ | |
assert ( node != NULL ); | |
free ( node->element ); | |
free ( node ); | |
} | |
static void release_trace ( List *trace ) | |
{ | |
assert ( trace != NULL ); | |
remove_all_nodes ( trace ); | |
free_list ( trace ); | |
} | |
static Node* malloc_scene ( void *data ) | |
{ | |
Node *node = (Node*) calloc ( 1, sizeof ( Node ) ); | |
if ( node == NULL ) { | |
return NULL; | |
} | |
Scene *scene = (Scene*) calloc ( 1, sizeof ( Scene ) ); | |
if ( scene == NULL ) { | |
free ( node ); | |
return NULL; | |
} | |
node->element = scene; | |
return node; | |
} | |
static void free_scene ( Node *node ) | |
{ | |
assert ( node != NULL ); | |
free ( ( (Scene*) node->element )->image ); | |
free ( node->element ); | |
free ( node ); | |
} | |
extern List* initialize_trace ( ); | |
static Node* malloc_car ( void *data ) | |
{ | |
Node *node = (Node*) calloc ( 1, sizeof ( Node ) ); | |
if ( node == NULL ) { | |
return NULL; | |
} | |
Car *car = (Car*) calloc ( 1, sizeof ( Car ) ); | |
if ( car == NULL ) { | |
free ( node ); | |
return NULL; | |
} | |
List *trace = initialize_trace ( ); | |
if ( trace == NULL ) { | |
free ( node ); | |
free ( car ); | |
return NULL; | |
} | |
car->id = *(unsigned *)data; | |
car->trace = trace; | |
car->scenes = NULL; | |
car->behind_stopline = NULL; | |
car->over_stopline = NULL; | |
car->ahead_stopline = NULL; | |
node->element = car; | |
return node; | |
} | |
// If no car in the scene is needed, then remove the scene. | |
/* static void remove_unneeded_scene ( Car *car, List *scene_list ) */ | |
/* { */ | |
/* if ( car->behind_stopline != NULL && */ | |
/* car->behind_stopline->total_cars == 0 ) { */ | |
/* car->behind_stopline = NULL; */ | |
/* } */ | |
/* } */ | |
static void free_car ( Node *node ) | |
{ | |
assert ( node != NULL ); | |
Car *car = (Car*) node->element; | |
Scene *scene = NULL; | |
if ( car->behind_stopline != NULL ) { | |
scene = (Scene*) car->behind_stopline->element; | |
scene->total_cars--; | |
if ( scene->total_cars == 0 ) { | |
remove_node ( car->scenes, car->behind_stopline ); | |
} | |
} | |
if ( car->over_stopline != NULL ) { | |
scene = (Scene*) car->over_stopline->element; | |
scene->total_cars--; | |
if ( scene->total_cars == 0 ) { | |
remove_node ( car->scenes, car->over_stopline ); | |
} | |
} | |
if ( car->ahead_stopline != NULL ) { | |
scene = (Scene*) car->ahead_stopline->element; | |
scene->total_cars--; | |
if ( scene->total_cars == 0 ) { | |
remove_node ( car->scenes, car->ahead_stopline ); | |
} | |
} | |
if ( car->trace != NULL ) { // 實際中,只要Car不空,至少有一個點 | |
release_trace ( car->trace ); | |
} | |
free ( car ); | |
free ( node ); | |
} | |
static void display_car ( List *list ) | |
{ | |
Node *node = NULL; | |
printf ( "%s (%d): \n", list->name, list->card ); | |
LIST_FOREACH ( node, list->head, linker ) { | |
printf ( "%d\n", ( (Car*) node->element )->id ); | |
} | |
} | |
static List* initialize_cars ( ) | |
{ | |
List *cars = malloc_list ( "Car list", malloc_car, free_car ); | |
for ( int i = 10; i > 0; --i ) { | |
insert_head ( cars, &i ); | |
} | |
return cars; | |
} | |
static List* initialize_scenes ( ) | |
{ | |
List *scenes = malloc_list ( "Scene list", malloc_scene, free_scene ); | |
return scenes; | |
} | |
List* initialize_trace ( ) | |
{ | |
List *trace = malloc_list ( "Car trace", malloc_trace_point, free_trace_point ); | |
return trace; | |
} | |
static BOOL is_car_remove ( Node *node ) | |
{ | |
return ( (Car*) node->element )->id & 0x1 ? YES : NO; | |
} | |
int main(int argc, char const* argv[]) | |
{ | |
List *list = initialize_cars (); | |
remove_head ( list ); | |
display_car ( list ); | |
remove_node_if ( list, is_car_remove ); | |
display_car ( list ); | |
remove_all_nodes ( list ); | |
display_car ( list ); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment