void thread_connect() { connected.store(false); do { struct sockaddr_in addr; int r; hostent* h; memset((void*)&addr, 0, sizeof(addr)); addr.sin_addr.s_addr = inet_addr(ip.c_str()); if(INADDR_NONE == addr.sin_addr.s_addr) { h = gethostbyname(ip.c_str()); if(NULL == h) { perror("Could not get host by name"); break;; } } else { h = gethostbyaddr((const char*)&addr.sin_addr, sizeof(struct sockaddr_in), AF_INET); if(NULL == h) { perror("Could not get host by address"); break;; } } sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(INVALID_SOCKET == sock) { perror("Could not create socket"); break; } BOOL bDontLinger = TRUE; setsockopt( sock, SOL_SOCKET, SO_DONTLINGER, ( const char* )&bDontLinger, sizeof( BOOL ) ); addr.sin_family = AF_INET; addr.sin_addr = *((in_addr*)*h->h_addr_list); addr.sin_port = htons(port); printf("Connecting... "); r = connect(sock, (sockaddr*)&addr, sizeof(struct sockaddr)); if(SOCKET_ERROR == r) { printf("Cannot connect to server%d\n", get_errno()); break; } printf("connected.\n"); connected.store(true); connecting.store(false); sender.swap(std::thread(std::bind(&transport_t::thread_send, this))); recver.swap(std::thread(std::bind(&transport_t::thread_recv, this))); return; } while (0); connecting.store(false); }
// ------------------------------------------------------------------------ void addAndSetTime(uint32_t ping, uint64_t server_time) { if (m_synchronised.load() == true) return; if (m_force_set_timer.load() == true) { m_force_set_timer.store(false); m_synchronised.store(true); STKHost::get()->setNetworkTimer(server_time + (uint64_t)(ping / 2)); return; } const uint64_t cur_time = StkTime::getMonoTimeMs(); // Discard too close time compared to last ping // (due to resend when packet loss) // 10 packets per second as seen in STKHost const uint64_t frequency = (uint64_t)((1.0f / 10.0f) * 1000.0f) / 2; if (!m_times.empty() && cur_time - std::get<2>(m_times.back()) < frequency) return; // Take max 20 averaged samples from m_times, the next addAndGetTime // is used to determine that server_time if it's correct, if not // clear half in m_times until it's correct if (m_times.size() >= 20) { uint64_t sum = std::accumulate(m_times.begin(), m_times.end(), (uint64_t)0, [cur_time](const uint64_t previous, const std::tuple<uint32_t, uint64_t, uint64_t>& b)->uint64_t { return previous + (uint64_t)(std::get<0>(b) / 2) + std::get<1>(b) + cur_time - std::get<2>(b); }); const int64_t averaged_time = sum / 20; const int64_t server_time_now = server_time + (uint64_t)(ping / 2); int difference = (int)std::abs(averaged_time - server_time_now); if (std::abs(averaged_time - server_time_now) < UserConfigParams::m_timer_sync_difference_tolerance) { STKHost::get()->setNetworkTimer(averaged_time); m_times.clear(); m_force_set_timer.store(false); m_synchronised.store(true); Log::info("NetworkTimerSynchronizer", "Network " "timer synchronized, difference: %dms", difference); return; } m_times.erase(m_times.begin(), m_times.begin() + 10); } m_times.emplace_back(ping, server_time, cur_time); }
/** * Start the IPC thread. */ void ipcStart() { std::unique_lock<std::mutex> lock { sIpcMutex }; sIpcThreadRunning.store(true); sIpcThread = std::thread { ipcThreadEntry }; }
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { WindowEvent params = {}; params.hWnd = hWnd; params.msg = msg; params.wParam = wParam; params.lParam = lParam; s_queue->Enqueue(params); switch (msg) { case WM_SIZE: if (g_renderApi && wParam != SIZE_MINIMIZED) { g_renderApi->Resize((int32_t) LOWORD(lParam), (int32_t) HIWORD(lParam)); return 0; } break; case WM_SYSCOMMAND: if ((wParam & 0xfff0) == SC_KEYMENU) // Disable ALT application menu return 0; break; case WM_DESTROY: s_running.store(false); PostQuitMessage(0); return 0; } return DefWindowProcW(hWnd, msg, wParam, lParam); }
progressIndicatorThreadWrapper( const std::chrono::nanoseconds& updateInterval ) { m_stopCondition.store( false ); m_thread = std::thread( [this, &updateInterval] { FormattedPrint::On(std::cout, false).app(" "); int slashIndex = 0; while( ! m_stopCondition.load() ) { FormattedPrint::On(std::cout, false).app("\b\b\b \b") .color( Green ) .app('[') .color( Yellow ) .app( slashes[ slashIndex++ ] ) .color( Green ) .app(']') .color(); slashIndex = slashIndex % 4; std::this_thread::sleep_for( updateInterval ); } FormattedPrint::On(std::cout, false).app("\b\b\b"); }); }
/** * This is the actual function that the thread executes. * It receives a block from the scheduler, class its run() method and returns it to the scheduler. * The thread runs until the it is told to stop by setting the m_stop boolean flag */ void operator()() { if(CPU_COUNT(&m_mask)>0) { pthread_t id = pthread_self(); int ret = pthread_setaffinity_np(id, sizeof(m_mask), &m_mask); if(ret != 0) { perror("setaffinity"); throw(std::runtime_error("set affinity failed")); } } while(!m_stop.load()) { std::shared_ptr<Block>torun(m_scheduler.next_task(m_id)); if(torun) { torun->run(); m_scheduler.task_done(m_id, std::move(torun)); } else { std::this_thread::sleep_for(std::chrono::milliseconds(10)); } } m_stop.store(false); }
bool init(const char* pipeline, core::c_window *window, bool validation) { VERIFY(graphics::render3d::resources::load_pipeline(pipeline)); VERIFY(create_instance("appname")); VERIFY(create_surface(window)); VERIFY(create_device()); VERIFY(create_device_queue()); VERIFY(graphics::render3d::resources::create_pipeline()); vk_globals::is_init = true; flag_needs_recreate_swapchain.store(false); flag_needs_shutdown.store(false); on_window_resize_listener = window->add_event_listener(core::e_window_event::ON_RESIZE, on_window_resize); return true; }
~progressIndicatorThreadWrapper() { m_stopCondition.store( true ); if( m_thread.joinable() ) { m_thread.join(); } }
void disconnect() { connected.store(false); closesocket(sock); sender.join(); recver.join(); send_queue.clear(); recv_queue.clear(); }
~WorkerThreads() { _shutdownFlag.store(true); _cache.setShutdownFlag(); for (auto worker : _workers) { worker->join(); delete worker; } }
void handleDbgBreakInterrupt() { // If we are not initialised, we should ignore DbgBreaks if (!decaf::config::debugger::enabled) { return; } std::unique_lock<std::mutex> lock(sMutex); auto coreId = cpu::this_core::id(); // Store our core state before we flip isPaused sCorePauseState[coreId] = cpu::this_core::state(); // Check to see if we were the last core to join on the fun auto coreBit = 1 << coreId; auto isPausing = sIsPausing.fetch_or(coreBit); if (isPausing == 0) { // This is the first core to hit a breakpoint sPauseInitiatorCoreId = coreId; // Signal the rest of the cores to stop for (auto i = 0; i < 3; ++i) { cpu::interrupt(i, cpu::DBGBREAK_INTERRUPT); } } if ((isPausing | coreBit) == (1 | 2 | 4)) { // This was the last core to join. sIsPaused.store(true); sIsPausing.store(0); sIsResuming.store(0); } // Spin around the release condition while we are paused while (sIsPausing.load() || sIsPaused.load()) { sPauseReleaseCond.wait(lock); } // Clear any additional DbgBreaks that occured cpu::this_core::clearInterrupt(cpu::DBGBREAK_INTERRUPT); // Everyone needs to leave at once in case new breakpoints occur. if ((sIsResuming.fetch_or(coreBit) | coreBit) == (1 | 2 | 4)) { sPauseReleaseCond.notify_all(); } else { while ((sIsResuming.load() | coreBit) != (1 | 2 | 4)) { sPauseReleaseCond.wait(lock); } } }
void swap_queues() { for(unsigned int i=0; i<m_full_slots; ++i) { m_queues[m_consumer_q].vec[i].valid.store(false,std::memory_order_release); } unsigned int newpoint=m_consumer_q<<30; m_consumer_q=exchange_queue(m_consumer_q); unsigned int old_pointer=m_pointer.exchange(newpoint,std::memory_order_release); m_full.store(false,std::memory_order_release); old_pointer&=~MASK; m_full_slots=std::min(old_pointer,Qlen); m_read=0; }
WorkerThreads(unsigned int threadsCount, RJCache& cache) : _nextThreadId(0), _cache(cache) { _shutdownFlag.store(false); _workers.reserve(threadsCount); for (unsigned int i = 0; i < threadsCount; i++) { std::thread* worker = new std::thread(&WorkerThreads::workerThreadFunc, this, _nextThreadId++, &cache); _workers.push_back(worker); } }
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow) { #ifdef _DEBUG // ATLTRACEで日本語を使うために必要 _tsetlocale(LC_ALL, _T("japanese")); #endif HRESULT hRes = ::CoInitialize(NULL); // If you are running on NT 4.0 or higher you can use the following call instead to // make the EXE free threaded. This means that calls come in on a random RPC thread. // HRESULT hRes = ::CoInitializeEx(NULL, COINIT_MULTITHREADED); ATLASSERT(SUCCEEDED(hRes)); // this resolves ATL window thunking problem when Microsoft Layer for Unicode (MSLU) is used ::DefWindowProc(NULL, 0, 0, 0L); AtlInitCommonControls(ICC_BAR_CLASSES); // add flags to support other controls hRes = _Module.Init(NULL, hInstance); ATLASSERT(SUCCEEDED(hRes)); FILE* fp_out = freopen("result.txt", "w", stdout); g_atomicMegaThreadActive.store(true); std::thread threadMegaLoop(CMegaAppImpl::StartMegaLoop); int nRet = Run(lpstrCmdLine, nCmdShow); g_atomicMegaThreadActive.store(false); threadMegaLoop.join(); fclose(fp_out); _Module.Term(); ::CoUninitialize(); return nRet; }
int main() { /* Handle Signals */ std::signal(SIGTERM, cleanup); std::signal(SIGINT , cleanup); std::signal(SIGABRT, cleanup); std::thread sw{stopwatch}; while(true) { if(std::getchar() != '\x03') /* ctrl+c */ lap.store(true); } return 0; }
/** * Main thread entry point for the IPC thread. * * This thread represents the IOS side of the IPC mechanism. * * Responsible for receiving IPC requests and dispatching them to the * correct IOS device. */ void ipcThreadEntry() { std::unique_lock<std::mutex> lock { sIpcMutex }; while (true) { if (!sIpcRequests.empty()) { auto request = sIpcRequests.front(); sIpcRequests.pop(); lock.unlock(); iosDispatchIpcRequest(request); lock.lock(); switch (request->cpuId) { case IOSCpuId::PPC0: sIpcResponses[0].push(request); cpu::interrupt(0, cpu::IPC_INTERRUPT); break; case IOSCpuId::PPC1: sIpcResponses[1].push(request); cpu::interrupt(1, cpu::IPC_INTERRUPT); break; case IOSCpuId::PPC2: sIpcResponses[2].push(request); cpu::interrupt(2, cpu::IPC_INTERRUPT); break; default: decaf_abort("Unexpected cpu id"); } } if (!sIpcThreadRunning.load()) { break; } if (sIpcRequests.empty()) { sIpcCond.wait(lock); } } sIpcThreadRunning.store(false); }
void join() { for (auto i = 0; i < 3; ++i) { if (gCore[i].thread.joinable()) { gCore[i].thread.join(); } } // Mark the CPU as no longer running gRunning.store(false); // Notify the timer thread that something changed gTimerCondition.notify_all(); // Wait for the timer thread to shut down if (gTimerThread.joinable()) { gTimerThread.join(); } }
void start() { installExceptionHandler(); gRunning.store(true); for (auto i = 0; i < 3; ++i) { auto &core = gCore[i]; core.id = i; core.thread = std::thread(std::bind(&coreEntryPoint, &core)); core.next_alarm = std::chrono::time_point<std::chrono::system_clock>::max(); static const std::string coreNames[] = { "Core #0", "Core #1", "Core #2" }; platform::setThreadName(&core.thread, coreNames[core.id]); } gTimerThread = std::thread(std::bind(&timerEntryPoint)); platform::setThreadName(&gTimerThread, "Timer Thread"); }
int main( int argc, char **argv ) { auto map = std::make_shared<concurrent::map>(); auto key = "foo"; auto t1 = std::thread( producer, map, key, "thread1" ); auto t2 = std::thread( producer, map, key, "thread2" ); auto t3 = std::thread( consumer, map, key ); std::this_thread::sleep_for( std::chrono::seconds( 2 ) ); g_is_done.store( true ); t1.join(); t2.join(); t3.join(); return EXIT_SUCCESS; }
unsigned int __stdcall MyThreadFunction(void*) { EGraphicsApi graphicsApi = EGraphicsApi::D3D11; if (!LoadRenderApiImpl(graphicsApi)) { s_running.store(false); return 1; } // Init time QueryPerformanceFrequency(&s_perfFreq); QueryPerformanceCounter(&s_lastTime); GameInfo gameInfo; ZeroMemory(&gameInfo, sizeof(gameInfo)); gameInfo.graphicsApi = graphicsApi; gameInfo.imguiState = ImGui::GetCurrentContext(); //heapArea = new HeapArea(512 * 1024 * 1024); //memory::SimpleArena arena(heapArea); //gameInfo.allocator = &arena; gameInfo.CalculateDeltaTime = CalculateDeltaTime; gameInfo.gfxFuncs = g_renderApi; gameInfo.config = &s_config; gameInfo.controls = &s_controls; gameInfo.CreateThread = slCreateThread; gameInfo.reloadOnSave = true; // Hardware info { SYSTEM_INFO sysinfo; GetSystemInfo(&sysinfo); s_hardware.numLogicalThreads = (uint32_t) sysinfo.dwNumberOfProcessors; } gameInfo.hardware = &s_hardware; // ENet if (enet_initialize() != 0) { s_running.store(false); return 1; } // Main loop while (s_running.load()) { // Check if graphics API change was requested if (gameInfo.graphicsApi != graphicsApi) { if (LoadRenderApiImpl(gameInfo.graphicsApi)) { graphicsApi = gameInfo.graphicsApi; g_renderApi = gameInfo.gfxFuncs; } else { gameInfo.graphicsApi = graphicsApi; gameInfo.gfxFuncs = g_renderApi; } } #ifdef _DEBUG { // Reload DLL FILETIME NewDLLWriteTime = Win32GetLastWriteTime((char*)s_dllName); // If the .DLL is being written to, the last write time may change multiple times // So we need to add a cooldown LARGE_INTEGER currentTime; QueryPerformanceCounter(¤tTime); if (CompareFileTime(&NewDLLWriteTime, &s_gameFuncs.DLLLastWriteTime) != 0 && (currentTime.QuadPart - s_lastDLLLoadTime.QuadPart) / s_perfFreq.QuadPart >= 1) { if (s_gameFuncs.dll) { FreeLibrary(s_gameFuncs.dll); } s_gameFuncs = LoadGameFuncs(); g_LogInfo("Reloaded DLL."); } else { // Ignore changes s_gameFuncs.DLLLastWriteTime = NewDLLWriteTime; } } #endif // Reload Lua if (gameInfo.reloadOnSave) { DWORD obj = WaitForSingleObject(hDirectoryChange, 0); if (obj == WAIT_OBJECT_0) { if (!FindNextChangeNotification(hDirectoryChange)) { g_LogInfo("Error: FindNextChangeNotification failed."); } // TODO: Change only of lua files changed (or make separate lua directory) LARGE_INTEGER currentTime; static LARGE_INTEGER s_lastLuaLoadTime; QueryPerformanceCounter(¤tTime); if ((currentTime.QuadPart - s_lastLuaLoadTime.QuadPart) / s_perfFreq.QuadPart >= 1) { s_lastLuaLoadTime = currentTime; gameInfo.reloadLua = true; } } } ParseMessages(); g_renderApi->ImGuiNewFrame(); s_controls.BeginFrame(); s_gameFuncs.UpdateGame(&gameInfo); s_controls.EndFrame(); // Rendering g_renderApi->Render(); } s_gameFuncs.DestroyGame(&gameInfo); g_renderApi->Destroy(); ImGui::Shutdown(); g_renderApi = nullptr; //delete heapArea; enet_deinitialize(); return 0; }
NetworkTimerSynchronizer() { m_synchronised.store(false); m_force_set_timer.store(false); }
void on_window_resize(void *value) { flag_needs_recreate_swapchain.store(true); }
void DialogSystem::receive(const MouseClickEvent &mce) { game::entities.each<Position, Solid, Dialog, Name>( [&](entityx::Entity e, Position &pos, Solid &dim, Dialog &d, Name &name) { static std::atomic_bool dialogRun; (void)e; (void)d; if (((mce.position.x > pos.x) & (mce.position.x < pos.x + dim.width)) && ((mce.position.y > pos.y) & (mce.position.y < pos.y + dim.height))) { if (!dialogRun.load()) { std::thread([&] { std::string questAssignedText; int newIndex; auto exml = game::engine.getSystem<WorldSystem>()->getXML()->FirstChildElement("Dialog"); dialogRun.store(true); if (e.has_component<Direction>()) d.talking = true; if (d.index == 9999) { ui::dialogBox(name.name, "", false, randomDialog[d.rindex % randomDialog.size()]); ui::waitForDialog(); } else if (exml != nullptr) { while (exml->StrAttribute("name") != name.name) exml = exml->NextSiblingElement(); exml = exml->FirstChildElement("text"); while (exml->IntAttribute("id") != d.index) exml = exml->NextSiblingElement(); auto oxml = exml->FirstChildElement("set"); if (oxml != nullptr) { do game::setValue(oxml->StrAttribute("id"), oxml->StrAttribute("value")); while ((oxml = oxml->NextSiblingElement())); game::briceUpdate(); } auto qxml = exml->FirstChildElement("quest"); if (qxml != nullptr) { const char *qname; auto qsys = game::engine.getSystem<QuestSystem>(); do { // assign quest qname = qxml->Attribute("assign"); if (qname != nullptr) { questAssignedText = qname; auto req = qxml->GetText(); qsys->assign(qname, qxml->StrAttribute("desc"), req ? req : ""); } // check / finish quest else { qname = qxml->Attribute("check"); if (qname != nullptr) { if (qname != nullptr && qsys->hasQuest(qname) && qsys->finish(qname) == 0) { d.index = 9999; } else { ui::dialogBox(name.name, "", false, "Finish my quest u nug"); ui::waitForDialog(); return; } // oldidx = d.index; // d.index = qxml->UnsignedAttribute("fail"); // goto COMMONAIFUNC; } } } while((qxml = qxml->NextSiblingElement())); } auto cxml = exml->FirstChildElement("content"); const char *content; if (cxml == nullptr) { content = randomDialog[d.rindex % randomDialog.size()].c_str(); } else { content = cxml->GetText() - 1; while (*++content && isspace(*content)); } ui::dialogBox(name.name, "", false, content); ui::waitForDialog(); if (!questAssignedText.empty()) ui::passiveImportantText(5000, ("Quest assigned:\n\"" + questAssignedText + "\"").c_str()); if (exml->QueryIntAttribute("nextid", &newIndex) == XML_NO_ERROR) d.index = newIndex; } d.talking = false; dialogRun.store(false); }).detach(); } } }); }
extern "C" JNIEXPORT void JNICALL Java_eu_vcmi_vcmi_NativeMethods_notifyServerReady(JNIEnv * env, jobject cls) { logNetwork->info("Received server ready signal"); androidTestServerReadyFlag.store(true); }
int CALLBACK WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { s_gameFuncs = LoadGameFuncs(); assert(s_gameFuncs.valid); ImGuiIO& io = ImGui::GetIO(); //io.MemAllocFn = memory::malloc; //io.MemFreeFn = memory::free; //_crtBreakAlloc = 4015; s_queue = new util::ThreadSafeQueue<WindowEvent>(); g_LogInfo(SL_BUILD_DATE); // Log CPU features { #if 0 struct CPUInfo { union { int i[4]; }; } info = { 0 }; // Get number of functions __cpuid(info.i, 0); int nIds_ = info.i[0]; // Dump info std::vector<CPUInfo> data; for (int i = 0; i <= nIds_; ++i) { __cpuidex(info.i, i, 0); data.push_back(info); } // Vendor if(data.size() >= 0) { char vendor[13] = {0}; memcpy(vendor + 0, data[0].i + 1, 4); memcpy(vendor + 4, data[0].i + 3, 4); memcpy(vendor + 8, data[0].i + 2, 4); g_LogInfo("CPU Vendor: " + std::string(vendor)); } #endif // http://stackoverflow.com/questions/850774/how-to-determine-the-hardware-cpu-and-ram-on-a-machine int CPUInfo[4] = { 0 }; char CPUBrandString[0x40]; // Get the information associated with each extended ID. __cpuid(CPUInfo, 0x80000000); int nExIds = CPUInfo[0]; for (int i = 0x80000000; i <= nExIds; i++) { __cpuid(CPUInfo, i); // Interpret CPU brand string if (i == 0x80000002) memcpy(CPUBrandString, CPUInfo, sizeof(CPUInfo)); else if (i == 0x80000003) memcpy(CPUBrandString + 16, CPUInfo, sizeof(CPUInfo)); else if (i == 0x80000004) memcpy(CPUBrandString + 32, CPUInfo, sizeof(CPUInfo)); } //string includes manufacturer, model and clockspeed std::string brand(CPUBrandString); g_LogInfo(brand.substr(brand.find_first_not_of(" "))); SYSTEM_INFO sysInfo; GetSystemInfo(&sysInfo); g_LogInfo("Logical processors: " + std::to_string(sysInfo.dwNumberOfProcessors)); MEMORYSTATUSEX statex; statex.dwLength = sizeof (statex); GlobalMemoryStatusEx(&statex); g_LogInfo("Total System Memory: " + std::to_string(statex.ullTotalPhys/1024/1024) + " MB"); } auto className = L"StarlightClassName"; WNDCLASSEXW wndClass = { 0 }; wndClass.cbSize = sizeof(WNDCLASSEXW); wndClass.style = CS_CLASSDC; wndClass.lpfnWndProc = WndProc; wndClass.hInstance = GetModuleHandleW(nullptr); wndClass.hCursor = LoadCursorW(nullptr, IDC_ARROW); wndClass.lpszClassName = className; RegisterClassExW(&wndClass); // Get desktop rectangle RECT desktopRect; GetClientRect(GetDesktopWindow(), &desktopRect); // Get window rectangle RECT windowRect = { 0, 0, 800, 600 }; // TODO: Config file? AdjustWindowRect(&windowRect, WS_OVERLAPPEDWINDOW, FALSE); // Calculate window dimensions LONG windowWidth = windowRect.right - windowRect.left; LONG windowHeight = windowRect.bottom - windowRect.top; LONG x = desktopRect.right / 2 - windowWidth / 2; LONG y = desktopRect.bottom / 2 - windowHeight / 2; #ifdef _DEBUG // Move the screen to the right monitor on JOTARO wchar_t computerName[MAX_COMPUTERNAME_LENGTH + 1]; DWORD dwSize = sizeof(computerName); GetComputerNameW(computerName, &dwSize); if (wcscmp(computerName, L"JOTARO") == 0) { x += 1920; } #endif s_config.Load(); s_hwnd = CreateWindowExW( 0L, className, L"Starlight", WS_OVERLAPPEDWINDOW, x, y, windowWidth, windowHeight, nullptr, nullptr, GetModuleHandleW(nullptr), nullptr ); // Show the window ShowWindow(s_hwnd, SW_MAXIMIZE); UpdateWindow(s_hwnd); // Create thread s_running.store(true); unsigned int threadID; HANDLE thread = (HANDLE) _beginthreadex(nullptr, 0, MyThreadFunction, nullptr, 0, &threadID); if (!thread) { // Error creating thread return 1; } // Watch Lua directory hDirectoryChange = FindFirstChangeNotification(L"../starlight/", TRUE, FILE_NOTIFY_CHANGE_LAST_WRITE); if (!hDirectoryChange) { g_LogInfo("Error creating directory change notification handle: Lua reload on save will not work."); } // Message loop MSG msg; while (s_running.load() && GetMessageW(&msg, nullptr, 0, 0)) { TranslateMessage(&msg); DispatchMessageW(&msg); } WaitForSingleObject(thread, INFINITE); CloseHandle(thread); if (hDirectoryChange) { if (!FindCloseChangeNotification(hDirectoryChange)) { g_LogInfo("Failed to close directory change notification handle."); } } s_gameFuncs.DestroyLogger(); io.Fonts->Clear(); s_config.Save(); delete s_queue; UnregisterClassW(className, GetModuleHandleW(nullptr)); _CrtDumpMemoryLeaks(); return 0; }
void fiber_waiter::reset() noexcept { m_ready.store(false, std::memory_order_relaxed); m_fstnext.store(fsnext_init, std::memory_order_relaxed); m_promise_state.store(static_cast<unsigned>(ext::future_state::unsatisfied), std::memory_order_relaxed); }
void fiber_waiter::continuate(shared_state_basic * caller) noexcept { m_ready.store(true, std::memory_order_relaxed); m_thread_var.notify_all(); m_fiber_var.notify_all(); }
int main(int argc, char** argv) { bool desired_mode_full=false; //if false go in safe_mode bool ir_warning_; bool bumper_warning_; ros::init(argc, argv, "roomba560_node"); ROS_INFO("Roomba for ROS %.2f", NODE_VERSION); double last_x, last_y, last_yaw; double vel_x, vel_y, vel_yaw; double dt; float last_charge = 0.0; int time_remaining = -1; ros::NodeHandle n; ros::NodeHandle pn("~"); pn.param<std::string>("port", port, "/dev/ttyUSB0"); std::string base_frame_id; std::string odom_frame_id; pn.param<std::string>("base_frame_id", base_frame_id, "base_link"); pn.param<std::string>("odom_frame_id", odom_frame_id, "odom"); roomba = new irobot::OpenInterface(port.c_str()); ros::Publisher odom_pub = n.advertise<nav_msgs::Odometry>("odom", 50); ros::Publisher battery_pub = n.advertise<irobotcreate2::Battery>("battery", 50); ros::Publisher bumper_pub = n.advertise<irobotcreate2::Bumper>("bumper", 50); ros::Publisher buttons_pub = n.advertise<irobotcreate2::Buttons>("buttons", 50); ros::Publisher cliff_pub = n.advertise<irobotcreate2::RoombaIR>("cliff", 50); ros::Publisher irbumper_pub = n.advertise<irobotcreate2::RoombaIR>("ir_bumper", 50); ros::Publisher irchar_pub = n.advertise<irobotcreate2::IRCharacter>("ir_character", 50); ros::Publisher wheeldrop_pub = n.advertise<irobotcreate2::WheelDrop>("wheel_drop", 50); tf::TransformBroadcaster tf_broadcaster; ros::Subscriber cmd_vel_sub = n.subscribe<geometry_msgs::Twist>("cmd_vel", 1, cmdVelReceived); ros::Subscriber leds_sub = n.subscribe<irobotcreate2::Leds>("leds", 1, ledsReceived); ros::Subscriber digitleds_sub = n.subscribe<irobotcreate2::DigitLeds>("digit_leds", 1, digitLedsReceived); ros::Subscriber song_sub = n.subscribe<irobotcreate2::Song>("song", 1, songReceived); ros::Subscriber playsong_sub = n.subscribe<irobotcreate2::PlaySong>("play_song", 1, playSongReceived); ros::Subscriber mode_sub = n.subscribe<std_msgs::String>("mode", 1, cmdModeReceived); irobot::OI_Packet_ID sensor_packets[1] = {irobot::OI_PACKET_GROUP_100}; roomba->setSensorPackets(sensor_packets, 1, OI_PACKET_GROUP_100_SIZE); if( roomba->openSerialPort(true) == 0) ROS_INFO("Connected to Roomba."); else { ROS_FATAL("Could not connect to Roomba."); ROS_BREAK(); } ros::Time current_time, last_time; current_time = ros::Time::now(); last_time = ros::Time::now(); bool first_loop=true; ros::Rate r(10.0); while(n.ok()) { ir_warning_ = false; bumper_warning_ = false; current_time = ros::Time::now(); last_x = roomba->odometry_x_; last_y = roomba->odometry_y_; last_yaw = roomba->odometry_yaw_; if( roomba->getSensorPackets(100) == -1) ROS_ERROR("Could not retrieve sensor packets."); else roomba->calculateOdometry(); dt = (current_time - last_time).toSec(); vel_x = (roomba->odometry_x_ - last_x)/dt; vel_y = (roomba->odometry_y_ - last_y)/dt; vel_yaw = (roomba->odometry_yaw_ - last_yaw)/dt; // ****************************************************************************************** //first, we'll publish the transforms over tf geometry_msgs::TransformStamped odom_trans; odom_trans.header.stamp = current_time; odom_trans.header.frame_id = odom_frame_id; odom_trans.child_frame_id = "base_footprint"; odom_trans.transform.translation.x = roomba->odometry_x_; odom_trans.transform.translation.y = roomba->odometry_y_; odom_trans.transform.translation.z = 0.0; odom_trans.transform.rotation = tf::createQuaternionMsgFromYaw(roomba->odometry_yaw_); tf_broadcaster.sendTransform(odom_trans); geometry_msgs::TransformStamped base_trans; base_trans.header.stamp = current_time; base_trans.header.frame_id = "base_footprint"; base_trans.child_frame_id = base_frame_id; base_trans.transform.translation.x = 0.0; base_trans.transform.translation.y = 0.0; base_trans.transform.translation.z = 0.0; base_trans.transform.rotation.x = 0; base_trans.transform.rotation.y = 0; base_trans.transform.rotation.z = 0; base_trans.transform.rotation.w = 1; tf_broadcaster.sendTransform(base_trans); geometry_msgs::TransformStamped scan_trans; scan_trans.header.stamp = current_time; scan_trans.header.frame_id = base_frame_id; scan_trans.child_frame_id = "base_laser_link"; scan_trans.transform.translation.x = 0.0; scan_trans.transform.translation.y = 0.0; scan_trans.transform.translation.z = 0.0; scan_trans.transform.rotation.x = 0; scan_trans.transform.rotation.y = 0; scan_trans.transform.rotation.z = 0; scan_trans.transform.rotation.w = 1; tf_broadcaster.sendTransform(scan_trans); //TODO: Finish brodcasting the tf for all the ir sensors on the Roomba /*geometry_msgs::TransformStamped cliff_left_trans; cliff_left_trans.header.stamp = current_time; cliff_left_trans.header.frame_id = "base_link"; cliff_left_trans.child_frame_id = "base_cliff_left"; cliff_left_trans.transform.translation.x = 0.0; cliff_left_trans.transform.translation.y = 0.0; cliff_left_trans.transform.translation.z = 0.0; cliff_left_trans.transform.rotation = ; tf_broadcaster.sendTransform(cliff_left_trans); */ // ****************************************************************************************** //next, we'll publish the odometry message over ROS nav_msgs::Odometry odom; odom.header.stamp = current_time; odom.header.frame_id = odom_frame_id; //set the position odom.pose.pose.position.x = roomba->odometry_x_; odom.pose.pose.position.y = roomba->odometry_y_; odom.pose.pose.position.z = 0.0; odom.pose.pose.orientation = tf::createQuaternionMsgFromYaw(roomba->odometry_yaw_); //set the velocity odom.child_frame_id = base_frame_id; odom.twist.twist.linear.x = vel_x; odom.twist.twist.linear.y = vel_y; odom.twist.twist.angular.z = vel_yaw; //publish the message odom_pub.publish(odom); // ****************************************************************************************** //publish battery irobotcreate2::Battery battery; battery.header.stamp = current_time; battery.power_cord = roomba->power_cord_; battery.dock = roomba->dock_; battery.level = 100.0*(roomba->charge_/roomba->capacity_); if(last_charge > roomba->charge_) time_remaining = (int)(battery.level/((last_charge-roomba->charge_)/roomba->capacity_)/dt)/60; last_charge = roomba->charge_; battery.time_remaining = time_remaining; battery_pub.publish(battery); // ****************************************************************************************** //publish bumpers irobotcreate2::Bumper bumper; bumper.left.header.stamp = current_time; bumper.left.state = roomba->bumper_[LEFT]; bumper.right.header.stamp = current_time; bumper.right.state = roomba->bumper_[RIGHT]; bumper_pub.publish(bumper); bumper_warning_ = bumper.left.state || bumper.right.state; bumper_warning.store(bumper_warning_); // ****************************************************************************************** //publish buttons irobotcreate2::Buttons buttons; buttons.header.stamp = current_time; buttons.clean = roomba->buttons_[BUTTON_CLEAN]; buttons.spot = roomba->buttons_[BUTTON_SPOT]; buttons.dock = roomba->buttons_[BUTTON_DOCK]; buttons.day = roomba->buttons_[BUTTON_DAY]; buttons.hour = roomba->buttons_[BUTTON_HOUR]; buttons.minute = roomba->buttons_[BUTTON_MINUTE]; buttons.schedule = roomba->buttons_[BUTTON_SCHEDULE]; buttons.clock = roomba->buttons_[BUTTON_CLOCK]; buttons_pub.publish(buttons); // ****************************************************************************************** //publish cliff irobotcreate2::RoombaIR cliff; cliff.header.stamp = current_time; cliff.header.frame_id = "base_cliff_left"; cliff.state = roomba->cliff_[LEFT]; cliff.signal = roomba->cliff_signal_[LEFT]; cliff_pub.publish(cliff); cliff.header.frame_id = "base_cliff_front_left"; cliff.state = roomba->cliff_[FRONT_LEFT]; cliff.signal = roomba->cliff_signal_[FRONT_LEFT]; cliff_pub.publish(cliff); cliff.header.frame_id = "base_cliff_front_right"; cliff.state = roomba->cliff_[FRONT_RIGHT]; cliff.signal = roomba->cliff_signal_[FRONT_RIGHT]; cliff_pub.publish(cliff); cliff.header.frame_id = "base_cliff_right"; cliff.state = roomba->cliff_[RIGHT]; cliff.signal = roomba->cliff_signal_[RIGHT]; cliff_pub.publish(cliff); // ****************************************************************************************** //publish irbumper irobotcreate2::RoombaIR irbumper; irbumper.header.stamp = current_time; irbumper.header.frame_id = "base_irbumper_left"; irbumper.state = roomba->ir_bumper_[LEFT]; irbumper.signal = roomba->ir_bumper_signal_[LEFT]; irbumper_pub.publish(irbumper); ir_warning_ = ir_warning_ || irbumper.state; irbumper.header.frame_id = "base_irbumper_front_left"; irbumper.state = roomba->ir_bumper_[FRONT_LEFT]; irbumper.signal = roomba->ir_bumper_signal_[FRONT_LEFT]; irbumper_pub.publish(irbumper); ir_warning_ = ir_warning_ || irbumper.state; irbumper.header.frame_id = "base_irbumper_center_left"; irbumper.state = roomba->ir_bumper_[CENTER_LEFT]; irbumper.signal = roomba->ir_bumper_signal_[CENTER_LEFT]; irbumper_pub.publish(irbumper); ir_warning_ = ir_warning_ || irbumper.state; irbumper.header.frame_id = "base_irbumper_center_right"; irbumper.state = roomba->ir_bumper_[CENTER_RIGHT]; irbumper.signal = roomba->ir_bumper_signal_[CENTER_RIGHT]; irbumper_pub.publish(irbumper); ir_warning_ = ir_warning_ || irbumper.state; irbumper.header.frame_id = "base_irbumper_front_right"; irbumper.state = roomba->ir_bumper_[FRONT_RIGHT]; irbumper.signal = roomba->ir_bumper_signal_[FRONT_RIGHT]; irbumper_pub.publish(irbumper); ir_warning_ = ir_warning_ || irbumper.state; irbumper.header.frame_id = "base_irbumper_right"; irbumper.state = roomba->ir_bumper_[RIGHT]; irbumper.signal = roomba->ir_bumper_signal_[RIGHT]; irbumper_pub.publish(irbumper); ir_warning_ = ir_warning_ || irbumper.state; ir_warning.store(ir_warning_); // ****************************************************************************************** //publish irchar irobotcreate2::IRCharacter irchar; irchar.header.stamp = current_time; irchar.omni = roomba->ir_char_[OMNI]; irchar.left = roomba->ir_char_[LEFT]; irchar.right = roomba->ir_char_[RIGHT]; irchar_pub.publish(irchar); // ****************************************************************************************** //publish wheeldrop irobotcreate2::WheelDrop wheeldrop; wheeldrop.left.header.stamp = current_time; wheeldrop.left.state = roomba->wheel_drop_[LEFT]; wheeldrop.right.header.stamp = current_time; wheeldrop.right.state = roomba->wheel_drop_[RIGHT]; wheeldrop_pub.publish(wheeldrop); ros::spinOnce(); r.sleep(); if(first_loop) { roomba->startOI(true); if(!desired_mode_full) roomba->Safe(); first_loop=false; } } // roomba->powerDown(); // do not powerDown the Roomba! roomba->closeSerialPort(); }
// ------------------------------------------------------------------------ void enableForceSetTimer() { if (m_synchronised.load() == true) return; m_force_set_timer.store(true); }
// ------------------------------------------------------------------------ void resynchroniseTimer() { m_synchronised.store(false); }