2018-06-05 23:15:23 +00:00
//
// Created by Antoine Bartuccio on 05/06/2018.
//
2018-06-06 18:29:02 +00:00
# include <string.h>
2018-06-05 23:15:23 +00:00
# include "Building.h"
2018-06-06 18:29:02 +00:00
# include "../Resident/Resident.h"
# include "../Visitor/Visitor.h"
# define LINE_BUFFER 256
2018-06-06 01:00:35 +00:00
2018-06-06 18:29:02 +00:00
void remove_end_char ( char * string , char character ) {
size_t string_size = strlen ( string ) ;
if ( string [ string_size - 1 ] = = character )
string [ string_size - 1 ] = ' \0 ' ;
}
2018-06-10 23:58:52 +00:00
List * split ( char * line , char * separator ) {
List * split = NEW ( List ) ;
char * to_delete = strdup ( line ) ;
char * to_delete_back = to_delete ;
2018-06-10 15:57:39 +00:00
char * token = NULL ;
2018-06-10 23:58:52 +00:00
while ( ( token = strsep ( & to_delete , separator ) ) ! = NULL )
split - > insert_tail ( split , ( void * ) token , sizeof ( char ) * strlen ( token ) ) ;
2018-06-10 15:57:39 +00:00
free ( to_delete_back ) ;
2018-06-10 23:58:52 +00:00
return split ;
2018-06-10 15:57:39 +00:00
}
2018-06-06 18:29:02 +00:00
void parse_residents_Building ( THIS ( Building ) , char * file ) {
2018-06-10 15:57:39 +00:00
/* File format is name;appartment_floor;destination */
2018-06-06 18:29:02 +00:00
FILE * f = fopen ( file , " r " ) ;
2018-06-10 23:58:52 +00:00
List * line_split = NULL ;
2018-06-06 18:29:02 +00:00
Resident * resident = NULL ;
size_t len = LINE_BUFFER ;
char * line = NULL ;
char * trash ;
int i = 0 ;
2018-06-15 09:50:38 +00:00
if ( f = = NULL ) {
2018-06-06 18:29:02 +00:00
CRASH ( " File for residents does not exist " ) ;
2018-06-15 09:50:38 +00:00
}
2018-06-06 18:29:02 +00:00
while ( getline ( & line , & len , f ) > 0 ) {
remove_end_char ( line , ' \n ' ) ;
2018-06-10 23:58:52 +00:00
line_split = split ( line , " ; " ) ;
2018-06-06 18:29:02 +00:00
2018-06-10 23:58:52 +00:00
resident = NEW ( Resident , i , line_split - > get_element_data ( line_split , 0 ) ,
( int ) strtol ( line_split - > get_element_data ( line_split , 1 ) , & trash , 10 ) ,
( int ) strtol ( line_split - > get_element_data ( line_split , 2 ) , & trash , 10 ) ) ;
2018-06-06 18:29:02 +00:00
this - > residents - > insert_tail ( this - > residents , resident , sizeof ( Resident ) ) ;
resident - > name = NULL ;
DELETE ( resident ) ;
2018-06-10 23:58:52 +00:00
DELETE ( line_split ) ;
2018-06-06 18:29:02 +00:00
i + + ;
}
free ( line ) ;
fclose ( f ) ;
}
void parse_visitors_Building ( THIS ( Building ) , char * file ) {
2018-06-10 15:57:39 +00:00
/* File format is name;contact_name */
2018-06-06 18:29:02 +00:00
FILE * f = fopen ( file , " r " ) ;
2018-06-10 23:58:52 +00:00
List * line_split = NULL ;
2018-06-06 18:29:02 +00:00
Visitor * visitor = NULL ;
size_t len = LINE_BUFFER ;
char * line = NULL ;
int i = 0 ;
2018-06-15 09:50:38 +00:00
if ( f = = NULL ) {
2018-06-06 18:29:02 +00:00
CRASH ( " File for visitors does not exist " ) ;
2018-06-15 09:50:38 +00:00
}
2018-06-06 18:29:02 +00:00
while ( getline ( & line , & len , f ) > 0 ) {
remove_end_char ( line , ' \n ' ) ;
2018-06-10 15:57:39 +00:00
2018-06-10 23:58:52 +00:00
line_split = split ( line , " ; " ) ;
visitor = NEW ( Visitor , i , line_split - > get_element_data ( line_split , 0 ) ,
line_split - > get_element_data ( line_split , 1 ) ) ;
2018-06-06 18:29:02 +00:00
this - > visitors - > insert_tail ( this - > visitors , visitor , sizeof ( Visitor ) ) ;
2018-06-10 15:57:39 +00:00
visitor - > contact_name = NULL ;
2018-06-06 18:29:02 +00:00
visitor - > name = NULL ;
DELETE ( visitor ) ;
2018-06-10 23:58:52 +00:00
DELETE ( line_split ) ;
2018-06-06 18:29:02 +00:00
i + + ;
}
free ( line ) ;
fclose ( f ) ;
}
void free_resident ( void * data ) {
Resident * r = ( Resident * ) data ;
DELETE ( r ) ;
}
void free_visitor ( void * data ) {
Visitor * v = ( Visitor * ) data ;
DELETE ( v ) ;
}
2018-06-06 01:00:35 +00:00
void _free__Building ( THIS ( Building ) ) {
int i = 0 ;
2018-06-06 18:29:02 +00:00
this - > residents - > clear_custom ( this - > residents , free_resident ) ;
this - > visitors - > clear_custom ( this - > visitors , free_visitor ) ;
2018-06-15 13:38:26 +00:00
pthread_mutex_unlock ( this - > mutex_cond_get_inside_elevator ) ;
pthread_mutex_destroy ( this - > mutex_cond_get_inside_elevator ) ;
pthread_mutex_unlock ( this - > mutex_cond_get_outside_elevator ) ;
pthread_mutex_destroy ( this - > mutex_cond_get_outside_elevator ) ;
pthread_mutex_unlock ( this - > mutex_func_get_inside_elevator ) ;
pthread_mutex_destroy ( this - > mutex_func_get_inside_elevator ) ;
2018-06-10 02:00:01 +00:00
2018-06-06 01:00:35 +00:00
DELETE ( this - > residents ) ;
2018-06-06 18:29:02 +00:00
DELETE ( this - > visitors ) ;
2018-06-06 01:00:35 +00:00
for ( i = 0 ; i < ELEVATOR_NB ; i + + )
DELETE ( this - > elevators [ i ] ) ;
2018-06-15 17:14:30 +00:00
for ( i = 0 ; i < FLOORS ; i + + ) {
pthread_cond_destroy ( this - > condition_floors [ i ] ) ;
2018-06-10 02:00:01 +00:00
free ( this - > condition_floors [ i ] ) ;
2018-06-15 17:14:30 +00:00
}
2018-06-10 02:00:01 +00:00
free ( this - > condition_floors ) ;
2018-06-15 13:38:26 +00:00
free ( this - > mutex_cond_get_inside_elevator ) ;
free ( this - > mutex_cond_get_outside_elevator ) ;
free ( this - > mutex_func_get_inside_elevator ) ;
2018-06-06 01:00:35 +00:00
free ( this - > elevators ) ;
free ( this ) ;
}
2018-06-18 13:51:48 +00:00
int get_inside_elevator_Building ( THIS ( Building ) , int current_floor , ElevatorPassenger elevator_passenger ) {
2018-06-10 02:00:01 +00:00
int i ;
/* Make assumption that a waiting elevator is not full */
2018-06-15 13:38:26 +00:00
pthread_mutex_lock ( this - > mutex_func_get_inside_elevator ) ;
2018-06-18 13:51:48 +00:00
printf ( " Test d'entrée à l'étage %d de %s : id %d \n " , current_floor , elevator_passenger . passenger . visitor - > name , elevator_passenger . passenger . visitor - > id ) ;
2018-06-10 02:00:01 +00:00
for ( i = 0 ; i < ELEVATOR_NB ; i + + ) {
2018-06-15 13:38:26 +00:00
if ( this - > elevators [ i ] - > can_get_inside ( this - > elevators [ i ] , current_floor ) ) {
2018-06-10 10:47:07 +00:00
/* pour faire taire le compilateur le temps que je revienne sur cette fonction */
2018-06-18 13:51:48 +00:00
if ( elevator_passenger . type = = VISITOR )
2018-06-18 13:56:22 +00:00
this - > elevators [ i ] - > add_passenger ( this - > elevators [ i ] , elevator_passenger ) ;
2018-06-10 02:00:01 +00:00
/* Il faut faire des trucs ici */
2018-06-15 13:38:26 +00:00
pthread_mutex_unlock ( this - > mutex_func_get_inside_elevator ) ;
2018-06-10 02:00:01 +00:00
return i ;
}
}
2018-06-15 13:38:26 +00:00
pthread_mutex_unlock ( this - > mutex_func_get_inside_elevator ) ;
2018-06-10 02:00:01 +00:00
return - 1 ;
}
2018-06-18 13:51:48 +00:00
void go_to_floor_Building ( THIS ( Building ) , int origin , int destination , ElevatorPassenger elevator_passenger ) {
2018-06-10 02:00:01 +00:00
int elevator_number ;
2018-06-15 09:50:38 +00:00
if ( origin < 0 | | origin > = FLOORS ) { CRASH ( " You are trying to start from a non existing floor \n " ) ; }
2018-06-15 17:14:30 +00:00
if ( destination < 0 | | destination > = FLOORS ) { CRASH ( " You are trying to reach a non existing floor \n " ) ; }
2018-06-10 02:00:01 +00:00
2018-06-15 13:38:26 +00:00
pthread_cond_wait ( this - > condition_floors [ origin ] , this - > mutex_cond_get_inside_elevator ) ;
2018-06-18 13:51:48 +00:00
elevator_number = this - > get_inside_elevator ( this , origin , elevator_passenger ) ;
if ( elevator_passenger . type = = RESIDENT )
printf ( " Le résident %s rentre dans l'ascenseur %s depuis l'étage %d \n " , elevator_passenger . passenger . resident - > name ,
2018-06-10 02:00:01 +00:00
this - > elevators [ elevator_number ] - > name , origin ) ;
2018-06-18 13:51:48 +00:00
else if ( elevator_passenger . type = = VISITOR )
printf ( " Le visiteur %s rentre dans l'ascenseur %s depuis l'étage %d \n " , elevator_passenger . passenger . visitor - > name ,
2018-06-10 02:00:01 +00:00
this - > elevators [ elevator_number ] - > name , origin ) ;
2018-06-15 13:38:26 +00:00
pthread_cond_wait ( this - > condition_floors [ destination ] , this - > mutex_cond_get_outside_elevator ) ;
2018-06-18 13:51:48 +00:00
if ( elevator_passenger . type = = RESIDENT )
printf ( " Le résident %s sors de l'ascenseur %s à l'étage %d \n " , elevator_passenger . passenger . resident - > name ,
2018-06-10 02:00:01 +00:00
this - > elevators [ elevator_number ] - > name , destination ) ;
2018-06-18 13:51:48 +00:00
else if ( elevator_passenger . type = = VISITOR )
printf ( " Le visiteur %s sors de l'ascenseur %s à l'étage %d \n " , elevator_passenger . passenger . visitor - > name ,
2018-06-10 02:00:01 +00:00
this - > elevators [ elevator_number ] - > name , destination ) ;
}
2018-06-11 08:52:58 +00:00
int use_call_box_Building ( THIS ( Building ) , char * resident_name ) {
/* Return negative number if not found */
Element * current = this - > residents - > get_head ( this - > residents ) ;
while ( current ! = NULL ) {
if ( ! strcmp ( ( ( Resident * ) current - > get_data ( current ) ) - > name , resident_name ) )
return ( ( Resident * ) current - > get_data ( current ) ) - > apartment_floor ;
current = current - > get_next ( current ) ;
}
return - 1 ;
}
2018-06-15 13:38:26 +00:00
void signal_elevator_at_floor_Building ( THIS ( Building ) , int floor ) {
pthread_cond_signal ( this - > condition_floors [ floor ] ) ;
}
2018-06-06 18:29:02 +00:00
Building * _init_Building ( char * residents_file , char * visitors_file ) {
2018-06-06 01:00:35 +00:00
Building * new_building = malloc_or_die ( sizeof ( Building ) ) ;
2018-06-07 20:04:30 +00:00
char elevator_name [ ] = " @ " ;
2018-06-06 01:00:35 +00:00
int i ;
new_building - > floors = FLOORS ;
new_building - > elevators = malloc_or_die ( sizeof ( Elevator * ) * ELEVATOR_NB ) ;
2018-06-15 13:38:26 +00:00
new_building - > mutex_cond_get_inside_elevator = malloc_or_die ( sizeof ( pthread_mutex_t ) ) ;
new_building - > mutex_cond_get_outside_elevator = malloc_or_die ( sizeof ( pthread_mutex_t ) ) ;
new_building - > mutex_func_get_inside_elevator = malloc_or_die ( sizeof ( pthread_mutex_t ) ) ;
pthread_mutex_init ( new_building - > mutex_cond_get_inside_elevator , NULL ) ;
pthread_mutex_init ( new_building - > mutex_cond_get_outside_elevator , NULL ) ;
pthread_mutex_init ( new_building - > mutex_func_get_inside_elevator , NULL ) ;
2018-06-10 02:00:01 +00:00
new_building - > condition_floors = malloc_or_die ( sizeof ( pthread_cond_t * ) * FLOORS ) ;
2018-06-06 01:00:35 +00:00
new_building - > residents = NEW ( List ) ;
2018-06-06 18:29:02 +00:00
new_building - > visitors = NEW ( List ) ;
2018-06-07 20:04:30 +00:00
for ( i = 0 ; i < ELEVATOR_NB ; i + + ) {
elevator_name [ 0 ] + + ;
new_building - > elevators [ i ] = NEW ( Elevator , elevator_name ) ;
}
2018-06-10 02:00:01 +00:00
for ( i = 0 ; i < FLOORS ; i + + ) {
new_building - > condition_floors [ i ] = malloc_or_die ( ( sizeof ( pthread_cond_t ) ) ) ;
pthread_cond_init ( new_building - > condition_floors [ i ] , NULL ) ;
}
2018-06-06 01:00:35 +00:00
2018-06-06 18:29:02 +00:00
2018-06-06 01:00:35 +00:00
LINK_ALL ( Building , new_building ,
2018-06-06 18:29:02 +00:00
parse_residents ,
2018-06-10 02:00:01 +00:00
parse_visitors ,
get_inside_elevator ,
2018-06-11 08:52:58 +00:00
use_call_box ,
2018-06-15 13:38:26 +00:00
go_to_floor ,
signal_elevator_at_floor
2018-06-06 01:00:35 +00:00
)
2018-06-06 18:29:02 +00:00
if ( residents_file ! = NULL )
new_building - > parse_residents ( new_building , residents_file ) ;
if ( visitors_file ! = NULL )
new_building - > parse_visitors ( new_building , visitors_file ) ;
2018-06-06 01:00:35 +00:00
return new_building ;
}