template <typename T> inline _3dArray<T>::_3dArray(const _3dArray &other) { if (!other.is_empty()) { init_memory(other.m_extents[0], other.m_extents[1], other.m_extents[2]); std::copy(other.begin(), other.end(), m_storage); } else init_empty(); }
int init_none (guestfs_h *g) { /* XXX At some point in the distant past, InitNone and InitEmpty * became folded together as the same thing. Really we should make * InitNone do nothing at all, but the tests may need to be checked * to make sure this is OK. */ return init_empty (g); }
int init_partition (guestfs_h *g) { if (init_empty (g) == -1) return -1; if (guestfs_part_disk (g, "/dev/sda", "mbr") == -1) return -1; return 0; }
int init_scratch_fs (guestfs_h *g) { if (init_empty (g) == -1) return -1; if (guestfs_mount (g, "/dev/sdb1", "/") == -1) return -1; return 0; }
int init_iso_fs (guestfs_h *g) { if (init_empty (g) == -1) return -1; if (guestfs_mount_ro (g, "/dev/sdd", "/") == -1) return -1; return 0; }
/** * Constructor. * Create an image from a specially prepared constant array, with no copying. Will call ptr->incr(). * * @param ptr The literal - first two bytes should be 0xff, then width, 0, height, 0, and the bitmap. Width and height are 16 bit. The literal has to be 4-byte aligned. * * @code * static const uint8_t heart[] __attribute__ ((aligned (4))) = { 0xff, 0xff, 10, 0, 5, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, }; // a cute heart * MicroBitImage i((ImageData*)(void*)heart); * @endcode */ MicroBitImage::MicroBitImage(ImageData *p) { if(p == NULL) { init_empty(); return; } ptr = p; ptr->incr(); }
int init_gpt (guestfs_h *g) { if (init_empty (g) == -1) return -1; if (guestfs_part_disk (g, "/dev/sda", "gpt") == -1) return -1; return 0; }
ErrorStack SharedMemoryRepo::attach_shared_memories( uint64_t master_upid, Eid master_eid, SocId my_soc_id, EngineOptions* options) { deallocate_shared_memories(); std::string base = get_master_path(master_upid, master_eid); std::string global_memory_path = base + std::string("_global"); global_memory_.attach(global_memory_path); if (global_memory_.is_null()) { deallocate_shared_memories(); return ERROR_STACK(kErrorCodeSocShmAttachFailed); } // read the options from global_memory uint64_t xml_size = 0; std::memcpy(&xml_size, global_memory_.get_block(), sizeof(xml_size)); ASSERT_ND(xml_size > 0); std::string xml(global_memory_.get_block() + sizeof(xml_size), xml_size); CHECK_ERROR(options->load_from_string(xml)); my_soc_id_ = my_soc_id; init_empty(*options); set_global_memory_anchors(xml_size, *options, false); bool failed = false; for (uint16_t node = 0; node < soc_count_; ++node) { std::string node_memory_str = base + std::string("_node_") + std::to_string(node); node_memories_[node].attach(node_memory_str); std::string vpool_str = base + std::string("_vpool_") + std::to_string(node); volatile_pools_[node].attach(vpool_str); if (node_memories_[node].is_null() || volatile_pools_[node].is_null()) { failed = true; } else { set_node_memory_anchors(node, *options, false); } } if (failed) { if (!node_memories_[my_soc_id].is_null()) { // then we can at least notify the error via the shared memory change_child_status(my_soc_id, ChildEngineStatus::kFatalError); } deallocate_shared_memories(); return ERROR_STACK(kErrorCodeSocShmAttachFailed); } return kRetOk; }
inline void _3dArray<T>::set_size(size_t extent0, size_t extent1, size_t extent2) { if (extent0 * extent1 * extent2 == m_extents[0] * m_extents[1] * m_extents[2]) { m_extents[0] = extent0; m_extents[1] = extent1; m_extents[2] = extent2; } else { if (m_strict) throw std::runtime_error("_3dArray::set_size(): Changing the total " "number of elements stored in an array " "created in the strict mode is not allowed"); if (m_owns) { delete[] m_storage; m_storage = 0; } if (extent0 * extent1 * extent2 != 0) init_memory(extent0, extent1, extent2); else init_empty(); } }
/** * Internal constructor which provides sanity checking and initialises class properties. * * @param x the width of the image * * @param y the height of the image * * @param bitmap an array of integers that make up an image. */ void MicroBitImage::init(const int16_t x, const int16_t y, const uint8_t *bitmap) { //sanity check size of image - you cannot have a negative sizes if(x < 0 || y < 0) { init_empty(); return; } // Create a copy of the array ptr = (ImageData*)malloc(sizeof(ImageData) + x * y); ptr->init(); ptr->width = x; ptr->height = y; // create a linear buffer to represent the image. We could use a jagged/2D array here, but experimentation // showed this had a negative effect on memory management (heap fragmentation etc). if (bitmap) this->printImage(x,y,bitmap); else this->clear(); }
/** * Constructor. * Create a blank bitmap representation of a given size. * * @param s A text based representation of the image given whitespace delimited numeric values. * * @code * MicroBitImage i("0,1,0,1,0\n1,0,1,0,1\n0,1,0,1,0\n1,0,1,0,1\n0,1,0,1,0\n"); // 5x5 image * @endcode */ MicroBitImage::MicroBitImage(const char *s) { int width = 0; int height = 0; int count = 0; int digit = 0; char parseBuf[10]; const char *parseReadPtr; char *parseWritePtr; uint8_t *bitmapPtr; if (s == NULL) { init_empty(); return; } // First pass: Parse the string to determine the geometry of the image. // We do this from first principles to avoid unecessary load of the strtok() libs etc. parseReadPtr = s; while (*parseReadPtr) { if (isdigit(*parseReadPtr)) { // Ignore numbers. digit = 1; } else if (*parseReadPtr =='\n') { if (digit) { count++; digit = 0; } height++; width = count > width ? count : width; count = 0; } else { if (digit) { count++; digit = 0; } } parseReadPtr++; } this->init(width, height, NULL); // Second pass: collect the data. parseReadPtr = s; parseWritePtr = parseBuf; bitmapPtr = this->getBitmap(); while (*parseReadPtr) { if (isdigit(*parseReadPtr)) { *parseWritePtr = *parseReadPtr; parseWritePtr++; } else { *parseWritePtr = 0; if (parseWritePtr > parseBuf) { *bitmapPtr = atoi(parseBuf); bitmapPtr++; parseWritePtr = parseBuf; } } parseReadPtr++; } }
/** * Get current ptr, do not decr() it, and set the current instance to empty color. * * This is to be used by specialized runtimes which pass ColorData around. */ ColorData *MicroBitColor::leakData() { ColorData* res = ptr; init_empty(); return res; }
/* * This handles the game for each client. */ void *game_runner(void *client_data_pointer) { /* Get client and details */ client_nfo client = *(client_nfo*)client_data_pointer; int socket_id = client.socket_id; int status = 1, client_status = 1, move = 0, ai_move = 0, read_size; uint32_t move_nbo, ai_move_nbo; c4_t board; /* To ensure memory is freed at the end */ pthread_detach(pthread_self()); /* Set-up the game */ srand(time(NULL)); init_empty(board, NO_PRINT); /* log that client is connected */ append_log(STATUS_CONNECTED, 0, &client, STATUS_CONNECTED, 0); /* Receive move from client */ while((read_size = recv(socket_id, &move_nbo, sizeof(uint32_t), 0)) > 0) { if(status < 0) break; /* Get move from (client move in network byte order)*/ move = ntohl(move_nbo); /* Make client move */ status = human_play(board, move, NO_PRINT); client_status = status; /* needed for log */ /* Make AI move if game is not over */ if(status > 0) { ai_move = suggest_move(board, RED); status = ai_play(board, ai_move, NO_PRINT); } /* log the moves */ append_log(status, ai_move, &client, client_status, move); /* If game is over, the old ai_move will be sent to client again but game will be terminated just after the client move is made in client program, so the ai move won't be made */ /* Send the AI move to client */ ai_move_nbo = htonl(ai_move); if(send(socket_id, &ai_move_nbo, sizeof(uint32_t), 0) < 0) { perror("send error"); break; } } if(read_size == 0) { /* Client has been disconnected from server */ if (status > 0) status = STATUS_ABNORMAL; } else if(read_size == -1) { perror("recv error"); if (status > 0) status = STATUS_ABNORMAL; } /* log any abnormal end of game */ if(status == STATUS_ABNORMAL) append_log(STATUS_ABNORMAL, 0, &client, STATUS_ABNORMAL, 0); free(client_data_pointer); return 0; }
ErrorStack SharedMemoryRepo::allocate_shared_memories( uint64_t upid, Eid eid, const EngineOptions& options) { deallocate_shared_memories(); init_empty(options); // We place a serialized EngineOptions in the beginning of shared memory. std::stringstream options_stream; options.save_to_stream(&options_stream); std::string xml(options_stream.str()); uint64_t xml_size = xml.size(); // construct unique meta files using PID. uint64_t global_memory_size = align_2mb(calculate_global_memory_size(xml_size, options)); std::string global_memory_path = get_self_path(upid, eid) + std::string("_global"); CHECK_ERROR(global_memory_.alloc(global_memory_path, global_memory_size, 0)); // from now on, be very careful to not exit without releasing this shared memory. set_global_memory_anchors(xml_size, options, true); global_memory_anchors_.master_status_memory_->status_code_ = MasterEngineStatus::kInitial; // copy the EngineOptions string into the beginning of the global memory std::memcpy(global_memory_.get_block(), &xml_size, sizeof(xml_size)); std::memcpy(global_memory_.get_block() + sizeof(xml_size), xml.data(), xml_size); // the following is parallelized uint64_t node_memory_size = align_2mb(calculate_node_memory_size(options)); uint64_t volatile_pool_size = static_cast<uint64_t>(options.memory_.page_pool_size_mb_per_node_) << 20; ErrorStack alloc_results[kMaxSocs]; std::vector< std::thread > alloc_threads; for (uint16_t node = 0; node < soc_count_; ++node) { alloc_threads.emplace_back(std::thread( SharedMemoryRepo::allocate_one_node, upid, eid, node, node_memory_size, volatile_pool_size, alloc_results + node, this)); } ErrorStack last_error; bool failed = false; for (uint16_t node = 0; node < soc_count_; ++node) { alloc_threads[node].join(); if (alloc_results[node].is_error()) { std::cerr << "[FOEDUS] Failed to allocate node shared memory for node-" << node << ". " << alloc_results[node] << std::endl; last_error = alloc_results[node]; failed = true; } } if (failed) { deallocate_shared_memories(); return last_error; } for (uint16_t node = 0; node < soc_count_; ++node) { set_node_memory_anchors(node, options, true); } return kRetOk; }
int transmit(void) { // Hide the cursor, and make sure it comes back before exiting. set_cursor(false); signal(SIGINT, sigint_handler); // Set up the keyboard listener. long time_unit = calibrate_listener(); if (time_unit == EOF) { return 0; } if (!spawn_listener()) { print_error("error creating thread"); return 1; } // Set up the circular buffers. int buf_size = number_of_columns(); char code_buf[buf_size]; char text_buf[buf_size]; struct Circle code_circ, text_circ; init_empty(&code_circ, code_buf, buf_size); init_empty(&text_circ, text_buf, buf_size); append(&code_circ, '*'); // Begin the main loop. Code code = 0; int code_size = 0; bool done = false; long time = current_millis(); enum { NONE, CHAR, WORD } wait_mode = NONE; while (!done) { // Check the state of the keyboard listener. long time_now = current_millis(); enum ListenerState state = get_listener_state(time_now); switch (state) { case LS_EOF: done = true; continue; case LS_NONE: break; case LS_DOWN: insert(&code_circ, '.'); wait_mode = NONE; code <<= 1; code_size++; break; case LS_REPEAT: insert(&code_circ, '-'); code |= 1; break; case LS_HOLD: case LS_HOLD_R: break; case LS_UP: append(&code_circ, '*'); time = time_now; wait_mode = CHAR; break; } // Check if enough time has passed to start a new character or word. long elapsed = time_now - time; switch (wait_mode) { case NONE: break; case CHAR: if (elapsed > TIME_BETWEEN_CHARS) { insert(&code_circ, ' '); append(&code_circ, '*'); wait_mode = WORD; char ch = INVALID_CODE; if (code_size <= MAX_SIZE) { code = add_size(code, code_size); char decoded = code_to_char(code); if (decoded) { ch = decoded; } } append(&text_circ, ch); code = 0; code_size = 0; } break; case WORD: if (elapsed > TIME_BETWEEN_WORDS) { insert(&code_circ, '/'); append(&code_circ, ' '); append(&code_circ, '*'); wait_mode = NONE; append(&text_circ, ' '); } break; } // Print the contents of both buffers. putchar('\r'); print_circle(&code_circ); fputs(" \n", stdout); print_circle(&text_circ); fputs(" \x1B[F", stdout); fflush(stdout); usleep(SLEEP_TIME_US); } cleanup(); return 0; }
void *thread_game(void *threadInfo) { struct readThreadParams *thisTheadInfo = (struct readThreadParams *)threadInfo; FILE *fptr = thisTheadInfo->filep; int sock = thisTheadInfo->sock; int status,n; //connect 4 variables c4_t board; int clientMove, serverMove; //uint16 used so all systems can play! uint16_t clientMoveNewtorked, serverMoveNetworked; printLog(fptr,thisTheadInfo,"client connected" ,-1,CLIENT); //connect 4 actions here srand(RSEED); //create a new board init_empty(board); /* main loop does two moves each iteration, one from the human * playing, and then one from the computer program (or game server) */ while (1) { //first we want the clients move if( (n = recv(sock, &clientMove, sizeof(uint16_t), 0)) != sizeof(uint16_t) ) { printf("socket closed\n"); status = STATUS_ABNORMAL; printLog(fptr, thisTheadInfo, "game over, code",status,CLIENT); break; } clientMoveNewtorked = htons(clientMove); //do move if (do_move(board, (int)clientMoveNewtorked, YELLOW)!=1) { printf("Panic\n"); status = STATUS_ABNORMAL; printLog(fptr, thisTheadInfo, "game over, code",status,CLIENT); break; } //if move possible we write to log printLog(fptr, thisTheadInfo, "client's move", (int)clientMoveNewtorked,CLIENT); // print_config(board); if (winner_found(board) == YELLOW) { /* rats, the person beat us! */ printf("Petty human wins\n"); status = STATUS_USER_WON; printLog(fptr, thisTheadInfo, "game over, code",status,CLIENT); break; } /* was that the last possible move? */ if (!move_possible(board)) { /* yes, looks like it was */ printf("An honourable draw\n"); status = STATUS_DRAW; printLog(fptr, thisTheadInfo, "game over, code",status,CLIENT); break; } /* otherwise, look for a move from the computer */ serverMove = suggest_move(board, RED); serverMoveNetworked = htons(serverMove); /* then play the move */ // printf(" I play in column %d\n", serverMove); if(send(sock, &serverMoveNetworked,sizeof(uint16_t),0) != sizeof(uint16_t)) { printf("error\n"); status = STATUS_ABNORMAL; printLog(fptr, thisTheadInfo, "game over, code",status,CLIENT); break; } if (do_move(board, serverMove, RED)!=1) { printf("Panic\n"); status = STATUS_ABNORMAL; printLog(fptr, thisTheadInfo, "game over, code",status,CLIENT); break; } printLog(fptr, thisTheadInfo, "server's move", serverMove,SERVER); // print_config(board); /* and did we win??? */ if (winner_found(board) == RED) { /* yes!!! */ printf("Server wins again!\n"); status = STATUS_AI_WON; printLog(fptr, thisTheadInfo, "game over, code",status,CLIENT); break; } /* otherwise, the game goes on */ } return NULL; }
/*------------------------- Main ---------------------*/ int main(int argc, char *argv[]) { /* Ensure enough arguments are passed */ if(argc < 3) { fprintf(stderr, "Usage: %s host port.\n", argv[0]); exit(EXIT_FAILURE); } /* Initialize a socket to communicate to the server */ int socket_fd = initialize_client_socket(argv[1], atoi(argv[2])); /* Begin the connect4 game against the server. */ /* The data structures required for this game */ c4_t board; int move, n; init_empty(board); print_config(board); /* This loop does 2 moves each iteration. One for the * human player and one for the server. */ while ((move = get_move(board)) != EOF) { /* process the person's move */ if (do_move(board, move, YELLOW)!=1) { printf("Panic\n"); break; } /* Send the move to the server */ int converted_move = htonl(move); n = write(socket_fd, &converted_move, sizeof(converted_move)); if(n < 0) { perror("Failed to write to socket.\n"); break; } print_config(board); /* and did they win??? */ if (winner_found(board) == YELLOW) { /* rats, the person beat us! */ printf("Ok, you beat me, beginner's luck!\n"); break; } /* was that the last possible move? */ if (!move_possible(board)) { /* yes, looks like it was */ printf("An honourable draw\n"); break; } /* Ask the server for its move */ n = read(socket_fd, &move, sizeof(move)); move = ntohl(move); if(n < 0) { perror("Failed to read from socket.\n"); break; } /* pretend to be thinking hard */ printf("Ok, let's see now...."); sleep(1); /* then play the move */ printf(" I play in column %d\n", move); if (do_move(board, move, RED)!=1) { printf("Panic\n"); break; } print_config(board); /* and did we win??? */ if (winner_found(board) == RED) { /* yes!!! */ printf("I guess I have your measure!\n"); break; } /* and did they win??? */ if (winner_found(board) == YELLOW) { /* rats, the person beat us! */ printf("Ok, you beat me, beginner's luck!\n"); break; } /* Was that the last possible move? */ if (!move_possible(board)) { /* yes, looks like it was */ printf("An honourable draw\n"); break; } /* otherwise, the game goes on */ } printf("FINALMOVE=%d", move); printf("\n"); close(socket_fd); return 0; }
int main(int argc, char * argv[]) { //msg to be sent to the server char msgtobesent[50]; //structure used for the connection information struct hostent *hp; struct sockaddr_in sin; char *host; int len, s, server_port; char flag[6]; if(argc==3){ host = argv[1]; server_port = atoi(argv[2]); } else { fprintf(stderr, "Usage :client host server_port\n"); exit(1); } /* translate host name into peer's IP address ; This is name translation service by the operating system */ hp = gethostbyname(host); if (!hp) { fprintf(stderr, "Unknown host %s \n",host); exit(1); } /* Building data structures for socket */ bzero( (char *)&sin,sizeof(sin)); sin.sin_family = AF_INET; bcopy(hp->h_addr, (char *)&sin.sin_addr, hp->h_length); sin.sin_port =htons(server_port); /* Active open */ /* Preliminary steps: Setup: creation of active open socket*/ if ( (s = socket(AF_INET, SOCK_STREAM, 0 )) < 0 ) { perror("Error in creating a socket to the server"); exit(1); } if(connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0 ) { perror("Error in connecting to the host"); close(s); exit(1); } //Just start the game on the client side //giving them a promot to enter a column c4_t board_; init_empty(board_); print_config(board_); printf("Enter column number: "); while(fgets(msgtobesent,sizeof(msgtobesent),stdin)) { //declrare the board so that it would be localscop //of loop , it will be moved from stack as long as //loop exits c4_t board; int sizeofboard = sizeof(board)+1; //give a warning to pass an int to move in a column if(!atoi(msgtobesent)){ printf("Please use an integer to move in a column\n"); continue; } //check if the given move from the client or user is within //the possible column if(atoi(msgtobesent) <1 || atoi(msgtobesent) > 7 ){ printf("Please use an integer between 1 to 7\n"); continue; } msgtobesent[24]='\0'; len=strlen(msgtobesent)+1; //send the message to the server //s is socket descriptor //on the other end (or server side ) // there will be a recv function to //recieve the message send(s,msgtobesent,len,0); if(recv(s,&board,sizeofboard,0)){ print_config(board); } if(recv(s,&board,sizeofboard,0)){ print_config(board); } if(recv(s,&flag,sizeof(flag),0)){ if(atoi(flag) == CONTINUE){ //promt again to enter column nunber //again because result is not come out yet printf("Enter column number: "); continue; } ///////different possiblity of the game //have we won else if(atoi(flag) == WIN){ printf("Ok, you beat me, beginner's luck!\n"); } //have we lost else if(atoi(flag) == LOSE){ printf("I guuess, I have your measure!\n"); } //is it draw else if(atoi(flag) == DRAW){ printf("An honourable draw!\n"); } //or some invalid move else{ printf("Panic!\n"); } //at this point we want to break the loop // because result has come out break; } } //Just give some sort of message on the client screen that //game has ended printf("EXITING....the game\n" ); //close the socket,no longer required close(s); //exit the program exit(1); }
/** * Get current ptr, do not decr() it, and set the current instance to empty image. * * This is to be used by specialized runtimes which pass ImageData around. */ ImageData *MicroBitImage::leakData() { ImageData* res = ptr; init_empty(); return res; }
template <typename T> inline _3dArray<T>::_3dArray() { init_empty(); }
/** * Default Constructor. * Creates a new reference to the empty MicroBitImage bitmap * * @code * MicroBitImage i(); //an empty image instance * @endcode */ MicroBitImage::MicroBitImage() { // Create new reference to the EmptyImage and we're done. init_empty(); }
void Screen::begin(const std::string& path) { batb->log << "batb->screen->begin( " << path << " )" << std::endl; LogIndent indent( batb->log, "* " ); if ( init_empty() ) { // set configuration file config( path ); //////////////////////////////////////////////////////////////////////////////// // setup GLFW // glfwSetErrorCallback( glfw_error_callback ); if ( !glfwInit() ) { batb->log << "ERROR: could not initialize GLFW" << std::endl; throw std::runtime_error( "Screen: Could not init GLFW" ); } //////////////////////////////////////////////////////////////////////////////// // screen bool debugctx = yaml["debug"].as<bool>( false ); glfwWindowHint( GLFW_OPENGL_DEBUG_CONTEXT, debugctx ); // debug symbols (?) batb->log << "debug context = " << debugctx << std::endl; // multisamples uint samples = 0; if ( YAML::Node node = yaml[ "multisamples" ] ) { samples = node.as<uint>( samples ); glfwWindowHint( GLFW_SAMPLES, samples ); } batb->log << "multisamples = " << samples << std::endl; // size uint wth = 640; uint hth = 480; if ( YAML::Node node = yaml[ "size" ] ) { wth = node[ "wth" ].as<uint>( wth ); hth = node[ "hth" ].as<uint>( hth ); } batb->log << "window size = " << wth << "x" << hth << std::endl; // fullscreen bool fullscreen = false; if ( YAML::Node node = yaml[ "fullscreen" ] ) { glfw_monitor = node.as<bool>( fullscreen ) ? glfwGetPrimaryMonitor() : 0; // if we create a fullscreen window, let us use the display's resolution if ( glfw_monitor ) { if ( auto mode = glfwGetVideoMode( glfw_monitor ) ) { // save before we set fullscreen nonfullscreen_wth_ = wth; nonfullscreen_hth_ = hth; wth = mode->width; hth = mode->height; } } } batb->log << "window fullscreen = " << fullscreen; if ( fullscreen ) batb->log << " (overriding window size with display resolution (" << wth << "x" << hth << ")"; batb->log->endl(); // title std::string title = ""; if ( YAML::Node node = yaml[ "title" ] ) { title = node.as<std::string>( title ); } batb->log << "window title = " << title << std::endl; // set addioninal windown hints // http://www.glfw.org/docs/latest/window.html#window_hints if ( YAML::Node node = yaml[ "glfw-hints" ] ) { batb->log << "GLFW hints:" << std::endl; LogIndent indent( batb->log, "- " ); for (auto p : node) { auto hint = p.first.as<std::string>(); auto value = p.second.as<std::string>(""); constexpr uint padding = 30; std::string pad( hint.size() < padding ? (padding - hint.size()) : 0, ' ' ); batb->log << hint << pad << " = " << value; if ( glfw_set_windowhint( hint, value ) ) { batb->log->endl(); } else { batb->log << " (WARNING: could not set)" << std::endl; } } } // NOTE: error in implementation of glfw, according to valgrind: glfw_window = glfwCreateWindow( wth, hth, title.c_str(), glfw_monitor, 0 ); // set GL context as 'theWindow_' glfwMakeContextCurrent( glfw_window ); if ( !glfw_window ) { batb->log << "ERROR: could not create GLFW window" << std::endl; throw std::runtime_error( "Screen: could not create GLFW window" ); } // we now have a context, init GLEW // or other, see // * http://www.glfw.org/docs/latest/context_guide.html#context_glext_auto // * https://www.khronos.org/opengl/wiki/OpenGL_Loading_Library GLenum err = glewInit(); if ( err != GLEW_OK ) { batb->log << "ERROR: could not initialize the OpenGL loading library (GLEW): " << glewGetErrorString( err ) << std::endl; std::ostringstream os; os << "Screen: could not init GLEW (" << glewGetErrorString( err ) << ")"; throw std::runtime_error( os.str() ); } // print verbose GL info if ( YAML::Node node = yaml[ "info" ] ) { if ( node.as<bool>() ) { printGLInfo(); } } } init( true ); }