Skip to content

Instantly share code, notes, and snippets.

@jiyeqian
Created April 22, 2013 11:30
Show Gist options
  • Save jiyeqian/5434075 to your computer and use it in GitHub Desktop.
Save jiyeqian/5434075 to your computer and use it in GitHub Desktop.
#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