Add switch support (BROKEN) and TessesFrameworkFeatures.h and CertificateChain.hpp will be installed properly
This commit is contained in:
@ -52,16 +52,17 @@ option(TESSESFRAMEWORK_ENABLE_APPS "Enable Tesses Framework cli apps" ON)
|
||||
option(TESSESFRAMEWORK_INSTALL_DEVELOPMENT "Enable Installing Tesses Framework Development Packages" ON)
|
||||
option(TESSESFRAMEWORK_ENABLE_STATIC "Enable Tesses Framework Static Libraries" ON)
|
||||
option(TESSESFRAMEWORK_ENABLE_SHARED "Enable Tesses Framework Shared Libraries" ON)
|
||||
option(TESSESFRAMEWORK_LOGTOFILE "TessesFramework Log to file" ON)
|
||||
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include)
|
||||
|
||||
if(TESSESFRAMEWORK_ENABLE_MBED)
|
||||
if(TESSESFRAMEWORK_EMBED_CERT_BUNDLE)
|
||||
include(cmake/bin2h.cmake)
|
||||
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/include/CertificateChain.h "#pragma once\n")
|
||||
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/include/TessesFramework/CertificateChain.h "#pragma once\n")
|
||||
#target_compile_definitions(TessesFramework PUBLIC TESSESFRAMEWORK_EMBED_CERT_BUNDLE)
|
||||
bin2h(SOURCE_FILE ${TESSESFRAMEWORK_CERT_BUNDLE_FILE} HEADER_FILE ${CMAKE_CURRENT_BINARY_DIR}/include/CertificateChain.h VARIABLE_NAME CertificateChain APPEND NULL_TERMINATE)
|
||||
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/include/CertificateChain.h "\n")
|
||||
bin2h(SOURCE_FILE ${TESSESFRAMEWORK_CERT_BUNDLE_FILE} HEADER_FILE ${CMAKE_CURRENT_BINARY_DIR}/include/TessesFramework/CertificateChain.h VARIABLE_NAME CertificateChain APPEND NULL_TERMINATE)
|
||||
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/include/TessesFramework/CertificateChain.h "\n")
|
||||
#else()
|
||||
#target_compile_definitions(TessesFramework PUBLIC TESSESFRAMEWORK_CERT_BUNDLE_FILE=${TESSESFRAMEWORK_CERT_BUNDLE_FILE})
|
||||
|
||||
@ -89,13 +90,17 @@ target_include_directories(${TessesFramework_TARGET} PUBLIC ${MBEDTLS_DIR}/inclu
|
||||
target_link_directories(${TessesFramework_TARGET} PUBLIC ${MBEDTLS_DIR}/lib)
|
||||
endif()
|
||||
target_link_libraries(${TessesFramework_TARGET} PUBLIC mbedtls mbedx509 mbedcrypto)
|
||||
target_include_directories(${TessesFramework_TARGET} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/include)
|
||||
endif()
|
||||
target_include_directories(${TessesFramework_TARGET}
|
||||
PUBLIC
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>"
|
||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
|
||||
)
|
||||
target_include_directories(${TessesFramework_TARGET}
|
||||
PUBLIC
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/include>"
|
||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
|
||||
)
|
||||
if("${CMAKE_SYSTEM_NAME}" STREQUAL "NintendoWii" OR "${CMAKE_SYSTEM_NAME}" STREQUAL "NintendoGameCube")
|
||||
target_link_libraries(${TessesFramework_TARGET} PUBLIC fat)
|
||||
endif()
|
||||
@ -145,7 +150,8 @@ install(TARGETS ${TessesFrameworkLibs}
|
||||
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||
)
|
||||
|
||||
install(DIRECTORY include/TessesFramework DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/TessesFramework DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/TessesFramework DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
|
||||
install(EXPORT TessesFrameworkTargets
|
||||
FILE TessesFrameworkTargets.cmake
|
||||
@ -157,15 +163,13 @@ install(EXPORT TessesFrameworkTargets
|
||||
include(CMakePackageConfigHelpers)
|
||||
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/TessesFrameworkConfig.cmake"
|
||||
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/TessesFramework)
|
||||
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/TessesFrameworkFeatures.h.in "${CMAKE_CURRENT_BINARY_DIR}/TessesFrameworkFeatures.h"
|
||||
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/TessesFrameworkFeatures.h.in "${CMAKE_CURRENT_BINARY_DIR}/include/TessesFramework/TessesFrameworkFeatures.h"
|
||||
INSTALL_DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/TessesFramework/TessesFrameworkFeatures.h)
|
||||
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/TessesFrameworkConfig.cmake"
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/TessesFramework)
|
||||
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/TessesFrameworkFeatures.h"
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/TessesFramework)
|
||||
endif()
|
||||
|
||||
if(TESSESFRAMEWORK_ENABLE_EXAMPLES)
|
||||
add_executable(copyfile examples/copyfile.cpp)
|
||||
target_link_libraries(copyfile PUBLIC tessesframework)
|
||||
|
||||
@ -14,5 +14,9 @@
|
||||
#if TESSES_FRAMEWORK_FLAG_@TESSESFRAMEWORK_ENABLE_THREADING@
|
||||
#define TESSESFRAMEWORK_ENABLE_THREADING
|
||||
#endif
|
||||
|
||||
#if TESSES_FRAMEWORK_FLAG_@TESSESFRAMEWORK_LOGTOFILE@
|
||||
#define TESSESFRAMEWORK_LOGTOFILE
|
||||
#endif
|
||||
#undef TESSES_FRAMEWORK_FLAG_OFF
|
||||
#undef TESSES_FRAMEWORK_FLAG_ON
|
||||
|
||||
@ -14,8 +14,10 @@ void print_help(const char* name)
|
||||
}
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
TF_Init();
|
||||
try {
|
||||
|
||||
TF_InitWithConsole();
|
||||
TF_LOG("INIT");
|
||||
const char* directory = "wwwroot";
|
||||
bool spa=false;
|
||||
bool allowListing = false;
|
||||
@ -54,11 +56,18 @@ int main(int argc, char** argv)
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "In folder: " << std::filesystem::absolute(directory).string() << std::endl;
|
||||
|
||||
|
||||
FileServer fs(directory,allowListing, spa);
|
||||
HttpServer server(port,fs);
|
||||
server.StartAccepting();
|
||||
TF_RunEventLoop();
|
||||
std::cout << "Closing server" << std::endl;
|
||||
TF_Quit();
|
||||
}catch(std::exception& ex)
|
||||
{
|
||||
TF_LOG(ex.what());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -86,12 +86,14 @@ class MyOtherWebServer : public IHttpServer
|
||||
public:
|
||||
bool Handle(ServerContext& ctx)
|
||||
{
|
||||
TF_LOG("IN HANDLE");
|
||||
if(ctx.path == "/")
|
||||
{
|
||||
std::string name;
|
||||
if(ctx.queryParams.TryGetFirst("name",name))
|
||||
{
|
||||
std::cout << name << std::endl;
|
||||
TF_LOG(name);
|
||||
ctx
|
||||
.WithMimeType("text/plain")
|
||||
.WithContentDisposition(HttpUtils::Sanitise(name) + ".txt",false)
|
||||
@ -114,7 +116,7 @@ class MyOtherWebServer : public IHttpServer
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
TF_Init();
|
||||
TF_InitWithConsole();
|
||||
MyOtherWebServer myo;
|
||||
MyWebServer mws;
|
||||
|
||||
|
||||
@ -30,9 +30,24 @@
|
||||
namespace Tesses::Framework
|
||||
{
|
||||
void TF_Init();
|
||||
void TF_InitWithConsole();
|
||||
void TF_ConnectToSelf(uint16_t port);
|
||||
void TF_RunEventLoop();
|
||||
void TF_RunEventLoopItteration();
|
||||
bool TF_IsRunning();
|
||||
void TF_Quit();
|
||||
bool TF_GetConsoleEventsEnabled();
|
||||
void TF_SetConsoleEventsEnabled(bool flag);
|
||||
void TF_InitConsole();
|
||||
#define TESSESFRAMEWORK_LOGTOFILE
|
||||
#if defined(TESSESFRAMEWORK_LOGTOFILE)
|
||||
void TF_Log(std::string dataToLog);
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(TESSESFRAMEWORK_LOGTOFILE)
|
||||
#define TF_LOG(log) Tesses::Framework::TF_Log(log)
|
||||
#else
|
||||
#define TF_LOG(log)
|
||||
#endif
|
||||
}
|
||||
@ -15,6 +15,7 @@ namespace Tesses::Framework::Streams
|
||||
TcpServer(std::string ip, uint16_t port, int32_t backlog);
|
||||
NetworkStream* GetStream(std::string& ip, uint16_t& port);
|
||||
~TcpServer();
|
||||
bool IsValid();
|
||||
void Close();
|
||||
};
|
||||
class NetworkStream : public Stream {
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include <windows.h>
|
||||
#elif defined(GEKKO)
|
||||
#include <ogc/lwp.h>
|
||||
#elif defined(__SWITCH__)
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
#if defined(TESSESFRAMEWORK_ENABLE_MBED)
|
||||
#if defined(TESSESFRAMEWORK_EMBED_CERT_BUNDLE)
|
||||
#include "CertificateChain.h"
|
||||
#include "TessesFramework/CertificateChain.h"
|
||||
#else
|
||||
#include "TessesFramework/TextStreams/StreamReader.hpp"
|
||||
using StreamReader = Tesses::Framework::TextStreams::StreamReader;
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include "TessesFramework/Filesystem/SubdirFilesystem.hpp"
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
#include "TessesFramework/Common.hpp"
|
||||
using LocalFilesystem = Tesses::Framework::Filesystem::LocalFilesystem;
|
||||
using SubdirFilesystem = Tesses::Framework::Filesystem::SubdirFilesystem;
|
||||
using VFSPath = Tesses::Framework::Filesystem::VFSPath;
|
||||
@ -38,7 +39,7 @@ namespace Tesses::Framework::Http
|
||||
}
|
||||
bool FileServer::SendFile(ServerContext& ctx,VFSPath path)
|
||||
{
|
||||
|
||||
TF_LOG("File: " + path.ToString());
|
||||
auto strm = this->vfs->OpenFile(path,"rb");
|
||||
bool retVal = false;
|
||||
if(strm != nullptr)
|
||||
@ -58,11 +59,15 @@ namespace Tesses::Framework::Http
|
||||
|
||||
if(this->vfs->DirectoryExists(path))
|
||||
{
|
||||
TF_LOG("Directory exists");
|
||||
for(auto f : defaultNames)
|
||||
{
|
||||
VFSPath p(path,f);
|
||||
|
||||
|
||||
VFSPath p=path;
|
||||
p = p / f;
|
||||
TF_LOG("Trying " + p.ToString());
|
||||
TF_LOG("Before file exists");
|
||||
TF_LOG(this->vfs->FileExists(p)?"File Exists" : "File Does Not Exist");
|
||||
TF_LOG("After file exists");
|
||||
if(this->vfs->FileExists(p))
|
||||
return SendFile(ctx,p);
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
#include "TessesFramework/Http/HttpStream.hpp"
|
||||
#include "TessesFramework/Crypto/MbedHelpers.hpp"
|
||||
#include "TessesFramework/Threading/Mutex.hpp"
|
||||
#include "TessesFramework/Common.hpp"
|
||||
|
||||
#include <iostream>
|
||||
using FileStream = Tesses::Framework::Streams::FileStream;
|
||||
@ -536,20 +537,36 @@ namespace Tesses::Framework::Http
|
||||
if(http == nullptr) return;
|
||||
auto svr=this->server;
|
||||
auto http = this->http;
|
||||
TF_LOG("Before Creating Thread");
|
||||
thrd = new Threading::Thread([svr,http]()->void {
|
||||
while(TF_IsRunning())
|
||||
{
|
||||
TF_LOG("after TF_IsRunning");
|
||||
std::string ip;
|
||||
uint16_t port;
|
||||
auto sock =svr->GetStream(ip,port);
|
||||
if(sock == nullptr) return;
|
||||
|
||||
TF_LOG("New Host IP: " + ip + ":" + std::to_string(port));
|
||||
|
||||
if(sock == nullptr)
|
||||
{
|
||||
std::cout << "STREAM ERROR" << std::endl;
|
||||
return;
|
||||
}
|
||||
TF_LOG("Before entering socket thread");
|
||||
Threading::Thread thrd2([sock,http,ip,port]()->void {
|
||||
TF_LOG("In thread to process");
|
||||
HttpServer::Process(*sock,*http,ip,port,false);
|
||||
TF_LOG("In thread after process");
|
||||
delete sock;
|
||||
});
|
||||
TF_LOG("Before attach");
|
||||
thrd2.Detach();
|
||||
TF_LOG("After attach");
|
||||
}
|
||||
});
|
||||
TF_LOG("Before printing interfaces");
|
||||
|
||||
std::cout << "\e[34mInterfaces:\n";
|
||||
for(auto _ip : NetworkStream::GetIPs())
|
||||
{
|
||||
@ -558,7 +575,9 @@ namespace Tesses::Framework::Http
|
||||
std::cout << "\e[35mhttp://";
|
||||
std::cout << _ip.second << ":" << std::to_string(this->port) << "/\n";
|
||||
}
|
||||
if(!svr->IsValid()) std::cout << "\e[31mError, we failed to bind or something\e[39m\n" << std::endl;
|
||||
std::cout << "\e[31mAlmost Ready to Listen\e[39m\n";
|
||||
TF_LOG("After printing interfaces");
|
||||
}
|
||||
HttpServer::~HttpServer()
|
||||
{
|
||||
@ -834,7 +853,7 @@ namespace Tesses::Framework::Http
|
||||
}
|
||||
void HttpServer::Process(Stream& strm, IHttpServer& server, std::string ip, uint16_t port, bool encrypted)
|
||||
{
|
||||
|
||||
TF_LOG("In process");
|
||||
while(true)
|
||||
{
|
||||
BufferedStream bStrm(strm);
|
||||
@ -863,6 +882,8 @@ namespace Tesses::Framework::Http
|
||||
ctx.originalPath = pp[0];
|
||||
ctx.path = ctx.originalPath;
|
||||
|
||||
TF_LOG(ctx.method + " with path " + ctx.path);
|
||||
|
||||
auto queryPart = pp[1];
|
||||
if(!queryPart.empty())
|
||||
{
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
#include "TessesFramework/Streams/NetworkStream.hpp"
|
||||
#include "TessesFramework/Http/HttpUtils.hpp"
|
||||
|
||||
#include <iostream>
|
||||
using HttpUtils = Tesses::Framework::Http::HttpUtils;
|
||||
#if defined(TESSESFRAMEWORK_ENABLE_NETWORKING)
|
||||
|
||||
@ -36,7 +36,7 @@ extern "C" {
|
||||
#if defined(GEKKO)
|
||||
|
||||
extern "C" uint32_t if_config( char *local_ip, char *netmask, char *gateway,bool use_dhcp, int max_retries);
|
||||
#elif !defined(_WIN32) && !defined(__ANDROID__)
|
||||
#elif !defined(_WIN32) && !defined(__ANDROID__) && !defined(__SWITCH__)
|
||||
#include <ifaddrs.h>
|
||||
#endif
|
||||
|
||||
@ -75,7 +75,7 @@ namespace Tesses::Framework::Streams {
|
||||
char gateway[16];
|
||||
if_config(localIp,netmask, gateway, true, 1);
|
||||
ipConfig.push_back(std::pair<std::string,std::string>("net",localIp));
|
||||
#elif defined(_WIN32) || defined(__ANDROID__)
|
||||
#elif defined(_WIN32) || defined(__ANDROID__) || defined(__SWITCH__)
|
||||
|
||||
#else
|
||||
struct ifaddrs *ifAddrStruct = NULL;
|
||||
@ -228,6 +228,7 @@ namespace Tesses::Framework::Streams {
|
||||
this->sock = NETWORK_SOCKET(AF_INET, SOCK_STREAM, 0);
|
||||
if(this->sock < 0)
|
||||
{
|
||||
std::cout << "FAILED TO CREATE SOCKET FOR SOME REASON" << std::endl;
|
||||
this->valid=false;
|
||||
return;
|
||||
}
|
||||
@ -245,17 +246,23 @@ namespace Tesses::Framework::Streams {
|
||||
#endif
|
||||
if(NETWORK_BIND(this->sock, (const sockaddr*)&addr, (socklen_t)sizeof(addr)) != 0)
|
||||
{
|
||||
std::cout << "FAILED TO BIND FOR SOME REASON" << std::endl;
|
||||
this->valid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if(NETWORK_LISTEN(this->sock, backlog) != 0)
|
||||
{
|
||||
std::cout << "FAILED TO LISTEN FOR SOME REASON" << std::endl;
|
||||
this->valid = false;
|
||||
return;
|
||||
}
|
||||
this->valid = true;
|
||||
}
|
||||
bool TcpServer::IsValid()
|
||||
{
|
||||
return this->valid;
|
||||
}
|
||||
TcpServer::TcpServer(std::string ip, uint16_t port, int32_t backlog)
|
||||
{
|
||||
this->owns=true;
|
||||
@ -345,14 +352,14 @@ namespace Tesses::Framework::Streams {
|
||||
if(ipV6)
|
||||
{
|
||||
#if defined(AF_INET6)
|
||||
this->sock = socket(AF_INET6, datagram ? SOCK_DGRAM : SOCK_STREAM, 0);
|
||||
this->sock = NETWORK_SOCKET(AF_INET6, datagram ? SOCK_DGRAM : SOCK_STREAM, 0);
|
||||
if(this->sock >= 0) this->success=true;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(AF_INET)
|
||||
this->sock = socket(AF_INET, datagram ? SOCK_DGRAM : SOCK_STREAM, 0);
|
||||
this->sock = NETWORK_SOCKET(AF_INET, datagram ? SOCK_DGRAM : SOCK_STREAM, 0);
|
||||
if(this->sock >= 0) this->success=true;
|
||||
#endif
|
||||
}
|
||||
@ -563,6 +570,7 @@ namespace Tesses::Framework::Streams {
|
||||
int noDelay2 = noDelay;
|
||||
NETWORK_SETSOCKOPT(this->sock, SOL_SOCKET, TCP_NODELAY, (const char*)&noDelay2,(socklen_t)sizeof(noDelay2));
|
||||
}
|
||||
|
||||
}
|
||||
#else
|
||||
namespace Tesses::Framework::Streams {
|
||||
@ -587,6 +595,10 @@ TcpServer::~TcpServer()
|
||||
{
|
||||
|
||||
}
|
||||
bool TcpServer::IsValid()
|
||||
{
|
||||
return this->valid;
|
||||
}
|
||||
void TcpServer::Close()
|
||||
{
|
||||
|
||||
|
||||
104
src/TF_Init.cpp
104
src/TF_Init.cpp
@ -5,6 +5,10 @@
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#include <cstdio>
|
||||
#elif defined(__SWITCH__)
|
||||
extern "C" {
|
||||
#include <switch.h>
|
||||
}
|
||||
#elif defined(GEKKO)
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -25,10 +29,23 @@ static GXRModeObj *rmode = NULL;
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(TESSESFRAMEWORK_ENABLE_THREADING)
|
||||
#include "TessesFramework/Threading/Mutex.hpp"
|
||||
#endif
|
||||
|
||||
namespace Tesses::Framework
|
||||
{
|
||||
|
||||
#if defined(TESSESFRAMEWORK_ENABLE_THREADING) && (defined(GEKKO) || defined(__SWITCH__))
|
||||
namespace Threading
|
||||
{
|
||||
extern void JoinAllThreads();
|
||||
extern void LookForFinishedThreads();
|
||||
}
|
||||
#endif
|
||||
volatile static bool isRunningSig=true;
|
||||
volatile static std::atomic<bool> isRunning;
|
||||
volatile static std::atomic<bool> gaming_console_events=true;
|
||||
void TF_ConnectToSelf(uint16_t port)
|
||||
{
|
||||
Tesses::Framework::Streams::NetworkStream ns("127.0.0.1",port,false,false,false);
|
||||
@ -49,21 +66,52 @@ namespace Tesses::Framework
|
||||
TF_RunEventLoopItteration();
|
||||
}
|
||||
}
|
||||
#if defined(__SWITCH__)
|
||||
bool initedConsole=false;
|
||||
PadState default_pad;
|
||||
#endif
|
||||
void TF_RunEventLoopItteration()
|
||||
{
|
||||
#if defined(TESSESFRAMEWORK_ENABLE_THREADING) && (defined(GEKKO) || defined(__SWITCH__))
|
||||
Tesses::Framework::Threading::LookForFinishedThreads();
|
||||
#endif
|
||||
|
||||
if(!isRunningSig) isRunning=false;
|
||||
#if defined(GEKKO)
|
||||
if(gaming_console_events)
|
||||
{
|
||||
PAD_ScanPads();
|
||||
if(PAD_ButtonsDown(0) & PAD_BUTTON_START) isRunning=false;
|
||||
}
|
||||
#elif defined(__SWITCH__)
|
||||
if(gaming_console_events)
|
||||
{
|
||||
if(!appletMainLoop()) isRunning=false;
|
||||
|
||||
padUpdate(&default_pad);
|
||||
|
||||
u64 kDown = padGetButtonsDown(&default_pad);
|
||||
|
||||
if (kDown & HidNpadButton_Plus)
|
||||
isRunning=false;
|
||||
|
||||
|
||||
if(initedConsole)
|
||||
consoleUpdate(NULL);
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void TF_Quit()
|
||||
{
|
||||
isRunning=false;
|
||||
#if defined(TESSESFRAMEWORK_ENABLE_THREADING) && (defined(GEKKO) || defined(__SWITCH__))
|
||||
Tesses::Framework::Threading::JoinAllThreads();
|
||||
#endif
|
||||
}
|
||||
|
||||
void TF_Init()
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
@ -91,6 +139,29 @@ if (iResult != 0) {
|
||||
#endif
|
||||
WPAD_Init();
|
||||
#endif
|
||||
#elif defined(__SWITCH__)
|
||||
padConfigureInput(1, HidNpadStyleSet_NpadStandard);
|
||||
padInitializeDefault(&default_pad);
|
||||
socketInitializeDefault();
|
||||
|
||||
// Initialize the default gamepad (which reads handheld mode inputs as well as the first connected controller)
|
||||
#else
|
||||
signal(SIGPIPE,SIG_IGN);
|
||||
signal(SIGINT,_sigInt);
|
||||
#endif
|
||||
|
||||
}
|
||||
bool TF_GetConsoleEventsEnabled()
|
||||
{
|
||||
return gaming_console_events;
|
||||
}
|
||||
void TF_SetConsoleEventsEnabled(bool flag)
|
||||
{
|
||||
gaming_console_events=flag;
|
||||
}
|
||||
void TF_InitConsole()
|
||||
{
|
||||
#if defined(GEKKO)
|
||||
rmode = VIDEO_GetPreferredMode(NULL);
|
||||
|
||||
// Allocate memory for the display in the uncached region
|
||||
@ -121,9 +192,34 @@ if (iResult != 0) {
|
||||
// we can use variables for this with format codes too
|
||||
// e.g. printf ("\x1b[%d;%dH", row, column );
|
||||
printf("\x1b[2;0H");
|
||||
#else
|
||||
signal(SIGPIPE,SIG_IGN);
|
||||
signal(SIGINT,_sigInt);
|
||||
#elif defined(__SWITCH__)
|
||||
consoleInit(NULL);
|
||||
initedConsole=true;
|
||||
#endif
|
||||
}
|
||||
void TF_InitWithConsole()
|
||||
{
|
||||
TF_Init();
|
||||
TF_InitConsole();
|
||||
#if defined(TESSESFRAMEWORK_LOGTOFILE)
|
||||
printf("Enabled Logging\n");
|
||||
#endif
|
||||
}
|
||||
#if defined(TESSESFRAMEWORK_LOGTOFILE)
|
||||
#if defined(TESSESFRAMEWORK_ENABLE_THREADING)
|
||||
Tesses::Framework::Threading::Mutex log_mtx;
|
||||
#endif
|
||||
void TF_Log(std::string txtToLog)
|
||||
{
|
||||
#if defined(TESSESFRAMEWORK_ENABLE_THREADING)
|
||||
log_mtx.Lock();
|
||||
#endif
|
||||
FILE* f = fopen("TF_Log.log","a");
|
||||
fprintf(f,"%s\n",txtToLog.c_str());
|
||||
fclose(f);
|
||||
#if defined(TESSESFRAMEWORK_ENABLE_THREADING)
|
||||
log_mtx.Unlock();
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -5,6 +5,10 @@
|
||||
#include <windows.h>
|
||||
#elif defined(GEKKO)
|
||||
#include <ogc/mutex.h>
|
||||
#elif defined(__SWITCH__)
|
||||
extern "C" {
|
||||
#include <switch/kernel/mutex.h>
|
||||
}
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
@ -19,6 +23,8 @@ namespace Tesses::Framework::Threading
|
||||
HANDLE mtx;
|
||||
#elif defined(GEKKO)
|
||||
mutex_t mtx;
|
||||
#elif defined(__SWITCH__)
|
||||
RMutex mtx;
|
||||
#else
|
||||
pthread_mutex_t mtx;
|
||||
pthread_mutexattr_t attr;
|
||||
@ -29,6 +35,8 @@ namespace Tesses::Framework::Threading
|
||||
CloseHandle(mtx);
|
||||
#elif defined(GEKKO)
|
||||
LWP_MutexDestroy(mtx);
|
||||
#elif defined(__SWITCH__)
|
||||
|
||||
#else
|
||||
pthread_mutex_destroy(&mtx);
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
@ -45,6 +53,8 @@ namespace Tesses::Framework::Threading
|
||||
#elif defined(GEKKO)
|
||||
md->mtx = LWP_MUTEX_NULL;
|
||||
LWP_MutexInit(&md->mtx, true);
|
||||
#elif defined(__SWITCH__)
|
||||
rmutexInit(&md->mtx);
|
||||
#else
|
||||
pthread_mutexattr_init(&md->attr);
|
||||
pthread_mutexattr_settype(&md->attr,PTHREAD_MUTEX_RECURSIVE);
|
||||
@ -61,6 +71,8 @@ namespace Tesses::Framework::Threading
|
||||
WaitForSingleObject(md->mtx, INFINITE);
|
||||
#elif defined(GEKKO)
|
||||
LWP_MutexLock(md->mtx);
|
||||
#elif defined(__SWITCH__)
|
||||
rmutexLock(&md->mtx);
|
||||
#else
|
||||
pthread_mutex_lock(&md->mtx);
|
||||
#endif
|
||||
@ -74,6 +86,8 @@ namespace Tesses::Framework::Threading
|
||||
ReleaseMutex(md->mtx);
|
||||
#elif defined(GEKKO)
|
||||
LWP_MutexUnlock(md->mtx);
|
||||
#elif defined(__SWITCH__)
|
||||
rmutexUnlock(&md->mtx);
|
||||
#else
|
||||
pthread_mutex_unlock(&md->mtx);
|
||||
#endif
|
||||
@ -87,6 +101,8 @@ namespace Tesses::Framework::Threading
|
||||
return WaitForSingleObject(md->mtx, 100) == WAIT_OBJECT_0;
|
||||
#elif defined(GEKKO)
|
||||
return LWP_MutexTryLock(md->mtx) == 0;
|
||||
#elif defined(__SWITCH__)
|
||||
return rmutexTryLock(&md->mtx);
|
||||
#else
|
||||
return pthread_mutex_trylock(&md->mtx) == 0;
|
||||
#endif
|
||||
|
||||
@ -1,10 +1,150 @@
|
||||
|
||||
#include "TessesFramework/Threading/Thread.hpp"
|
||||
#include <iostream>
|
||||
|
||||
#include <memory>
|
||||
#include "TessesFramework/Threading/Mutex.hpp"
|
||||
#include "TessesFramework/Common.hpp"
|
||||
#if defined(__SWITCH__)
|
||||
extern "C" {
|
||||
#include <switch.h>
|
||||
#include <switch/kernel/thread.h>
|
||||
}
|
||||
using NxThread = Thread;
|
||||
#endif
|
||||
namespace Tesses::Framework::Threading
|
||||
{
|
||||
|
||||
|
||||
#if defined(TESSESFRAMEWORK_ENABLE_THREADING)
|
||||
|
||||
#if defined(__SWITCH__) || defined(GEKKO)
|
||||
Mutex needed_to_be_joined_mtx;
|
||||
class NeedToBeJoinnedThread {
|
||||
|
||||
#if defined(GEKKO)
|
||||
static void* cb(void* data)
|
||||
#elif defined(__SWITCH__)
|
||||
static void cb(void* data)
|
||||
#endif
|
||||
{
|
||||
|
||||
auto ntbjt = static_cast<NeedToBeJoinnedThread*>(data);
|
||||
|
||||
ntbjt->hasInvoked=true;
|
||||
TF_LOG("About to call thread func");
|
||||
if(ntbjt->_cb)
|
||||
ntbjt->_cb();
|
||||
TF_LOG("Finished calling thread func");
|
||||
ntbjt->hasExited=true;
|
||||
|
||||
#if defined(GEKKO)
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
std::function<void()> _cb;
|
||||
std::atomic<bool> hasInvoked=false;
|
||||
#if defined(__SWITCH__)
|
||||
NxThread thrd;
|
||||
#elif defined(GEKKO)
|
||||
lwp_t thrd;
|
||||
#endif
|
||||
public:
|
||||
NeedToBeJoinnedThread(std::function<void()> cb)
|
||||
{
|
||||
this->_cb = cb;
|
||||
joinned=false;
|
||||
joinning=false;
|
||||
hasExited=false;
|
||||
#if defined(GEKKO)
|
||||
LWP_CreateThread(&thrd, cb, static_cast<void*>(this), nullptr,12000, 98);
|
||||
#elif defined(__SWITCH__)
|
||||
TF_LOG("Before Thread create");
|
||||
Result rc = threadCreate(&thrd,this->cb,
|
||||
static_cast<void*>(this), NULL, 0x100000,
|
||||
0x20 , 2);
|
||||
if (R_FAILED(rc))
|
||||
{
|
||||
this->hasExited=true;
|
||||
this->joinned=true;
|
||||
TF_LOG("Failed to create Thread");
|
||||
return;
|
||||
}
|
||||
|
||||
TF_LOG("After Thread create, before starting");
|
||||
rc = threadStart(&thrd);
|
||||
if (R_FAILED(rc))
|
||||
{
|
||||
TF_LOG("Failed to start thread");
|
||||
threadClose(&thrd);
|
||||
this->hasExited=true;
|
||||
this->joinned=true;
|
||||
return;
|
||||
}
|
||||
TF_LOG("Starting");
|
||||
#endif
|
||||
}
|
||||
std::atomic<bool> joinned;
|
||||
std::atomic<bool> joinning;
|
||||
std::atomic<bool> hasExited;
|
||||
void Join();
|
||||
void WaitTillInvoked()
|
||||
{
|
||||
while(!hasInvoked);
|
||||
TF_LOG("Invoked!");
|
||||
}
|
||||
};
|
||||
|
||||
void NeedToBeJoinnedThread::Join()
|
||||
{
|
||||
if(joinning)
|
||||
{
|
||||
return;
|
||||
}
|
||||
joinning=true;
|
||||
#if defined(__SWITCH__)
|
||||
threadWaitForExit(&this->thrd);
|
||||
threadClose(&this->thrd);
|
||||
#elif defined(GEKKO)
|
||||
void* res;
|
||||
LWP_JoinThread(this->thrd,&res);
|
||||
#endif
|
||||
joinned=true;
|
||||
//start the joinning process
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<NeedToBeJoinnedThread>> needToBeJoinnedThread;
|
||||
void JoinAllThreads()
|
||||
{
|
||||
needed_to_be_joined_mtx.Lock();
|
||||
for(auto item : needToBeJoinnedThread)
|
||||
{
|
||||
item->Join();
|
||||
}
|
||||
needToBeJoinnedThread.clear();
|
||||
needed_to_be_joined_mtx.Unlock();
|
||||
|
||||
}
|
||||
void LookForFinishedThreads()
|
||||
{
|
||||
|
||||
needed_to_be_joined_mtx.Lock();
|
||||
for(auto index = needToBeJoinnedThread.begin(); index < needToBeJoinnedThread.end(); index++)
|
||||
{
|
||||
auto& idx = *index;
|
||||
if(idx->hasExited)
|
||||
{
|
||||
if(idx->joinning) while(!idx->joinned);
|
||||
TF_LOG("ABOUT TO JOIN");
|
||||
idx->Join();
|
||||
TF_LOG("JOINNED");
|
||||
needToBeJoinnedThread.erase(index);
|
||||
index--;
|
||||
}
|
||||
}
|
||||
needed_to_be_joined_mtx.Unlock();
|
||||
}
|
||||
|
||||
#endif
|
||||
class ThreadHiddenFieldData : public HiddenFieldData {
|
||||
public:
|
||||
#if defined(_WIN32)
|
||||
@ -16,7 +156,8 @@ namespace Tesses::Framework::Threading
|
||||
#elif defined(GEKKO)
|
||||
lwp_t thrd;
|
||||
|
||||
|
||||
#elif defined(__SWITCH__) || defined(GEKKO)
|
||||
std::shared_ptr<NeedToBeJoinnedThread> thread;
|
||||
#else
|
||||
pthread_t thrd;
|
||||
#endif
|
||||
@ -30,6 +171,8 @@ namespace Tesses::Framework::Threading
|
||||
|
||||
#if defined(_WIN32)
|
||||
static DWORD __stdcall cb(LPVOID data)
|
||||
#elif defined(__SWITCH__)
|
||||
static void cb(void* data)
|
||||
#else
|
||||
static void* cb(void* data)
|
||||
#endif
|
||||
@ -39,8 +182,10 @@ namespace Tesses::Framework::Threading
|
||||
auto fn = thrd->fn;
|
||||
thrd->hasInvoked=true;
|
||||
fn();
|
||||
#if !defined(_WIN32)
|
||||
#if !defined(_WIN32) && !defined(__SWITCH__)
|
||||
return NULL;
|
||||
#elif(__SWITCH__)
|
||||
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
@ -55,26 +200,37 @@ namespace Tesses::Framework::Threading
|
||||
data->fn = fn;
|
||||
#if defined(_WIN32)
|
||||
data->thrd = CreateThread(NULL,0,cb,static_cast<LPVOID>(data), 0, &data->thrdId);
|
||||
#elif defined(GEKKO)
|
||||
auto res = LWP_CreateThread(&data->thrd, cb, static_cast<void*>(data), nullptr,12000, 98);
|
||||
while(!data->hasInvoked);
|
||||
#elif defined(__SWITCH__) || defined(GEKKO)
|
||||
data->thread = std::make_shared<NeedToBeJoinnedThread>(fn);
|
||||
data->thread->WaitTillInvoked();
|
||||
//threadCreate(,cb,static_cast<void*>(data),NULL,8000000,0x00,-2);
|
||||
#else
|
||||
pthread_create(&data->thrd,NULL,cb,static_cast<void*>(data));
|
||||
while(!data->hasInvoked);
|
||||
//thrd_create(&thrd, cb, static_cast<void*>(this));
|
||||
#endif
|
||||
while(!data->hasInvoked);
|
||||
|
||||
#endif
|
||||
}
|
||||
void Thread::Detach()
|
||||
{
|
||||
#if defined(TESSESFRAMEWORK_ENABLE_THREADING)
|
||||
auto data = this->data.GetField<ThreadHiddenFieldData*>();
|
||||
#if !defined(GEKKO)
|
||||
|
||||
#if defined(_WIN32)
|
||||
CloseHandle(data->thrd);
|
||||
#elif defined(__SWITCH__) || defined(GEKKO)
|
||||
TF_LOG("Detaching");
|
||||
needed_to_be_joined_mtx.Lock();
|
||||
needToBeJoinnedThread.push_back(data->thread);
|
||||
needed_to_be_joined_mtx.Unlock();
|
||||
|
||||
TF_LOG("Detached!");
|
||||
#else
|
||||
pthread_detach(data->thrd);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -84,9 +240,8 @@ namespace Tesses::Framework::Threading
|
||||
auto data = this->data.GetField<ThreadHiddenFieldData*>();
|
||||
#if defined(_WIN32)
|
||||
WaitForSingleObject(data->thrd, INFINITE);
|
||||
#elif defined(GEKKO)
|
||||
void* res;
|
||||
LWP_JoinThread(data->thrd,&res);
|
||||
#elif defined(__SWITCH__) || defined(GEKKO)
|
||||
data->thread->Join();
|
||||
#else
|
||||
pthread_join(data->thrd,NULL);
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user