// // Created by Antoine Bartuccio on 05/06/2018. // #include #include "Building.h" #include "../Resident/Resident.h" #include "../Visitor/Visitor.h" #define LINE_BUFFER 256 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'; } void split(char * line, int number_to_split, char output[][LINE_BUFFER], char separator){ char * token = NULL; char * to_delete = NULL; char * to_delete_back = NULL; int i = 0; to_delete = strdup(line); to_delete_back = to_delete; while(i < number_to_split && (token = strsep(&to_delete, &separator)) != NULL){ strcpy(output[i], token); i++; } free(to_delete_back); } void parse_residents_Building(THIS(Building), char * file){ /* File format is name;appartment_floor;destination */ FILE * f = fopen(file, "r"); Resident * resident = NULL; size_t len = LINE_BUFFER; char * line = NULL; char * trash; char data[3][LINE_BUFFER]; int i = 0; if (f == NULL) CRASH("File for residents does not exist"); while (getline(&line, &len, f) > 0) { remove_end_char(line, '\n'); split(line, 3, data, ';'); resident = NEW(Resident, i, data[0], (int) strtol(data[1], &trash, 10), (int) strtol(data[2], &trash, 10)); this->residents->insert_tail(this->residents, resident, sizeof(Resident)); resident->name = NULL; DELETE(resident); i++; } free(line); fclose(f); } void parse_visitors_Building(THIS(Building), char * file){ /* File format is name;contact_name */ FILE * f = fopen(file, "r"); Visitor * visitor = NULL; size_t len = LINE_BUFFER; char * line = NULL; char data[2][LINE_BUFFER]; int i = 0; if (f == NULL) CRASH("File for visitors does not exist"); while (getline(&line, &len, f) > 0) { remove_end_char(line, '\n'); split(line, 2, data, ';'); visitor = NEW(Visitor, i, data[0], data[1]); this->visitors->insert_tail(this->visitors, visitor, sizeof(Visitor)); visitor->contact_name = NULL; visitor->name = NULL; DELETE(visitor); 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); } void _free__Building(THIS(Building)){ int i = 0; this->residents->clear_custom(this->residents, free_resident); this->visitors->clear_custom(this->visitors, free_visitor); pthread_mutex_unlock(this->mutex_get_inside_elevator); pthread_mutex_destroy(this->mutex_get_inside_elevator); pthread_mutex_unlock(this->mutex_get_outside_elevator); pthread_mutex_destroy(this->mutex_get_outside_elevator); DELETE(this->residents); DELETE(this->visitors); DELETE(this->box); for (i=0; ielevators[i]); for (i=0; icondition_floors[i]); free(this->condition_floors); free(this->mutex_get_inside_elevator); free(this->mutex_get_outside_elevator); free(this->elevators); free(this); } int get_inside_elevator_Building(THIS(Building), int current_floor, Passenger passenger, PASSENGER_TYPE type){ int i; /* Make assumption that a waiting elevator is not full */ for (i=0; ielevators[i]->get_floor(this->elevators[i]) == current_floor && this->elevators[i]->get_state(this->elevators[i]) == waiting){ /* pour faire taire le compilateur le temps que je revienne sur cette fonction */ printf("visiteur %s, de type %d\n", passenger.visitor->name, type); /* Il faut faire des trucs ici */ return i; } } return -1; } void go_to_floor_Building(THIS(Building), int origin, int destination, Passenger passenger, PASSENGER_TYPE type){ int elevator_number; if (origin < 0 || origin >= FLOORS) CRASH("You are trying to start from a non existing floor\n"); if (destination < 0 || origin >= FLOORS) CRASH("You are trying to reach a non existing floor\n"); pthread_cond_wait(this->condition_floors[origin], this->mutex_get_inside_elevator); elevator_number = this->get_inside_elevator(this, origin, passenger, type); if (type == resident) printf("Le résident %s rentre dans l'ascenseur %s depuis l'étage %d\n", passenger.resident->name, this->elevators[elevator_number]->name, origin); else if (type == visitor) printf("Le visiteur %s rentre dans l'ascenseur %s depuis l'étage %d\n", passenger.visitor->name, this->elevators[elevator_number]->name, origin); pthread_cond_wait(this->condition_floors[destination], this->mutex_get_outside_elevator); if (type == resident) printf("Le résident %s sors de l'ascenseur %s à l'étage %d\n", passenger.resident->name, this->elevators[elevator_number]->name, destination); else if (type == visitor) printf("Le visiteur %s sors de l'ascenseur %s à l'étage %d\n", passenger.visitor->name, this->elevators[elevator_number]->name, destination); } Building *_init_Building(char * residents_file, char * visitors_file){ Building * new_building = malloc_or_die(sizeof(Building)); char elevator_name[] = "@"; int i; new_building->floors = FLOORS; new_building->elevators = malloc_or_die(sizeof(Elevator*) * ELEVATOR_NB); new_building->mutex_get_inside_elevator = malloc_or_die(sizeof(pthread_mutex_t)); new_building->mutex_get_outside_elevator = malloc_or_die(sizeof(pthread_mutex_t)); new_building->condition_floors = malloc_or_die(sizeof(pthread_cond_t*) * FLOORS); new_building->residents = NEW(List); new_building->visitors = NEW(List); new_building->box = NEW(CommunicationBox); for (i=0; ielevators[i] = NEW(Elevator, elevator_name); } for (i=0; icondition_floors[i] = malloc_or_die((sizeof(pthread_cond_t))); pthread_cond_init(new_building->condition_floors[i], NULL); } LINK_ALL(Building, new_building, parse_residents, parse_visitors, get_inside_elevator, go_to_floor ) if (residents_file != NULL) new_building->parse_residents(new_building, residents_file); if (visitors_file != NULL) new_building->parse_visitors(new_building, visitors_file); return new_building; }