1
0
mirror of https://gitlab.com/klmp200/LO41.git synced 2024-11-25 18:44:20 +00:00

Merge branch 'bro' into 'master'

Bro

See merge request klmp200/LO41!2
This commit is contained in:
Aethor 2018-06-21 19:36:41 +00:00
commit 9ccec46143
12 changed files with 266 additions and 94 deletions

View File

@ -2,18 +2,45 @@
// Created by Antoine Bartuccio on 05/06/2018. // Created by Antoine Bartuccio on 05/06/2018.
// //
#include <string.h> #include <string.h>
#include <math.h>
#include "Building.h" #include "Building.h"
#include "../Resident/Resident.h" #include "../Resident/Resident.h"
#include "../Visitor/Visitor.h" #include "../Visitor/Visitor.h"
#define LINE_BUFFER 256 #define LINE_BUFFER 256
SYNCHRONIZED_GETTER(Building, int*, waiting_floors)
void remove_end_char(char * string, char character){ void remove_end_char(char * string, char character){
size_t string_size = strlen(string); size_t string_size = strlen(string);
if (string[string_size - 1] == character) if (string[string_size - 1] == character)
string[string_size - 1] = '\0'; string[string_size - 1] = '\0';
} }
/**
* Get the best call for the elevator
*@param THIS(Building) : this
*@param elevator_floor : actual floor of the requesting elevator
*@returns the closest floor where a client is calling as an int. If no client is calling, returns -1.
*/
int get_next_call_Building(THIS(Building), int elevator_floor){
pthread_mutex_lock(this->mutex_func_get_next_call);
int* waiting_floors = this->get_waiting_floors(this);
int i;
float best_diff = INFINITY;
int next_target = -1;
for(i=0; i<FLOORS; i++){
if(waiting_floors[i] > 0){
if(abs(elevator_floor - i) < best_diff){
best_diff = abs(elevator_floor - i);
next_target = i;
}
}
}
pthread_mutex_unlock(this->mutex_func_get_next_call);
return next_target;
}
List * split(char * line, char * separator){ List * split(char * line, char * separator){
List * split = NEW(List); List * split = NEW(List);
char * to_delete = strdup(line); char * to_delete = strdup(line);
@ -118,6 +145,12 @@ void _free__Building(THIS(Building)){
pthread_mutex_unlock(this->mutex_func_get_inside_elevator); pthread_mutex_unlock(this->mutex_func_get_inside_elevator);
pthread_mutex_destroy(this->mutex_func_get_inside_elevator); pthread_mutex_destroy(this->mutex_func_get_inside_elevator);
pthread_mutex_unlock(this->mutex_func_get_next_call);
pthread_mutex_destroy(this->mutex_func_get_next_call);
pthread_mutex_unlock(&this->mutex_waiting_floors);
pthread_mutex_destroy(&this->mutex_waiting_floors);
DELETE(this->residents); DELETE(this->residents);
DELETE(this->visitors); DELETE(this->visitors);
for (i=0; i<ELEVATOR_NB; i++) for (i=0; i<ELEVATOR_NB; i++)
@ -130,6 +163,7 @@ void _free__Building(THIS(Building)){
free(this->mutex_cond_get_inside_elevator); free(this->mutex_cond_get_inside_elevator);
free(this->mutex_cond_get_outside_elevator); free(this->mutex_cond_get_outside_elevator);
free(this->mutex_func_get_inside_elevator); free(this->mutex_func_get_inside_elevator);
free(this->mutex_func_get_next_call);
free(this->elevators); free(this->elevators);
free(this); free(this);
@ -142,17 +176,14 @@ void _free__Building(THIS(Building)){
* @passenger the passenger to put in the elevator * @passenger the passenger to put in the elevator
* @returns an elevator number ( between 0 and ELEVATOR_NB - 1, inclusive ), -1 if no elevator was found ready to accept the passenger * @returns an elevator number ( between 0 and ELEVATOR_NB - 1, inclusive ), -1 if no elevator was found ready to accept the passenger
*/ */
int get_inside_elevator_Building(THIS(Building), int current_floor, Passenger passenger){ int get_inside_elevator_Building(THIS(Building), int current_floor, Passenger * passenger){
int i; int i;
/* Make assumption that a waiting elevator is not full */ /* Make assumption that a waiting elevator is not full */
pthread_mutex_lock(this->mutex_func_get_inside_elevator); pthread_mutex_lock(this->mutex_func_get_inside_elevator);
printf("Test d'entrée à l'étage %d de %s : id %d\n", current_floor, passenger.visitor->name, passenger.visitor->id); printf("Test d'entrée à l'étage %d de %s : id %d\n", current_floor, passenger->get_name(passenger), passenger->get_id(passenger));
for (i=0; i<ELEVATOR_NB; i++){ for (i=0; i<ELEVATOR_NB; i++){
if (this->elevators[i]->can_get_inside(this->elevators[i], current_floor)){ if (this->elevators[i]->can_get_inside(this->elevators[i], current_floor)){
/* pour faire taire le compilateur le temps que je revienne sur cette fonction */
//if (passenger.type == VISITOR) TODO : ???
this->elevators[i]->add_passenger(this->elevators[i], passenger); this->elevators[i]->add_passenger(this->elevators[i], passenger);
/* Il faut faire des trucs ici */
pthread_mutex_unlock(this->mutex_func_get_inside_elevator); pthread_mutex_unlock(this->mutex_func_get_inside_elevator);
return i; return i;
} }
@ -161,36 +192,28 @@ int get_inside_elevator_Building(THIS(Building), int current_floor, Passenger pa
return -1; return -1;
} }
void go_to_floor_Building(THIS(Building), int origin, int destination, Passenger passenger){ void go_to_floor_Building(THIS(Building), int origin, int destination, Passenger * passenger){
int elevator_number; int elevator_number;
if (origin < 0 || origin >= FLOORS) {CRASH("You are trying to start from a non existing floor\n");} if (origin < 0 || origin >= FLOORS) {CRASH("You are trying to start from a non existing floor\n");}
if (destination < 0 || destination >= FLOORS) {CRASH("You are trying to reach a non existing floor\n");} if (destination < 0 || destination >= FLOORS) {CRASH("You are trying to reach a non existing floor\n");}
this->waiting_floors[origin]++;//on ajoute à la liste des attentes
pthread_cond_wait(this->condition_floors[origin], this->mutex_cond_get_inside_elevator); pthread_cond_wait(this->condition_floors[origin], this->mutex_cond_get_inside_elevator);
elevator_number = this->get_inside_elevator(this, origin, passenger); elevator_number = this->get_inside_elevator(this, origin, passenger);
if (elevator_number != -1){ //passenger accepted in elevator if (elevator_number != -1){ //passenger accepted in elevator
if (passenger.type == RESIDENT) this->waiting_floors[origin]--;//on retire de la liste des attentes
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 (passenger.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_cond_get_outside_elevator); pthread_cond_wait(this->condition_floors[destination], this->mutex_cond_get_outside_elevator);
if (passenger.type == RESIDENT) this->elevators[elevator_number]->remove_passenger(this->elevators[elevator_number], passenger);
printf("Le résident %s sort de l'ascenseur %s à l'étage %d\n", passenger.resident->name,
this->elevators[elevator_number]->name, destination);
else if (passenger.type == VISITOR)
printf("Le visiteur %s sort de l'ascenseur %s à l'étage %d\n", passenger.visitor->name,
this->elevators[elevator_number]->name, destination);
}else{ }else{
if (passenger.type == RESIDENT) if (passenger->type == RESIDENT)
printf("Le résident %s à l'étage %d n'a pas pu rentrer dans un ascenseur. Préempté !\n", passenger.resident->name, origin); printf("Le résident %s à l'étage %d n'a pas pu rentrer dans un ascenseur. Préempté !\n", passenger->get_name(passenger), origin);
else if (passenger.type == VISITOR) else if (passenger->type == VISITOR)
printf("Le visiteur %s à l'étage %d n'a pas pu rentrer dans un ascenseur. Préempté !\n", passenger.visitor->name, origin); printf("Le visiteur %s à l'étage %d n'a pas pu rentrer dans un ascenseur. Préempté !\n", passenger->get_name(passenger), origin);
}//todo : else, remettre en attente ? //reloading fire
this->go_to_floor(this, origin, destination, passenger);
}
} }
@ -213,17 +236,23 @@ Building *_init_Building(char * residents_file, char * visitors_file){
Building * new_building = malloc_or_die(sizeof(Building)); Building * new_building = malloc_or_die(sizeof(Building));
char elevator_name[] = "@"; char elevator_name[] = "@";
int i; int i;
new_building->floors = FLOORS; new_building->floors = FLOORS;
for (i=0; i<FLOORS; i++)
new_building->waiting_floors[i] = 0;
pthread_mutex_init(&new_building->mutex_waiting_floors, NULL);
new_building->elevators = malloc_or_die(sizeof(Elevator*) * ELEVATOR_NB); new_building->elevators = malloc_or_die(sizeof(Elevator*) * ELEVATOR_NB);
new_building->mutex_cond_get_inside_elevator = malloc_or_die(sizeof(pthread_mutex_t)); 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_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)); new_building->mutex_func_get_inside_elevator = malloc_or_die(sizeof(pthread_mutex_t));
new_building->mutex_func_get_next_call = 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_inside_elevator, NULL);
pthread_mutex_init(new_building->mutex_cond_get_outside_elevator, NULL); pthread_mutex_init(new_building->mutex_cond_get_outside_elevator, NULL);
pthread_mutex_init(new_building->mutex_func_get_inside_elevator, NULL); pthread_mutex_init(new_building->mutex_func_get_inside_elevator, NULL);
pthread_mutex_init(new_building->mutex_func_get_next_call, NULL);
new_building->condition_floors = malloc_or_die(sizeof(pthread_cond_t*) * FLOORS); new_building->condition_floors = malloc_or_die(sizeof(pthread_cond_t*) * FLOORS);
new_building->residents = NEW(List); new_building->residents = NEW(List);
@ -240,12 +269,14 @@ Building *_init_Building(char * residents_file, char * visitors_file){
LINK_ALL(Building, new_building, LINK_ALL(Building, new_building,
parse_residents, parse_residents,
parse_visitors, parse_visitors,
get_inside_elevator, get_inside_elevator,
use_call_box, use_call_box,
go_to_floor, go_to_floor,
signal_elevator_at_floor get_next_call,
get_waiting_floors,
signal_elevator_at_floor
) )
if (residents_file != NULL) if (residents_file != NULL)

View File

@ -17,22 +17,27 @@
typedef struct o_Building { typedef struct o_Building {
PRIVATE int floors; PRIVATE int floors;
PRIVATE int waiting_floors[FLOORS];
PRIVATE List * residents; PRIVATE List * residents;
PRIVATE List * visitors; PRIVATE List * visitors;
PRIVATE Elevator ** elevators; PRIVATE Elevator ** elevators;
PRIVATE pthread_mutex_t mutex_waiting_floors;
PRIVATE pthread_mutex_t * mutex_cond_get_inside_elevator; PRIVATE pthread_mutex_t * mutex_cond_get_inside_elevator;
PRIVATE pthread_mutex_t * mutex_cond_get_outside_elevator; PRIVATE pthread_mutex_t * mutex_cond_get_outside_elevator;
PRIVATE pthread_mutex_t * mutex_func_get_inside_elevator; PRIVATE pthread_mutex_t * mutex_func_get_inside_elevator;
PRIVATE pthread_mutex_t * mutex_func_get_next_call;
PRIVATE pthread_cond_t ** condition_floors; PRIVATE pthread_cond_t ** condition_floors;
PRIVATE void (*parse_residents)(_THIS(Building), char * file); PRIVATE void (*parse_residents)(_THIS(Building), char * file);
PRIVATE void (*parse_visitors)(_THIS(Building), char * file); PRIVATE void (*parse_visitors)(_THIS(Building), char * file);
PRIVATE int (*get_inside_elevator)(_THIS(Building), int current_floor, Passenger passenger); PRIVATE int (*get_inside_elevator)(_THIS(Building), int current_floor, Passenger * passenger);
PUBLIC int (*use_call_box)(_THIS(Building), char * resident_name); PUBLIC int (*use_call_box)(_THIS(Building), char * resident_name);
PUBLIC void (*signal_elevator_at_floor)(_THIS(Building), int floor); PUBLIC void (*signal_elevator_at_floor)(_THIS(Building), int floor);
PUBLIC int (*get_next_call)(_THIS(Building), int elevator_floor);
PUBLIC int* (*get_waiting_floors)(_THIS(Building));
SYNCHRONIZE PUBLIC void (*go_to_floor)(_THIS(Building), int origin, int destination, Passenger passenger); SYNCHRONIZE PUBLIC void (*go_to_floor)(_THIS(Building), int origin, int destination, Passenger * passenger);
DESTRUCTOR(Building); DESTRUCTOR(Building);
} Building; } Building;

View File

@ -4,6 +4,7 @@
#include <string.h> #include <string.h>
#include <math.h> #include <math.h>
#include <unistd.h>
#include "Elevator.h" #include "Elevator.h"
#include "../SharedData/SharedData.h" #include "../SharedData/SharedData.h"
@ -29,17 +30,35 @@ void _free__Elevator(THIS(Elevator)){
free(this); free(this);
} }
void add_passenger_Elevator(THIS(Elevator), Passenger passenger){ void add_passenger_Elevator(THIS(Elevator), Passenger * passenger){
pthread_mutex_lock(&this->mutex_passengers); pthread_mutex_lock(&this->mutex_passengers);
this->passengers->insert_tail(this->passengers, ((void *)&passenger), sizeof(Passenger)); this->passengers->insert_tail(this->passengers, ((void *)passenger), sizeof(Passenger));
printf("L'ascenseur %s recoit le visiteur %s\nIl y a maintenant %d passagers dans l'ascenseur %s\n", this->name, printf("L'ascenseur %s recoit le visiteur %s à l'étage %d\nIl y a maintenant %d passagers dans l'ascenseur %s\n", this->name,
passenger.type == VISITOR ? passenger.visitor->get_name(passenger.visitor) : passenger.resident->get_name(passenger.resident), passenger->get_name(passenger),
this->passengers->get_size(this->passengers), this->name); this->get_floor(this),
this->passengers->get_size(this->passengers), this->name);
if (this->passengers->get_size(this->passengers) >= MAX_ELEVATOR_CAPACITY) if (this->passengers->get_size(this->passengers) >= MAX_ELEVATOR_CAPACITY)
this->set_state(this, SLEEPING); this->set_state(this, SLEEPING);
pthread_mutex_unlock(&this->mutex_passengers); pthread_mutex_unlock(&this->mutex_passengers);
} }
/**
* Remove a passenger from an elevator. Efectively remove him from the elevator's passenger list.
* @SYNCHRONIZED passengers : this elevator's list of passenger is accessed via mutex
* @param THIS(Elevator) : this
* @param passenger : the passenger to remove
*/
void remove_passenger_Elevator(THIS(Elevator), Passenger * passenger){
pthread_mutex_lock(&this->mutex_passengers);
if (passenger->type == RESIDENT)
printf("Le résident %s sort de l'ascenseur %s à l'étage %d\n", passenger->get_name(passenger), this->name, this->get_floor(this));
else if (passenger->type == VISITOR)
printf("Le visiteur %s sort de l'ascenseur %s à l'étage %d\n", passenger->get_name(passenger), this->name, this->get_floor(this));
this->passengers->remove_inside(this->passengers, passenger, passenger->compare);
printf("Ascenseur %s : j'ai encore %d passagers\n", this->name, this->passengers->get_size(this->passengers));
pthread_mutex_unlock(&this->mutex_passengers);
}
int get_number_of_passengers_Elevator(THIS(Elevator)){ int get_number_of_passengers_Elevator(THIS(Elevator)){
int num; int num;
pthread_mutex_lock(&this->mutex_passengers); pthread_mutex_lock(&this->mutex_passengers);
@ -51,10 +70,10 @@ int get_number_of_passengers_Elevator(THIS(Elevator)){
/** /**
* Search the closest floor where the elevator should stop. In practice ( for now ), it means that this function returns the closest floor amongs it's passengers destinations. * Search the closest floor where the elevator should stop. In practice ( for now ), it means that this function returns the closest floor amongs it's passengers destinations.
* @THIS(Elevator) a pointer the current Elevator * @THIS(Elevator) a pointer the current Elevator
* @return the found floor as an int. If no passengers are in the elevator, returns 0 ( as the elevator should come back to floor 0 ). * @return the found floor as an int. If no passengers are in the elevator, returns -1.
* @todo should consider passenger calling the elevator * @todo should consider passenger calling the elevator
*/ */
int get_next_floor_Elevator(THIS(Elevator)){ int get_next_passenger_stop_Elevator(THIS(Elevator)){
int i, next_floor, temp_floor; int i, next_floor, temp_floor;
float min_diff; float min_diff;
Element* temp_element; Element* temp_element;
@ -63,13 +82,13 @@ int get_next_floor_Elevator(THIS(Elevator)){
pthread_mutex_lock(&this->mutex_floor); pthread_mutex_lock(&this->mutex_floor);
min_diff = INFINITY; min_diff = INFINITY;
next_floor = 0; next_floor = -1;
for(i=0;i<this->passengers->get_size(this->passengers);i++){ for(i=0;i<this->passengers->get_size(this->passengers);i++){
temp_element = this->passengers->get_element(this->passengers, i); temp_element = this->passengers->get_element(this->passengers, i);
temp_passenger = (Passenger*) temp_element->get_data(temp_element); temp_passenger = (Passenger*) temp_element->get_data(temp_element);
temp_floor = temp_passenger->type == RESIDENT ? temp_passenger->resident->destination : temp_passenger->visitor->destination; temp_floor = temp_passenger->get_destination(temp_passenger);
if(abs(this->floor - temp_floor) < min_diff && temp_floor != this->floor){ if(abs(this->floor - temp_floor) < min_diff /*&& temp_floor != this->floor*/){
min_diff = abs(this->floor - temp_floor); min_diff = abs(this->floor - temp_floor);
next_floor = temp_floor; next_floor = temp_floor;
} }
@ -105,13 +124,31 @@ void *runnable_Elevator(void * void_this){
/* This is where the thread logic will be implemented */ /* This is where the thread logic will be implemented */
Elevator * this = (Elevator*) void_this; Elevator * this = (Elevator*) void_this;
SharedData * data = GET_INSTANCE(SharedData); SharedData * data = GET_INSTANCE(SharedData);
Building * building = data->main_building;
int next_call;
int next_passenger_stop;
AGENT_OPTIONS AGENT_OPTIONS
printf("Je suis l'ascenseur %s\n", this->name); printf("Initialisation de l'ascenseur %s\n", this->name);
for (;;){ for (;;){
data->main_building->signal_elevator_at_floor(data->main_building, this->get_floor(this)); building->signal_elevator_at_floor(data->main_building, this->get_floor(this));
this->set_floor(this, this->get_next_floor(this)); if(this->target_floor == this->get_floor(this)){
if((next_passenger_stop = this->get_next_passenger_stop(this)) != -1){
this->target_floor = next_passenger_stop;
}else if((next_call = building->get_next_call(building, this->floor)) != -1){
this->target_floor = next_call;
}
}
if(this->get_floor(this) != this->target_floor){
this->set_floor(this, this->target_floor);
printf("Ascenseur %s en route vers l'étage %d\n", this->name, this->target_floor);
/*printf("DEBUG : Next passenger stop : %d\n", next_passenger_stop);
printf("DEBUG : Next call from user : %d\n", next_call);
printf("\n\n");*/
fflush(stdout);
}
} }
return NULL; return NULL;
@ -121,21 +158,23 @@ Elevator *_init_Elevator(char * name){
Elevator * new_elevator = malloc_or_die(sizeof(Elevator)); Elevator * new_elevator = malloc_or_die(sizeof(Elevator));
new_elevator->name = strdup(name); new_elevator->name = strdup(name);
new_elevator->passengers = NEW(List); new_elevator->passengers = NEW(List);
new_elevator->target_floor = 0;
pthread_mutex_init(&new_elevator->mutex_passengers, NULL); pthread_mutex_init(&new_elevator->mutex_passengers, NULL);
pthread_mutex_init(&new_elevator->mutex_state, NULL); pthread_mutex_init(&new_elevator->mutex_state, NULL);
pthread_mutex_init(&new_elevator->mutex_floor, NULL); pthread_mutex_init(&new_elevator->mutex_floor, NULL);
LINK_ALL(Elevator, new_elevator, LINK_ALL(Elevator, new_elevator,
runnable, runnable,
get_number_of_passengers, get_number_of_passengers,
get_next_floor, get_next_passenger_stop,
can_get_inside, can_get_inside,
add_passenger, remove_passenger,
get_state, add_passenger,
set_state, get_state,
get_floor, set_state,
set_floor, get_floor,
repair set_floor,
repair
); );
new_elevator->set_floor(new_elevator, 0); new_elevator->set_floor(new_elevator, 0);

View File

@ -20,6 +20,7 @@ typedef struct o_Elevator {
PRIVATE List * passengers; PRIVATE List * passengers;
PRIVATE char * name; PRIVATE char * name;
PRIVATE int floor; PRIVATE int floor;
PRIVATE int target_floor;
PRIVATE pthread_mutex_t mutex_passengers; PRIVATE pthread_mutex_t mutex_passengers;
PRIVATE pthread_mutex_t mutex_state; PRIVATE pthread_mutex_t mutex_state;
PRIVATE pthread_mutex_t mutex_floor; PRIVATE pthread_mutex_t mutex_floor;
@ -28,11 +29,12 @@ typedef struct o_Elevator {
SYNCHRONIZE PRIVATE void (*set_state)(_THIS(Elevator), ELEVATOR_STATE var); SYNCHRONIZE PRIVATE void (*set_state)(_THIS(Elevator), ELEVATOR_STATE var);
SYNCHRONIZE PRIVATE void (*set_floor)(_THIS(Elevator), int var); SYNCHRONIZE PRIVATE void (*set_floor)(_THIS(Elevator), int var);
SYNCHRONIZE PRIVATE int (*get_next_floor)(_THIS(Elevator)); SYNCHRONIZE PRIVATE int (*get_next_passenger_stop)(_THIS(Elevator));
SYNCHRONIZE PUBLIC void (*repair)(_THIS(Elevator)); SYNCHRONIZE PUBLIC void (*repair)(_THIS(Elevator));
SYNCHRONIZE PUBLIC int (*get_number_of_passengers)(_THIS(Elevator)); SYNCHRONIZE PUBLIC int (*get_number_of_passengers)(_THIS(Elevator));
SYNCHRONIZE PUBLIC void (*add_passenger)(_THIS(Elevator), Passenger passenger); SYNCHRONIZE PUBLIC void (*remove_passenger) (_THIS(Elevator), Passenger * passenger);
SYNCHRONIZE PUBLIC void (*add_passenger)(_THIS(Elevator), Passenger * passenger);
SYNCHRONIZE PUBLIC ELEVATOR_STATE (*get_state)(_THIS(Elevator)); SYNCHRONIZE PUBLIC ELEVATOR_STATE (*get_state)(_THIS(Elevator));
SYNCHRONIZE PUBLIC int (*get_floor)(_THIS(Elevator)); SYNCHRONIZE PUBLIC int (*get_floor)(_THIS(Elevator));
SYNCHRONIZE PUBLIC int (*can_get_inside)(_THIS(Elevator), int floor); SYNCHRONIZE PUBLIC int (*can_get_inside)(_THIS(Elevator), int floor);

View File

@ -140,6 +140,56 @@ void insert_inside_List(THIS(List), void * data, size_t data_size, int index){
} }
/**
* Remove element with specified data in the list
* @param this THIS(List)
* @param data_to_remove pointer to data you want to remove
* @param compare a compare function, return true or false and takes two void * pointers
* @return true or false, depending on if the element was found in the list
*/
int remove_inside_List(THIS(List), void * data_to_remove, int (*compare)(void*, void*)){
Element* temp_element = this->head;
while(temp_element != NULL){
if(compare(data_to_remove, temp_element->data)){
if(temp_element == this->head){
this->remove_head(this);
}else if (temp_element == this->tail){
this->remove_tail(this);
}else{
if(temp_element->previous != NULL)
temp_element->previous->next = temp_element->next;
if(temp_element->next != NULL)
temp_element->next->previous = temp_element->previous;
DELETE(temp_element);
}
return 1;
}
temp_element = temp_element->next;
}
return 0;
}
/**
* Check if data_to_find exist in list
* @param this THIS(List)
* @param data_to_find pointer to data you want to find inside
* @param compare a compare function, return true or false and takes two void * pointers
* @return true or false if the element is within the list or not
*/
int contains_List(THIS(List), void * data_to_find, int (*compare)(void *, void *)){
Element * current = this->head;
while (current != NULL){
if (compare(data_to_find, current->data)){
return 1;
}
current = current->next;
}
return 0;
}
void remove_head_List(THIS(List)){ void remove_head_List(THIS(List)){
DELETE(this->head); DELETE(this->head);
} }
@ -156,21 +206,23 @@ List *_init_List(){
l->custom_free = free; l->custom_free = free;
LINK_ALL(List, l, LINK_ALL(List, l,
get_head, get_head,
get_tail, get_tail,
get_size, get_size,
get_head_data, get_head_data,
get_tail_data, get_tail_data,
get_element, get_element,
get_element_data, get_element_data,
set_custom_free, set_custom_free,
insert_inside, remove_inside,
insert_tail, insert_inside,
insert_head, insert_tail,
clear_custom, insert_head,
clear, clear_custom,
remove_head, clear,
remove_tail remove_head,
remove_tail,
contains
) )
return l; return l;
} }

View File

@ -29,6 +29,8 @@ struct o_List {
PUBLIC void* (*get_element_data)(_THIS(List), int index); PUBLIC void* (*get_element_data)(_THIS(List), int index);
PUBLIC int (*get_size)(_THIS(List)); PUBLIC int (*get_size)(_THIS(List));
PUBLIC int (*contains)(_THIS(List), void * data_to_find, int (*compare)(void *, void *));
PUBLIC int (*remove_inside)(_THIS(List), void * data_to_remove, int (*compare)(void*, void*));
PUBLIC void (*set_custom_free)(_THIS(List), void (*custom_free)(void *)); PUBLIC void (*set_custom_free)(_THIS(List), void (*custom_free)(void *));
PUBLIC void (*insert_inside)(_THIS(List), void * data, size_t data_size, int index); PUBLIC void (*insert_inside)(_THIS(List), void * data, size_t data_size, int index);

View File

@ -4,6 +4,19 @@
#include "Passenger.h" #include "Passenger.h"
int compare_Passenger(void * passenger1, void * passenger2){
return (strcmp(((Passenger*) passenger1)->get_name((Passenger*) passenger1),
((Passenger*) passenger2)->get_name((Passenger*) passenger2)) == 0);
}
int get_destination_Passenger(THIS(Passenger)){
if (this->type == RESIDENT)
return this->resident->get_destination(this->resident);
if (this->type == VISITOR)
return this->visitor->get_destination(this->visitor);
return -1;
}
int get_id_Passenger(THIS(Passenger)){ int get_id_Passenger(THIS(Passenger)){
if (this->type == RESIDENT) if (this->type == RESIDENT)
return this->resident->get_id(this->resident); return this->resident->get_id(this->resident);
@ -33,22 +46,25 @@ void _free__Passenger(THIS(Passenger)){
free(this); free(this);
} }
Passenger *_init_Passenger(void *passenger, PASSENGER_TYPE type){ Passenger *_init_Passenger(void* passenger_data, PASSENGER_TYPE type){
Passenger * new_passenger = malloc_or_die(sizeof(Passenger)); Passenger * new_passenger = malloc_or_die(sizeof(Passenger));
new_passenger->resident = NULL; new_passenger->resident = NULL;
new_passenger->visitor = NULL; new_passenger->visitor = NULL;
new_passenger->type = type; new_passenger->type = type;
if (type == RESIDENT) if (type == RESIDENT)
new_passenger->resident = (Resident*) passenger; new_passenger->resident = (Resident*) passenger_data;
if (type == VISITOR) if (type == VISITOR)
new_passenger->visitor = (Visitor*) passenger; new_passenger->visitor = (Visitor*) passenger_data;
//new_passenger->compare = compare_Passenger;
LINK_ALL(Passenger, new_passenger, LINK_ALL(Passenger, new_passenger,
get_id, get_id,
get_name, get_name,
runnable get_destination,
compare,
runnable
) )
return new_passenger; return new_passenger;

View File

@ -7,6 +7,7 @@
#include "../Resident/Resident.h" #include "../Resident/Resident.h"
#include "../Visitor/Visitor.h" #include "../Visitor/Visitor.h"
#include <string.h>
typedef enum {RESIDENT, VISITOR} PASSENGER_TYPE; typedef enum {RESIDENT, VISITOR} PASSENGER_TYPE;
@ -19,11 +20,13 @@ typedef struct o_Passenger {
PUBLIC char * (*get_name)(_THIS(Passenger)); PUBLIC char * (*get_name)(_THIS(Passenger));
PUBLIC int (*get_id)(_THIS(Passenger)); PUBLIC int (*get_id)(_THIS(Passenger));
PUBLIC int (*get_destination)(_THIS(Passenger));
PUBLIC void * (*runnable)(void* void_this); PUBLIC void * (*runnable)(void* void_this);
PUBLIC int (*compare)(void * passenger1, void * passenger2);//yeah I know, but i needed int (*) (void*, void*)
DESTRUCTOR(Passenger); DESTRUCTOR(Passenger);
} Passenger; } Passenger;
Passenger *_init_Passenger(void *passenger, PASSENGER_TYPE type); Passenger *_init_Passenger(void* passenger_data, PASSENGER_TYPE type);
#endif //LO41_PASSENGER_H #endif //LO41_PASSENGER_H

View File

@ -5,24 +5,35 @@
#include <string.h> #include <string.h>
#include <pthread.h> #include <pthread.h>
#include "Resident.h" #include "Resident.h"
#include "../SharedData/SharedData.h"
GETTER(Resident, char *, name); GETTER(Resident, char *, name);
GETTER(Resident, int, destination);
GETTER(Resident, int, id); GETTER(Resident, int, id);
GETTER(Resident, int, apartment_floor); GETTER(Resident, int, apartment_floor);
void * runnable_Resident(void * void_this){ void * runnable_Resident(void * void_this){
Resident * this = (Resident*) void_this; Resident * this = (Resident*) void_this;
SharedData* data = GET_INSTANCE(SharedData);
Passenger * passenger = NEW(Passenger, (void*) this, RESIDENT);
AGENT_OPTIONS AGENT_OPTIONS;
this->passenger = passenger;
passenger->resident = this;
passenger->type = RESIDENT;
printf("Je suis le resident %s et je suis a l'etage %d en direction de l'etage %d\n", printf("Je suis le resident %s et je suis a l'etage %d en direction de l'etage %d\n",
this->name, this->apartment_floor, this->destination); this->name, this->apartment_floor, this->destination);
data->main_building->go_to_floor(data->main_building, this->position, this->destination, passenger);
return NULL; return NULL;
} }
void _free__Resident(THIS(Resident)){ void _free__Resident(THIS(Resident)){
if (this->name != NULL) if (this->name != NULL)
free(this->name); free(this->name);
if(this->passenger != NULL)
free(this->passenger);
free(this); free(this);
} }
@ -34,12 +45,14 @@ Resident *_init_Resident(int id, char* name, int apartment_floor, int destinatio
new_resident->apartment_floor = apartment_floor; new_resident->apartment_floor = apartment_floor;
new_resident->position = new_resident->apartment_floor; new_resident->position = new_resident->apartment_floor;
new_resident->destination = destination; new_resident->destination = destination;
new_resident->passenger = NULL;
LINK_ALL(Resident, new_resident, LINK_ALL(Resident, new_resident,
get_name, get_name,
get_id, get_destination,
runnable, get_id,
get_apartment_floor runnable,
get_apartment_floor
) )
return new_resident; return new_resident;

View File

@ -13,11 +13,13 @@ typedef struct o_Resident {
PRIVATE int destination; PRIVATE int destination;
PRIVATE int position; PRIVATE int position;
PRIVATE char* name; PRIVATE char* name;
PRIVATE void* passenger;
PUBLIC void * (*runnable)(void * void_this); PUBLIC void * (*runnable)(void * void_this);
PUBLIC char * (*get_name)(_THIS(Resident)); PUBLIC char * (*get_name)(_THIS(Resident));
PUBLIC int (*get_id)(_THIS(Resident)); PUBLIC int (*get_id)(_THIS(Resident));
PUBLIC int (*get_apartment_floor)(_THIS(Resident)); PUBLIC int (*get_apartment_floor)(_THIS(Resident));
PUBLIC int (*get_destination)(_THIS(Resident));
DESTRUCTOR(Resident); DESTRUCTOR(Resident);
} Resident; } Resident;

View File

@ -7,17 +7,18 @@
#include <string.h> #include <string.h>
GETTER(Visitor, char*, name); GETTER(Visitor, char*, name);
GETTER(Visitor, int, destination);
GETTER(Visitor, int, id); GETTER(Visitor, int, id);
void * runnable_Visitor(void * void_this){ void * runnable_Visitor(void * void_this){
Visitor *this = (Visitor*) void_this; Visitor *this = (Visitor*) void_this;
SharedData * data = GET_INSTANCE(SharedData); SharedData * data = GET_INSTANCE(SharedData);
Passenger passenger; Passenger * passenger = NEW(Passenger, (void*) this, VISITOR);
AGENT_OPTIONS AGENT_OPTIONS;
this->passenger = (void*) passenger;
passenger.visitor = this; passenger->visitor = this;
passenger.type = VISITOR;
printf("Bonjour, je suis %s et je souhaite rendre visite a %s\n", this->name, this->contact_name); printf("Bonjour, je suis %s et je souhaite rendre visite a %s\n", this->name, this->contact_name);
printf("Bip, %s appel a l'interphone\n%s habite a l'etage %d\n", this->name, this->contact_name, (this->destination = data->use_call_box(data, this->contact_name))); printf("Bip, %s appel a l'interphone\n%s habite a l'etage %d\n", this->name, this->contact_name, (this->destination = data->use_call_box(data, this->contact_name)));
@ -30,6 +31,8 @@ void _free__Visitor(THIS(Visitor)){
free(this->name); free(this->name);
if (this->contact_name != NULL) if (this->contact_name != NULL)
free(this->contact_name); free(this->contact_name);
if (this->passenger != NULL)
free(this->passenger);
free(this); free(this);
} }
@ -39,6 +42,7 @@ Visitor *_init_Visitor(int id, char* name, char * contact_name){
new_visitor->id = id; new_visitor->id = id;
new_visitor->position = 0; new_visitor->position = 0;
new_visitor->destination = -1; new_visitor->destination = -1;
new_visitor->passenger = NULL;
if (contact_name != NULL) if (contact_name != NULL)
new_visitor->contact_name = strdup(contact_name); new_visitor->contact_name = strdup(contact_name);
@ -46,9 +50,10 @@ Visitor *_init_Visitor(int id, char* name, char * contact_name){
new_visitor->contact_name = NULL; new_visitor->contact_name = NULL;
LINK_ALL(Visitor, new_visitor, LINK_ALL(Visitor, new_visitor,
get_name, get_name,
get_id, get_destination,
runnable get_id,
runnable
); );
return new_visitor; return new_visitor;

View File

@ -13,10 +13,12 @@ typedef struct o_Visitor {
PRIVATE char * contact_name; PRIVATE char * contact_name;
PRIVATE int position; PRIVATE int position;
PRIVATE int destination; PRIVATE int destination;
PRIVATE void * passenger;
PUBLIC void * (*runnable)(void* void_this); PUBLIC void * (*runnable)(void* void_this);
PUBLIC char * (*get_name)(_THIS(Visitor)); PUBLIC char * (*get_name)(_THIS(Visitor));
PUBLIC int (*get_id)(_THIS(Visitor)); PUBLIC int (*get_id)(_THIS(Visitor));
PUBLIC int (*get_destination)(_THIS(Visitor));
DESTRUCTOR(Visitor); DESTRUCTOR(Visitor);
} Visitor; } Visitor;