// function to test threads // This function will run concurrently. void* avatar(void* ptr) { // Initial variables int sockfd = 0; struct sockaddr_in servaddr; avatarInfo a = *((avatarInfo *) ptr); fprintf(a.pLog, "\n\nTHREAD FOR %i", a.avID); ///////////////////////// create socket //Create a socket for the client //If sockfd<0 there was an error in the creation of the socket if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) <0) { perror("Problem in creating the socket"); exit(2); } //Creation of the socket memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr= inet_addr(a.ip); servaddr.sin_port = htons(a.MazePort); //convert to big-endian order //Connection of the client to the socket int connected = connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)); if (connected <0) { perror("Problem in connecting to the server"); exit(3); } fprintf(a.pLog, "Avatar %d connected to socket: %i\n", a.avID, connected); //////////////////////////// send initial message AM_Message *ready = calloc(1, sizeof(AM_Message)); if (!ready) { perror("No memory\n"); exit(4); } ready->type = htonl(AM_AVATAR_READY); ready->avatar_ready.AvatarId = htonl(a.avID); //send ready message to server int sent = send(sockfd, ready, sizeof(AM_Message), 0); fprintf(a.pLog, "Avatar ready message sent: %i, for av %i\n", sent, a.avID); free(ready); sleep(1); ////////////////////////// initialize a move message and a rec message AM_Message *rec_message = calloc(1, sizeof(AM_Message)); if(!rec_message) { perror("\nNo memory"); exit(4); } ////////////////////////////////// listen to server while (1) { memset(rec_message, 0, sizeof(AM_Message)); //printf("\n thread %i, socket %i", a.avID, sockfd); int x = recv(sockfd, rec_message, sizeof(AM_Message), 0); if ( x== 0) { //error: server terminated prematurely //printf("\n server error"); return NULL; } ///////////////////////////////////////// if turnID matches avID, make a move if(ntohl(rec_message->type) == AM_AVATAR_TURN) { pthread_mutex_lock(&turn_lock); // if turn id is my id int move = -1; if(ntohl(rec_message->avatar_turn.TurnId) == a.avID) { // write board to the log fprintf(a.pLog, "\n\nits my turn: %i", a.avID); fprintf(a.pLog, "\nCurrent board:"); XYPos pos; //look through the positions received from the server and add them to the Avatars, if they aren't there, or use them to update the maze based on the last move for(int b = 0; b < a.nAvatars; b++) { pos.x = ntohl(rec_message->avatar_turn.Pos[b].x); pos.y = ntohl(rec_message->avatar_turn.Pos[b].y); fprintf(a.pLog, "\nPosition of avatar %i - x: %i y: %i", b,pos.x, pos.y); //printf("\nCurrent position of avatar %i - x: %i y: %i", b,pos.x, pos.y); //printf("\nAvatar %d: pos.x: %i, pos.y: %i, direction: %d, last_move: %d \n", b, Avatars[b].pos.x, Avatars[b].pos.y, Avatars[b].direction, Avatars[b].last_move); if (Avatars[b].last_move == -1) { //if the avatar doesn't have a position yet Avatars[b].pos = pos; Avatars[b].last_move = M_NULL_MOVE; } else if (Avatars[b].last_move != M_NULL_MOVE) { if ((pos.x == Avatars[b].pos.x) && (pos.y == Avatars[b].pos.y)) { fprintf(a.pLog, "Avatar %d encountered a wall and did not move.", b); AddWall(Avatars[b].pos.y, Avatars[b].pos.x, Avatars[b].last_move, 1); Avatars[b].last_move = M_NULL_MOVE; } else { fprintf(a.pLog, "Avatar %d moved successfully.", b); switch(Avatars[b].last_move) { case M_NORTH: if (maze->maze[Avatars[b].pos.y][Avatars[b].pos.x].north_wall != 2) { AddWall(Avatars[b].pos.y, Avatars[b].pos.x, Avatars[b].last_move, 0); } break; case M_SOUTH: if (maze->maze[Avatars[b].pos.y][Avatars[b].pos.x].south_wall != 2) { AddWall(Avatars[b].pos.y, Avatars[b].pos.x, Avatars[b].last_move, 0); } break; case M_EAST: if (maze->maze[Avatars[b].pos.y][Avatars[b].pos.x].east_wall != 2) { AddWall(Avatars[b].pos.y, Avatars[b].pos.x, Avatars[b].last_move, 0); } break; case M_WEST: if (maze->maze[Avatars[b].pos.y][Avatars[b].pos.x].west_wall != 2) { AddWall(Avatars[b].pos.y, Avatars[b].pos.x, Avatars[b].last_move, 0); } break; default: AddWall(Avatars[b].pos.y, Avatars[b].pos.x, Avatars[b].last_move, 0); break; } Avatars[b].pos = pos; Avatars[b].direction = Avatars[b].last_move; Avatars[b].last_move = M_NULL_MOVE; } } } ////////////////graphics//////////////// //initscr(); clear(); raw(); //start_color(); create_border(maze->num_col, maze->num_row); draw_inside(maze); //draw_fakes(maze); int f; for (f = 0; f<a.nAvatars; f++) { draw_avatar(2*Avatars[f].pos.y+1, 2*Avatars[f].pos.x+1); } //unsigned int microseconds; //microseconds = 200; //usleep(microseconds); refresh(); /* Determine the direction of the move for the current Avatar */ /* Avatar 0 has a fixed location - it never moves */ if (a.avID == 0) { if(!final_destination) { final_destination = (XYPos *) calloc(1, sizeof(XYPos)); final_destination->x = Avatars[a.avID].pos.x; final_destination->y = Avatars[a.avID].pos.y; } move = M_NULL_MOVE; } // if(!final_destination){ // for(int i = 0; i < a.nAvatars; i++){ // if (i == a.avID) continue; // //if the Avatar is in the same place as another Avatar, save position as final_destination // if((Avatars[i].pos.x == Avatars[a.avID].pos.x) && (Avatars[i].pos.y == Avatars[a.avID].pos.y)){ // final_destination = (XYPos *) calloc(1, sizeof(XYPos)); // final_destination->x = Avatars[a.avID].pos.x; // final_destination->y = Avatars[a.avID].pos.y; // move = M_NULL_MOVE; // break; // } // } // } /* Determine the direction of the move for Avatars that aren't Avatar 0 */ //if Avatar is at final_destination, it should not move if((final_destination) && (Avatars[a.avID].pos.x == final_destination->x) && (Avatars[a.avID].pos.y == final_destination ->y)) { move = M_NULL_MOVE; } else { //if the Avatar is alone, use the rightHandRule to determine the next move move = rightHandRule(Avatars[a.avID]); } //temporary fix to diagnose the initial -1 rightHandRule return if(move == -1) { ClearFakeWalls(Avatars[a.avID].pos.y, Avatars[a.avID].pos.x); move = rightHandRule(Avatars[a.avID]); move = (move == -1) ? M_NULL_MOVE : move; } Avatars[a.avID].last_move = move; //int move = rand() % 4; // write move to the log fprintf(a.pLog, "\nMove: %i", move); //printf("\nMove: %i", move); //send a move message for the current avatar AM_Message *ready = calloc(1, sizeof(AM_Message)); if (!ready) { perror("No memory\n"); exit(4); } ready->type = htonl(AM_AVATAR_MOVE); ready->avatar_move.AvatarId = htonl(a.avID); ready->avatar_move.Direction =htonl(move); //send ready message to server int sent = send(sockfd, ready, sizeof(AM_Message), 0); fprintf(a.pLog, "\nAvatar move message sent: %i, for av %i", sent, a.avID); free(ready); //sleep(1); } pthread_mutex_unlock(&turn_lock); } // else if the message is success, break else if(ntohl(rec_message->type) == AM_MAZE_SOLVED) { pthread_mutex_lock(&solved_lock); if(!thread_return) { time_t myTime; char buff[100]; thread_return = (char *) calloc(100, sizeof(char)); myTime = time(NULL); strftime(buff, 100, "%a %d %Y, %H:%M", localtime(&myTime)); //printf("%s\n", buff); sprintf(thread_return, "\nMaze Solved on %s!\n", buff); //printf("\nSolved!\n"); //free(rec_message); //free(ptr); } //stop at solution, wait for an input to end graphics //refresh(); //sleep(1); //clear(); //printw("Maze solved!"); //getch(); //clear(); //endwin(); //delwin(stdscr); if(a.avID == 0) { //stop at solution, wait for an input to end graphics refresh(); sleep(1); clear(); printw("Maze solved!"); getch(); clear(); //endwin(); } pthread_mutex_unlock(&solved_lock); break; } else if(ntohl(rec_message->type) == AM_TOO_MANY_MOVES) { pthread_mutex_lock(&too_many_moves_lock); printf("\nToo many moves! You lose.\n"); //fprintf(a.pLog,"\nToo many moves! You lose.\n"); thread_return = "\nToo many moves! You lose.\n"; //free(rec_message); //free(ptr); pthread_mutex_unlock(&too_many_moves_lock); break; } else if(IS_AM_ERROR(ntohl(rec_message->type))) { pthread_mutex_lock(&error_lock); thread_return = (char *) calloc(100, sizeof(char)); printf("\nReceived Error code\n"); sprintf(thread_return, "\nReceived Error code: %u\n", ntohl(rec_message->type)); //free(rec_message); //free(ptr); pthread_mutex_unlock(&error_lock); break; } } //CleanupMaze(); free(rec_message); free(ptr); pthread_exit(thread_return); }
static struct weston_compositor * wayland_compositor_create(struct wl_display *display, int width, int height, const char *display_name, int *argc, char *argv[], struct weston_config *config) { struct wayland_compositor *c; struct wl_event_loop *loop; int fd; c = malloc(sizeof *c); if (c == NULL) return NULL; memset(c, 0, sizeof *c); if (weston_compositor_init(&c->base, display, argc, argv, config) < 0) goto err_free; c->parent.wl_display = wl_display_connect(display_name); if (c->parent.wl_display == NULL) { weston_log("failed to create display: %m\n"); goto err_compositor; } wl_list_init(&c->input_list); c->parent.registry = wl_display_get_registry(c->parent.wl_display); wl_registry_add_listener(c->parent.registry, ®istry_listener, c); wl_display_dispatch(c->parent.wl_display); c->base.wl_display = display; if (gl_renderer_create(&c->base, c->parent.wl_display, gl_renderer_alpha_attribs, NULL) < 0) goto err_display; c->base.destroy = wayland_destroy; c->base.restore = wayland_restore; c->border.top = 30; c->border.bottom = 24; c->border.left = 25; c->border.right = 26; /* requires border fields */ if (wayland_compositor_create_output(c, width, height) < 0) goto err_gl; /* requires gl_renderer_output_state_create called * by wayland_compositor_create_output */ create_border(c); loop = wl_display_get_event_loop(c->base.wl_display); fd = wl_display_get_fd(c->parent.wl_display); c->parent.wl_source = wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE, wayland_compositor_handle_event, c); if (c->parent.wl_source == NULL) goto err_gl; wl_event_source_check(c->parent.wl_source); return &c->base; err_gl: c->base.renderer->destroy(&c->base); err_display: wl_display_disconnect(c->parent.wl_display); err_compositor: weston_compositor_shutdown(&c->base); err_free: free(c); return NULL; }