int main(int argc, const char *argv[]) { PtrVector<Test> vec; //vector<Test*> for (int i = 0; i < 5; i++) { vec.push_back(new Test); } return 0; }
/** Rebuild the list of tracks and GPs. This need to be recomputed e.g. to * take unlocked tracks into account. */ void TracksScreen::buildTrackList() { DynamicRibbonWidget* tracks_widget = this->getWidget<DynamicRibbonWidget>("tracks"); RibbonWidget* tabs = this->getWidget<RibbonWidget>("trackgroups"); // Reset track list everytime (accounts for locking changes, etc.) tracks_widget->clearItems(); m_random_track_list.clear(); const std::string& curr_group_name = tabs->getSelectionIDString(0); const int track_amount = (int)track_manager->getNumberOfTracks(); // First build a list of all tracks to be displayed // (e.g. exclude arenas, ...) PtrVector<Track, REF> tracks; for (int n = 0; n < track_amount; n++) { Track* curr = track_manager->getTrack(n); if (race_manager->getMinorMode() == RaceManager::MINOR_MODE_EASTER_EGG && !curr->hasEasterEggs()) continue; if (curr->isArena() || curr->isSoccer()||curr->isInternal()) continue; if (curr_group_name != ALL_TRACK_GROUPS_ID && !curr->isInGroup(curr_group_name)) continue; tracks.push_back(curr); } // for n<track_amount tracks.insertionSort(); for (unsigned int i = 0; i < tracks.size(); i++) { Track *curr = tracks.get(i); if (PlayerManager::getCurrentPlayer()->isLocked(curr->getIdent())) { tracks_widget->addItem( _("Locked : solve active challenges to gain access to more!"), "locked", curr->getScreenshotFile(), LOCKED_BADGE, IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE); } else { tracks_widget->addItem(translations->fribidize(curr->getName()), curr->getIdent(), curr->getScreenshotFile(), 0, IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE); m_random_track_list.push_back(curr->getIdent()); } } tracks_widget->addItem(_("Random Track"), "random_track", "/gui/track_random.png", 0 /* no badge */, IconButtonWidget::ICON_PATH_TYPE_RELATIVE); tracks_widget->updateItemDisplay(); std::random_shuffle( m_random_track_list.begin(), m_random_track_list.end() ); } // buildTrackList
// ============================================================================ GroupUserConfigParam::GroupUserConfigParam(const char* group_name, const char* comment) { m_param_name = group_name; all_params.push_back(this); if(comment != NULL) m_comment = comment; } // GroupUserConfigParam
/** Write settings to config file. */ void UserConfig::saveConfig() { const std::string filename = file_manager->getUserConfigFile(m_filename); try { std::ofstream configfile (filename.c_str(), std::ofstream::out); configfile << "<?xml version=\"1.0\"?>\n"; configfile << "<stkconfig version=\"" << m_current_config_version << "\" >\n\n"; const int paramAmount = all_params.size(); for(int i=0; i<paramAmount; i++) { //Log::info("UserConfig", "Saving parameter %d to file", i); all_params[i].write(configfile); } configfile << "</stkconfig>\n"; configfile.close(); } catch (std::runtime_error& e) { Log::error("UserConfig::saveConfig", "Failed to write config to %s, because %s", filename.c_str(), e.what()); } } // saveConfig
ListUserConfigParam<T, U>::ListUserConfigParam(const char* param_name, const char* comment) { m_param_name = param_name; all_params.push_back(this); if(comment != NULL) m_comment = comment; } // ListUserConfigParam
/** Write settings to config file. */ void UserConfig::saveConfig() { const std::string filename = file_manager->getUserConfigFile(m_filename); try { std::ofstream configfile (filename.c_str(), std::ofstream::out); configfile << "<?xml version=\"1.0\"?>\n"; configfile << "<stkconfig version=\"" << m_current_config_version << "\" >\n\n"; const int paramAmount = all_params.size(); for(int i=0; i<paramAmount; i++) { //std::cout << "saving parameter " << i << " to file\n"; all_params[i].write(configfile); } configfile << "</stkconfig>\n"; configfile.close(); } catch (std::runtime_error& e) { std::cerr << "[UserConfig::saveConfig] ERROR: Failed to write config to " << filename.c_str() << "; cause : " << e.what() << "\n"; } } // saveConfig
// ============================================================================ TimeUserConfigParam::TimeUserConfigParam(StkTime::TimeType default_value, const char* param_name, const char* comment) { m_value = default_value; m_default_value = default_value; m_param_name = param_name; all_params.push_back(this); if(comment != NULL) m_comment = comment; } // TimeUserConfigParam
// ============================================================================ StringUserConfigParam::StringUserConfigParam(const char* default_value, const char* param_name, const char* comment) { m_value = default_value; m_default_value = default_value; m_param_name = param_name; all_params.push_back(this); if(comment != NULL) m_comment = comment; } // StringUserConfigParam
virtual bool OnEvent(const SEvent& event) { bool out = CGUIEditBox::OnEvent(event); if (event.EventType == EET_KEY_INPUT_EVENT && event.KeyInput.PressedDown) { for (unsigned int n=0; n<m_listeners.size(); n++) { m_listeners[n].onTextUpdated(); } } return out; }
ListUserConfigParam<T,U>::ListUserConfigParam(const char* param_name, const char* comment, int nb_elements, ...) { m_param_name = param_name; all_params.push_back(this); if(comment != NULL) m_comment = comment; // add the default list va_list arguments; va_start ( arguments, nb_elements ); for ( int i = 0; i < nb_elements; i++ ) m_elements.push_back(T(va_arg ( arguments, U ))); va_end ( arguments ); // Cleans up the list } // ListUserConfigParam
/** This function adds a list of widgets recursively, effectively creating the hierarchy * of widgets. * \param widgets The vector of widgets to add * \param parent The parent widget of the vector of widgets */ void AbstractTopLevelContainer::addWidgetsRecursively( PtrVector<Widget>& widgets, Widget* parent) { const unsigned short widgets_amount = widgets.size(); // ------- add widgets for (int n=0; n<widgets_amount; n++) { if (widgets[n].getType() == WTYPE_DIV) { widgets[n].add(); // Will do nothing, but will maybe reserve an ID addWidgetsRecursively(widgets[n].m_children, &widgets[n]); } else { // warn if widget has no dimensions (except for ribbons and icons, // where it is normal since it adjusts to its contents) if ((widgets[n].m_w < 1 || widgets[n].m_h < 1) && widgets[n].getType() != WTYPE_RIBBON && widgets[n].getType() != WTYPE_ICON_BUTTON && widgets[n].getType() != WTYPE_SPACER) { Log::warn("AbstractTopLevelContainer::addWidgetsRecursively", "Widget %s of type %d has no dimensions", widgets[n].m_properties[PROP_ID].c_str(), widgets[n].getType()); } if (widgets[n].m_x == -1 || widgets[n].m_y == -1) { Log::warn("AbstractTopLevelContainer::addWidgetsRecursively", "Widget %s of type %d has no position", widgets[n].m_properties[PROP_ID].c_str(), widgets[n].getType()); } widgets[n].add(); } } // for n in all widgets } // addWidgetsRecursively
/** Returns the total number of karts of this GP. */ int getTotalKarts() const { return m_karts.size(); }
/** Returns the number of players in the config file.*/ unsigned int getNumPlayers() const { return m_all_players.size(); }
KeyboardConfig* getKeyboardConfig(const int i) { return m_keyboard_configs.get(i); }
KeyboardDevice* getKeyboard(const int i) { return m_keyboards.get(i); }
int getKeyboardConfigAmount() const { return m_keyboard_configs.size(); }
void KartSelectionScreen::setKartsFromCurrentGroup() { RibbonWidget* tabs = getWidget<RibbonWidget>("kartgroups"); assert(tabs != NULL); std::string selected_kart_group = tabs->getSelectionIDString(PLAYER_ID_GAME_MASTER); UserConfigParams::m_last_used_kart_group = selected_kart_group; // This can happen if addons are removed so that also the previously // selected kart group is removed. In this case, select the // 'standard' group if (selected_kart_group != ALL_KART_GROUPS_ID && !kart_properties_manager->getKartsInGroup(selected_kart_group).size()) { selected_kart_group = DEFAULT_GROUP_NAME; } DynamicRibbonWidget* w = getWidget<DynamicRibbonWidget>("karts"); w->clearItems(); int usable_kart_count = 0; PtrVector<const KartProperties, REF> karts; for(unsigned int i=0; i<kart_properties_manager->getNumberOfKarts(); i++) { const KartProperties* prop = kart_properties_manager->getKartById(i); // Ignore karts that are not in the selected group if(selected_kart_group != ALL_KART_GROUPS_ID && !prop->isInGroup(selected_kart_group)) continue; karts.push_back(prop); } karts.insertionSort(); for(unsigned int i=0; i<karts.size(); i++) { const KartProperties* prop = karts.get(i); if (PlayerManager::getCurrentPlayer()->isLocked(prop->getIdent()) && !m_multiplayer) { w->addItem(_("Locked : solve active challenges to gain access to more!"), ID_LOCKED + prop->getIdent(), prop->getAbsoluteIconFile(), LOCKED_BADGE, IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE); } else { w->addItem(translations->fribidize(prop->getName()), prop->getIdent(), prop->getAbsoluteIconFile(), 0, IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE); usable_kart_count++; } } // add random if (usable_kart_count > 1) { w->addItem(_("Random Kart"), RANDOM_KART_ID, "/gui/random_kart.png"); } w->updateItemDisplay(); }
void clearListeners() { m_listeners.clearWithoutDeleting(); }
GamepadConfig* getGamepadConfig(const int i) { return m_gamepad_configs.get(i); }
GamePadDevice* getGamePad(const int i) { return m_gamepads.get(i); }
int getGamePadConfigAmount() const { return m_gamepad_configs.size(); }
int getGamePadAmount() const { return m_gamepads.size(); }
/** Load configuration values from file. */ bool UserConfig::loadConfig() { const std::string filename = file_manager->getUserConfigFile(m_filename); XMLNode* root = file_manager->createXMLTree(filename); if(!root || root->getName() != "stkconfig") { Log::error("UserConfig", "Could not read user config file '%s'.", filename.c_str()); if(root) delete root; // Create a default config file - just in case that stk crashes later // there is a config file that can be modified (to e.g. disable // shaders) saveConfig(); return false; } // ---- Read config file version int config_file_version = m_current_config_version; if(root->get("version", &config_file_version) < 1) { GUIEngine::showMessage( _("Your config file was malformed, so it was deleted and a new one will be created."), 10.0f); Log::error("UserConfig", "Warning, malformed user config file! Contains no version"); } if (config_file_version < m_current_config_version) { // current version (8) is 100% incompatible with other versions (which were lisp) // so we just delete the old config. in the future, for smaller updates, we can // add back the code previously there that upgraded the config file to the new // format instead of overwriting it. GUIEngine::showMessage(_("Your config file was too old, so it was deleted and a new one will be created."), 10.0f); Log::info("UserConfig", "Your config file was too old, so it was deleted and a new one will be created."); delete root; return false; } // if configFileVersion<SUPPORTED_CONFIG_VERSION // ---- Read parameters values (all parameter objects must have been created before this point if // you want them automatically read from the config file) const int paramAmount = all_params.size(); for(int i=0; i<paramAmount; i++) { all_params[i].findYourDataInAChildOf(root); } // ---- Read Saved GP's UserConfigParams::m_saved_grand_prix_list.clearAndDeleteAll(); std::vector<XMLNode*> saved_gps; root->getNodes("SavedGP", saved_gps); const int gp_amount = saved_gps.size(); for (int i=0; i<gp_amount; i++) { UserConfigParams::m_saved_grand_prix_list.push_back( new SavedGrandPrix( saved_gps[i]) ); } delete root; return true; } // loadConfig
void addListener(GUIEngine::ITextBoxWidgetListener* listener) { m_listeners.push_back(listener); }
// ---------------------------------------------------------------------------- UserConfigParam::~UserConfigParam() { all_params.remove(this); } // ~UserConfigParam
int getKeyboardAmount() { return m_keyboards.size(); }
void clearGamepads() { m_gamepads.clearAndDeleteAll(); }
void manualInsertObject(TrackObject* obj) { m_all_objects.push_back(obj); }
int main(int argc, char* argv[]) { google::InitGoogleLogging(argv[0]); gflags::ParseCommandLineFlags(&argc, &argv, true); // Detect the hardware concurrency level. const std::size_t num_hw_threads = DefaultsConfigurator::GetNumHardwareThreads(); // Use the command-line value if that was supplied, else use the value // that we computed above, provided it did return a valid value. // TODO(jmp): May need to change this at some point to keep one thread // available for the OS if the hardware concurrency level is high. const unsigned int real_num_workers = quickstep::FLAGS_num_workers != 0 ? quickstep::FLAGS_num_workers : (num_hw_threads != 0 ? num_hw_threads : 1); if (real_num_workers > 0) { printf("Starting Quickstep with %d worker thread(s) and a %.2f GB buffer pool\n", real_num_workers, (static_cast<double>(quickstep::FLAGS_buffer_pool_slots) * quickstep::kSlotSizeBytes)/quickstep::kAGigaByte); } else { LOG(FATAL) << "Quickstep needs at least one worker thread to run"; } #ifdef QUICKSTEP_HAVE_FILE_MANAGER_HDFS if (quickstep::FLAGS_use_hdfs) { LOG(INFO) << "Using HDFS as the default persistent storage, with namenode at " << quickstep::FLAGS_hdfs_namenode_host << ":" << quickstep::FLAGS_hdfs_namenode_port << " and block replication factor " << quickstep::FLAGS_hdfs_num_replications << "\n"; } #endif // Initialize the thread ID based map here before the Foreman and workers are // constructed because the initialization isn't thread safe. quickstep::ClientIDMap::Instance(); MessageBusImpl bus; bus.Initialize(); // The TMB client id for the main thread, used to kill workers at the end. const client_id main_thread_client_id = bus.Connect(); bus.RegisterClientAsSender(main_thread_client_id, kPoisonMessage); // Setup the paths used by StorageManager. string fixed_storage_path(quickstep::FLAGS_storage_path); if (!fixed_storage_path.empty() && (fixed_storage_path.back() != quickstep::kPathSeparator)) { fixed_storage_path.push_back(quickstep::kPathSeparator); } string catalog_path(fixed_storage_path); catalog_path.append("catalog.pb.bin"); if (quickstep::FLAGS_initialize_db) { // Initialize the database // TODO(jmp): Refactor the code in this file! LOG(INFO) << "Initializing the database, creating a new catalog file and storage directory\n"; // Create the directory // TODO(jmp): At some point, likely in C++-17, we will just have the // filesystem path, and we can clean this up #ifdef QUICKSTEP_OS_WINDOWS std::filesystem::create_directories(fixed_storage_path); LOG(FATAL) << "Failed when attempting to create the directory: " << fixed_storage_path << "\n"; LOG(FATAL) << "Check if the directory already exists. If so, delete it or move it before initializing \n"; #else { string path_name = "mkdir " + fixed_storage_path; if (std::system(path_name.c_str())) { LOG(FATAL) << "Failed when attempting to create the directory: " << fixed_storage_path << "\n"; } } #endif // Create the default catalog file. std::ofstream catalog_file(catalog_path); if (!catalog_file.good()) { LOG(FATAL) << "ERROR: Unable to open catalog.pb.bin for writing.\n"; } quickstep::Catalog catalog; catalog.addDatabase(new quickstep::CatalogDatabase(nullptr, "default")); if (!catalog.getProto().SerializeToOstream(&catalog_file)) { LOG(FATAL) << "ERROR: Unable to serialize catalog proto to file catalog.pb.bin\n"; return 1; } // Close the catalog file - it will be reopened below by the QueryProcessor. catalog_file.close(); } // Setup QueryProcessor, including CatalogDatabase and StorageManager. std::unique_ptr<QueryProcessor> query_processor; try { query_processor.reset(new QueryProcessor(catalog_path, fixed_storage_path)); } catch (const std::exception &e) { LOG(FATAL) << "FATAL ERROR DURING STARTUP: " << e.what() << "\nIf you intended to create a new database, " << "please use the \"-initialize_db=true\" command line option."; } catch (...) { LOG(FATAL) << "NON-STANDARD EXCEPTION DURING STARTUP"; } // Parse the CPU affinities for workers and the preloader thread, if enabled // to warm up the buffer pool. const vector<int> worker_cpu_affinities = InputParserUtil::ParseWorkerAffinities(real_num_workers, quickstep::FLAGS_worker_affinities); const std::size_t num_numa_nodes_covered = DefaultsConfigurator::GetNumNUMANodesCoveredByWorkers(worker_cpu_affinities); if (quickstep::FLAGS_preload_buffer_pool) { std::chrono::time_point<std::chrono::steady_clock> preload_start, preload_end; preload_start = std::chrono::steady_clock::now(); printf("Preloading the buffer pool ... "); fflush(stdout); quickstep::PreloaderThread preloader(*query_processor->getDefaultDatabase(), query_processor->getStorageManager(), worker_cpu_affinities.front()); preloader.start(); preloader.join(); preload_end = std::chrono::steady_clock::now(); printf("in %g seconds\n", std::chrono::duration<double>(preload_end - preload_start).count()); } Foreman foreman(&bus, query_processor->getDefaultDatabase(), query_processor->getStorageManager(), num_numa_nodes_covered); // Get the NUMA affinities for workers. vector<int> cpu_numa_nodes = InputParserUtil::GetNUMANodesForCPUs(); if (cpu_numa_nodes.empty()) { // libnuma is not present. Assign -1 as the NUMA node for every worker. cpu_numa_nodes.assign(worker_cpu_affinities.size(), -1); } vector<int> worker_numa_nodes; PtrVector<Worker> workers; vector<client_id> worker_client_ids; // Initialize the worker threads. DCHECK_EQ(static_cast<std::size_t>(real_num_workers), worker_cpu_affinities.size()); for (std::size_t worker_thread_index = 0; worker_thread_index < worker_cpu_affinities.size(); ++worker_thread_index) { int numa_node_id = -1; if (worker_cpu_affinities[worker_thread_index] >= 0) { // This worker can be NUMA affinitized. numa_node_id = cpu_numa_nodes[worker_cpu_affinities[worker_thread_index]]; } worker_numa_nodes.push_back(numa_node_id); workers.push_back( new Worker(worker_thread_index, &bus, worker_cpu_affinities[worker_thread_index])); worker_client_ids.push_back(workers.back().getBusClientID()); } // TODO(zuyu): Move WorkerDirectory within Shiftboss once the latter is added. WorkerDirectory worker_directory(worker_cpu_affinities.size(), worker_client_ids, worker_numa_nodes); foreman.setWorkerDirectory(&worker_directory); // Start the worker threads. for (Worker &worker : workers) { worker.start(); } LineReaderImpl line_reader("quickstep> ", " ...> "); std::unique_ptr<SqlParserWrapper> parser_wrapper(new SqlParserWrapper()); std::chrono::time_point<std::chrono::steady_clock> start, end; for (;;) { string *command_string = new string(); *command_string = line_reader.getNextCommand(); if (command_string->size() == 0) { delete command_string; break; } parser_wrapper->feedNextBuffer(command_string); bool quitting = false; // A parse error should reset the parser. This is because the thrown quickstep // SqlError does not do the proper reset work of the YYABORT macro. bool reset_parser = false; for (;;) { ParseResult result = parser_wrapper->getNextStatement(); if (result.condition == ParseResult::kSuccess) { if (result.parsed_statement->getStatementType() == ParseStatement::kQuit) { quitting = true; break; } if (result.parsed_statement->getStatementType() == ParseStatement::kCommand) { try { quickstep::cli::executeCommand( *result.parsed_statement, *(query_processor->getDefaultDatabase()), stdout); } catch (const quickstep::SqlError &sql_error) { fprintf(stderr, "%s", sql_error.formatMessage(*command_string).c_str()); reset_parser = true; break; } continue; } std::unique_ptr<QueryHandle> query_handle; try { query_handle.reset(query_processor->generateQueryHandle(*result.parsed_statement)); } catch (const quickstep::SqlError &sql_error) { fprintf(stderr, "%s", sql_error.formatMessage(*command_string).c_str()); reset_parser = true; break; } DCHECK(query_handle->getQueryPlanMutable() != nullptr); foreman.setQueryPlan(query_handle->getQueryPlanMutable()->getQueryPlanDAGMutable()); foreman.reconstructQueryContextFromProto(query_handle->getQueryContextProto()); try { start = std::chrono::steady_clock::now(); foreman.start(); foreman.join(); end = std::chrono::steady_clock::now(); const CatalogRelation *query_result_relation = query_handle->getQueryResultRelation(); if (query_result_relation) { PrintToScreen::PrintRelation(*query_result_relation, query_processor->getStorageManager(), stdout); DropRelation::Drop(*query_result_relation, query_processor->getDefaultDatabase(), query_processor->getStorageManager()); } query_processor->saveCatalog(); printf("Execution time: %g seconds\n", std::chrono::duration<double>(end - start).count()); } catch (const std::exception &e) { fprintf(stderr, "QUERY EXECUTION ERROR: %s\n", e.what()); break; } printf("Query Complete\n"); } else { if (result.condition == ParseResult::kError) { fprintf(stderr, "%s", result.error_message.c_str()); } reset_parser = true; break; } } if (quitting) { break; } else if (reset_parser) { parser_wrapper.reset(new SqlParserWrapper()); reset_parser = false; } } // Terminate all workers before exiting. // The main thread broadcasts poison message to the workers. Each worker dies // after receiving poison message. The order of workers' death is irrelavant. MessageStyle style; style.Broadcast(true); Address address; address.All(true); std::unique_ptr<WorkerMessage> poison_message(WorkerMessage::PoisonMessage()); TaggedMessage poison_tagged_message(poison_message.get(), sizeof(*poison_message), kPoisonMessage); const tmb::MessageBus::SendStatus send_status = bus.Send(main_thread_client_id, address, style, std::move(poison_tagged_message)); CHECK(send_status == tmb::MessageBus::SendStatus::kOK) << "Broadcast message from Foreman to workers failed"; for (Worker &worker : workers) { worker.join(); } return 0; }
void clearKeyboard() { m_keyboards.clearAndDeleteAll(); }