| 1 | /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ |
| 2 | /* If you are missing that file, acquire a complete release at teeworlds.com. */ |
| 3 | |
| 4 | #include <base/logger.h> |
| 5 | #include <base/system.h> |
| 6 | |
| 7 | #include <engine/console.h> |
| 8 | #include <engine/engine.h> |
| 9 | #include <engine/shared/config.h> |
| 10 | #include <engine/shared/jobs.h> |
| 11 | #include <engine/shared/network.h> |
| 12 | #include <engine/storage.h> |
| 13 | |
| 14 | #include <thread> |
| 15 | |
| 16 | class CEngine : public IEngine |
| 17 | { |
| 18 | IConsole *m_pConsole; |
| 19 | IStorage *m_pStorage; |
| 20 | |
| 21 | bool m_Logging; |
| 22 | std::shared_ptr<CFutureLogger> m_pFutureLogger; |
| 23 | |
| 24 | char m_aAppName[256]; |
| 25 | |
| 26 | CJobPool m_JobPool; |
| 27 | |
| 28 | static void Con_DbgLognetwork(IConsole::IResult *pResult, void *pUserData) |
| 29 | { |
| 30 | CEngine *pEngine = static_cast<CEngine *>(pUserData); |
| 31 | |
| 32 | if(pEngine->m_Logging) |
| 33 | { |
| 34 | CNetBase::CloseLog(); |
| 35 | pEngine->m_Logging = false; |
| 36 | } |
| 37 | else |
| 38 | { |
| 39 | char aBuf[32]; |
| 40 | str_timestamp(buffer: aBuf, buffer_size: sizeof(aBuf)); |
| 41 | char aFilenameSent[IO_MAX_PATH_LENGTH], aFilenameRecv[IO_MAX_PATH_LENGTH]; |
| 42 | str_format(buffer: aFilenameSent, buffer_size: sizeof(aFilenameSent), format: "dumps/network_sent_%s.txt" , aBuf); |
| 43 | str_format(buffer: aFilenameRecv, buffer_size: sizeof(aFilenameRecv), format: "dumps/network_recv_%s.txt" , aBuf); |
| 44 | CNetBase::OpenLog(DataLogSent: pEngine->m_pStorage->OpenFile(pFilename: aFilenameSent, Flags: IOFLAG_WRITE, Type: IStorage::TYPE_SAVE), |
| 45 | DataLogRecv: pEngine->m_pStorage->OpenFile(pFilename: aFilenameRecv, Flags: IOFLAG_WRITE, Type: IStorage::TYPE_SAVE)); |
| 46 | pEngine->m_Logging = true; |
| 47 | } |
| 48 | } |
| 49 | |
| 50 | public: |
| 51 | CEngine(bool Test, const char *pAppname, std::shared_ptr<CFutureLogger> pFutureLogger) : |
| 52 | m_pFutureLogger(std::move(pFutureLogger)) |
| 53 | { |
| 54 | str_copy(dst&: m_aAppName, src: pAppname); |
| 55 | if(!Test) |
| 56 | { |
| 57 | log_info("engine" , "running on %s-%s-%s" , CONF_FAMILY_STRING, CONF_PLATFORM_STRING, CONF_ARCH_STRING); |
| 58 | log_info("engine" , "arch is %s" , CONF_ARCH_ENDIAN_STRING); |
| 59 | |
| 60 | char aVersionStr[128]; |
| 61 | if(os_version_str(version: aVersionStr, length: sizeof(aVersionStr))) |
| 62 | { |
| 63 | log_info("engine" , "operating system version: %s" , aVersionStr); |
| 64 | } |
| 65 | |
| 66 | // init the network |
| 67 | net_init(); |
| 68 | CNetBase::Init(); |
| 69 | } |
| 70 | |
| 71 | #if defined(CONF_PLATFORM_EMSCRIPTEN) |
| 72 | // Make sure we don't use more threads than allowed in total (see PTHREAD_POOL_SIZE in Emscripten.toolchain) |
| 73 | // otherwise starting more threads may lead to deadlocks as the threads will simply not start. |
| 74 | const size_t ThreadCount = 4; |
| 75 | #else |
| 76 | const size_t ThreadCount = std::max(a: 4, b: (int)std::thread::hardware_concurrency()) - 2; |
| 77 | #endif |
| 78 | m_JobPool.Init(NumThreads: ThreadCount); |
| 79 | |
| 80 | m_Logging = false; |
| 81 | } |
| 82 | |
| 83 | ~CEngine() override |
| 84 | { |
| 85 | CNetBase::CloseLog(); |
| 86 | } |
| 87 | |
| 88 | void Init() override |
| 89 | { |
| 90 | m_pConsole = Kernel()->RequestInterface<IConsole>(); |
| 91 | m_pStorage = Kernel()->RequestInterface<IStorage>(); |
| 92 | |
| 93 | if(!m_pConsole || !m_pStorage) |
| 94 | return; |
| 95 | |
| 96 | m_pConsole->Register(pName: "dbg_lognetwork" , pParams: "" , Flags: CFGFLAG_SERVER | CFGFLAG_CLIENT, pfnFunc: Con_DbgLognetwork, pUser: this, pHelp: "Log the network" ); |
| 97 | } |
| 98 | |
| 99 | void AddJob(std::shared_ptr<IJob> pJob) override |
| 100 | { |
| 101 | m_JobPool.Add(pJob: std::move(pJob)); |
| 102 | } |
| 103 | |
| 104 | void ShutdownJobs() override |
| 105 | { |
| 106 | m_JobPool.Shutdown(); |
| 107 | } |
| 108 | |
| 109 | void SetAdditionalLogger(std::shared_ptr<ILogger> &&pLogger) override |
| 110 | { |
| 111 | m_pFutureLogger->Set(pLogger); |
| 112 | } |
| 113 | }; |
| 114 | |
| 115 | IEngine *CreateEngine(const char *pAppname, std::shared_ptr<CFutureLogger> pFutureLogger) { return new CEngine(false, pAppname, std::move(pFutureLogger)); } |
| 116 | IEngine *CreateTestEngine(const char *pAppname) { return new CEngine(true, pAppname, nullptr); } |
| 117 | |