Make threading and networking optional

This commit is contained in:
2025-02-27 04:17:12 -06:00
parent 29c53b171d
commit 02767f8710
39 changed files with 2054 additions and 99 deletions

BIN
.Config.cmake.in.kate-swp Normal file

Binary file not shown.

View File

@ -18,6 +18,8 @@ src/Streams/MemoryStream.cpp
src/Streams/NetworkStream.cpp
src/Streams/Stream.cpp
src/Streams/BufferedStream.cpp
src/Streams/ByteReader.cpp
src/Streams/ByteWriter.cpp
src/TextStreams/StreamReader.cpp
src/TextStreams/StreamWriter.cpp
src/TextStreams/TextReader.cpp
@ -32,13 +34,24 @@ src/Filesystem/NullFilesystem.cpp
src/Filesystem/MountableFilesystem.cpp
src/Crypto/ClientTLSStream.cpp
src/Crypto/MbedHelpers.cpp
src/Graphics/ImageFormats/Bitmap.cpp
src/Graphics/ImageFormats/ImageFormat.cpp
src/Graphics/Renderers/ImageRenderer.cpp
src/Graphics/Renderers/Renderer.cpp
src/Graphics/Color.cpp
src/Graphics/Image.cpp
src/TF_Init.cpp
src/wrapper.cpp
src/HiddenField.cpp
)
set(TESSESFRAMEWORK_CERT_BUNDLE_FILE "/etc/ssl/certs/ca-certificates.crt" CACHE FILEPATH "Path to ca-chain")
option(TESSESFRAMEWORK_EMBED_CERT_BUNDLE "Embed the certificate chain bundle" ON)
option(TESSESFRAMEWORK_ENABLE_MBED "Enable Tesses Framework mbedtls" ON)
option(TESSESFRAMEWORK_ENABLE_LIBWEBCAM "Enable LibWebCam" ON)
option(TESSESFRAMEWORK_ENABLE_NETWORKING "Enable Networking" ON)
option(TESSESFRAMEWORK_ENABLE_THREADING "Enable Threading" ON)
option(TESSESFRAMEWORK_ENABLE_EXAMPLES "Enable Tesses Framework examples" ON)
option(TESSESFRAMEWORK_ENABLE_APPS "Enable Tesses Framework cli apps" ON)
option(TESSESFRAMEWORK_INSTALL_DEVELOPMENT "Enable Installing Tesses Framework Development Packages" ON)
@ -62,6 +75,17 @@ endif()
set(MBEDTLS_DIR "" CACHE PATH "Mbed tls directory")
function(link_deps TessesFramework_TARGET)
if(TESSESFRAMEWORK_ENABLE_THREADING)
target_compile_definitions(${TessesFramework_TARGET} PUBLIC TESSESFRAMEWORK_ENABLE_THREADING)
endif()
if(TESSESFRAMEWORK_ENABLE_NETWORKING)
target_compile_definitions(${TessesFramework_TARGET} PUBLIC TESSESFRAMEWORK_ENABLE_NETWORKING)
endif()
if(TESSESFRAMEWORK_ENABLE_LIBWEBCAM)
target_compile_definitions(${TessesFramework_TARGET} PUBLIC TESSESFRAMEWORK_ENABLE_LIBWEBCAM)
find_package(libwebcam REQUIRED)
target_link_libraries(${TessesFramework_TARGET} PUBLIC libwebcam)
endif()
if(TESSESFRAMEWORK_ENABLE_MBED)
target_compile_definitions(${TessesFramework_TARGET} PUBLIC TESSESFRAMEWORK_ENABLE_MBED)
if(TESSESFRAMEWORK_EMBED_CERT_BUNDLE)
@ -165,7 +189,14 @@ if(TESSESFRAMEWORK_ENABLE_EXAMPLES)
add_executable(mountabletest examples/mountabletest.cpp)
target_link_libraries(mountabletest PUBLIC tessesframework)
add_executable(bmp examples/bmp.cpp)
target_link_libraries(bmp PUBLIC tessesframework)
add_executable(bmp2 examples/bmp2.cpp)
target_link_libraries(bmp2 PUBLIC tessesframework)
add_executable(bmp3 examples/bmp3.cpp)
target_link_libraries(bmp3 PUBLIC tessesframework)
add_executable(bmp4 examples/bmp4.cpp)
target_link_libraries(bmp4 PUBLIC tessesframework)
endif()
if(TESSESFRAMEWORK_ENABLE_APPS)
@ -185,4 +216,4 @@ set(CPACK_PACKAGE_VERSION_MAJOR "${TessesFramework_VERSION_MAJOR}")
set(CPACK_PACKAGE_VERSION_MINOR "${TessesFramework_VERSION_MINOR}")
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libmbedtls-dev (>= 2.28.8)")
include(CPack)
include(CPack)

View File

@ -8,4 +8,13 @@ if(NOT ("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows" OR "${CMAKE_SYSTEM_NAME}" STRE
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
endif()
endif()
set(TESSESFRAMEWORK_ENABLE_LIBWEBCAM @TESSESFRAMEWORK_ENABLE_LIBWEBCAM@)
if(${TESSESFRAMEWORK_ENABLE_LIBWEBCAM})
find_package(libwebcam)
endif()
set(TESSESFRAMEWORK_ENABLE_NETWORKING @TESSESFRAMEWORK_ENABLE_NETWORKING@)
set(TESSESFRAMEWORK_ENABLE_THREADING @TESSESFRAMEWORK_ENABLE_THREADING@)

View File

@ -4,5 +4,15 @@
#if TESSES_FRAMEWORK_FLAG_@TESSESFRAMEWORK_ENABLE_MBED@
#define TESSESFRAMEWORK_ENABLE_MBED
#endif
#if TESSES_FRAMEWORK_FLAG_@TESSESFRAMEWORK_ENABLE_LIBWEBCAM@
#define TESSESFRAMEWORK_ENABLE_MINIFB
#endif
#if TESSES_FRAMEWORK_FLAG_@TESSESFRAMEWORK_ENABLE_NETWORKING@
#define TESSESFRAMEWORK_ENABLE_NETWORKING
#endif
#if TESSES_FRAMEWORK_FLAG_@TESSESFRAMEWORK_ENABLE_THREADING@
#define TESSESFRAMEWORK_ENABLE_THREADING
#endif
#undef TESSES_FRAMEWORK_FLAG_OFF
#undef TESSES_FRAMEWORK_FLAG_ON
#undef TESSES_FRAMEWORK_FLAG_ON

47
examples/bmp.cpp Normal file
View File

@ -0,0 +1,47 @@
#include "TessesFramework/TessesFramework.hpp"
#include <cstdlib>
using namespace Tesses::Framework;
using namespace Tesses::Framework::Graphics;
using namespace Tesses::Framework::Graphics::ImageFormats;
using namespace Tesses::Framework::Streams;
void doIt(const char* n)
{
std::string p = n;
srand(std::stoi(p));
p.append(".bmp");
FileStream* strm = new FileStream(p,"wb");
Image image(320,240);
std::vector<Color> colors = {
Colors::Crimson,
Colors::Chartreuse,
Colors::FireBrick,
Colors::Turquoise,
Colors::DarkOrange,
Colors::Orange
};
for(uint32_t y = 0; y < image.Height(); y++)
{
for(uint32_t x = 0; x < image.Width(); x++)
{
image.SetPixel(x,y,colors[rand() % (int)colors.size()]);
}
}
ImageFormats::Bitmap bmp;
bmp.Save(strm,&image);
delete strm;
}
int main(int argc, char** argv)
{
for(int i = 1; i < argc; i++)
{
doIt(argv[i]);
}
}

72
examples/bmp2.cpp Normal file
View File

@ -0,0 +1,72 @@
#include "TessesFramework/TessesFramework.hpp"
#include <cstdlib>
using namespace Tesses::Framework;
using namespace Tesses::Framework::Graphics;
using namespace Tesses::Framework::Graphics::ImageFormats;
using namespace Tesses::Framework::Streams;
#define WIDTH 19
#define HEIGHT 12
#define A 0x0A
#define B 0x0B
#define C 0x0C
char house[] = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, //1
0,0,0,0,0,0,0,0,9,9,0,0,0,7,0,0,B,B,0, //2
0,0,0,8,8,0,0,0,9,9,0,0,7,6,7,0,A,0,B, //3
0,0,0,8,8,0,0,0,0,0,0,7,C,C,C,7,A,0,0, //4
0,8,8,8,8,8,8,0,0,0,7,C,C,C,C,C,7,0,0, //5
0,8,8,8,8,8,8,0,0,7,7,7,7,7,7,7,7,7,0, //6
0,0,0,8,8,0,0,0,0,1,5,5,5,5,5,5,5,1,0, //7
0,0,0,8,8,0,0,0,0,1,6,5,3,3,3,5,6,1,0, //8
4,4,4,8,8,4,4,4,4,1,6,5,3,2,3,5,6,1,4, //9
4,4,4,8,8,4,4,4,4,1,5,5,3,2,3,5,5,1,4, //10
4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,1,1,4, //11
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 //12
};
int main(int argc, char** argv)
{
Color pallete[] = {
Colors::SkyBlue,
Colors::Grey,
Colors::Crimson,
Colors::Lime,
Colors::LawnGreen,
Colors::DarkOliveGreen,
Colors::DimGrey,
Colors::BurlyWood,
Colors::White,
Colors::Yellow,
Colors::FireBrick,
Colors::WhiteSmoke,
Colors::DarkGoldenRod
};
Image img(WIDTH*32,HEIGHT*32);
for(uint32_t y = 0; y < HEIGHT; y++)
{
for(uint32_t x = 0; x < WIDTH; x++)
{
char c = house[y * WIDTH + x];
for(uint32_t y0 = 0; y0 < 32; y0++)
{
uint32_t y1 = y * 32 + y0;
for(uint32_t x0 = 0; x0 < 32;x0++)
{
uint32_t x1 = x * 32 + x0;
img.SetPixel(x1,y1, pallete[c]);
}
}
}
}
FileStream* strm = new FileStream("house.bmp","wb");
ImageFormats::Bitmap bmp;
bmp.Save(strm,&img);
delete strm;
}

23
examples/bmp3.cpp Normal file
View File

@ -0,0 +1,23 @@
#include "TessesFramework/TessesFramework.hpp"
#include <iostream>
using namespace Tesses::Framework;
using namespace Tesses::Framework::Graphics;
using namespace Tesses::Framework::Graphics::ImageFormats;
using namespace Tesses::Framework::Streams;
int main(int argc,char** argv)
{
if(argc < 3) {
std::cout << "INBMP OUTBMP" << std::endl;
return 1;
}
FileStream* src = new FileStream(argv[1],"rb");
Image img;
Bitmap bmp;
bmp.Load(src,&img);
delete src;
FileStream* dest = new FileStream(argv[2],"wb");
bmp.Save(dest,&img);
delete dest;
}

31
examples/bmp4.cpp Normal file
View File

@ -0,0 +1,31 @@
#include "TessesFramework/TessesFramework.hpp"
#include <iostream>
using namespace Tesses::Framework;
using namespace Tesses::Framework::Graphics;
using namespace Tesses::Framework::Graphics::ImageFormats;
using namespace Tesses::Framework::Streams;
int main(int argc,char** argv)
{
if(argc < 3) {
std::cout << "INBMP OUTBMP" << std::endl;
return 1;
}
FileStream* src = new FileStream(argv[1],"rb");
Image img;
Bitmap bmp;
bmp.Load(src,&img);
delete src;
Image img2(img.Width()+64,img.Height()+64);
Renderers::ImageRenderer irdr(&img2);
irdr.DrawRectangle(Rectangle(0,0,(int32_t)img2.Width(),(int32_t)img2.Height()),Colors::Crimson,false);
irdr.DrawRectangle(Rectangle(1,1,(int32_t)img2.Width()-2,(int32_t)img2.Height()-2),Colors::Chartreuse,true);
irdr.DrawImage(Point(32,32),&img);
FileStream* dest = new FileStream(argv[2],"wb");
bmp.Save(dest,&img2);
delete dest;
}

View File

@ -0,0 +1,176 @@
#pragma once
#include "../Common.hpp"
namespace Tesses::Framework::Graphics {
struct Color {
uint8_t Red=0;
uint8_t Green=0;
uint8_t Blue=0;
uint8_t Alpha=255;
Color();
Color(uint8_t r, uint8_t g, uint8_t b);
Color(uint8_t r, uint8_t g, uint8_t b, uint8_t a);
Color(Color c, uint8_t a);
Color(uint8_t* color_data);
std::string ToString(bool alphaIf255=false);
void ToArray(uint8_t* color_data);
static bool TryParse(std::string color, Color& col);
static Color Parse(std::string color);
bool operator!=(Color other);
bool operator==(Color other);
};
namespace Colors {
extern const Color AliceBlue;
extern const Color AntiqueWhite;
extern const Color Aqua;
extern const Color Aquamarine;
extern const Color Azure;
extern const Color Beige;
extern const Color Bisque;
extern const Color Black;
extern const Color BlanchedAlmond;
extern const Color Blue;
extern const Color BlueViolet;
extern const Color Brown;
extern const Color BurlyWood;
extern const Color CadetBlue;
extern const Color Chartreuse;
extern const Color Chocolate;
extern const Color Coral;
extern const Color CornflowerBlue;
extern const Color Cornsilk;
extern const Color Crimson;
extern const Color Cyan;
extern const Color DarkBlue;
extern const Color DarkCyan;
extern const Color DarkGoldenRod;
extern const Color DarkGray;
extern const Color DarkGrey;
extern const Color DarkGreen;
extern const Color DarkKhaki;
extern const Color DarkMagenta;
extern const Color DarkOliveGreen;
extern const Color DarkOrange;
extern const Color DarkOrchid;
extern const Color DarkRed;
extern const Color DarkSalmon;
extern const Color DarkSeaGreen;
extern const Color DarkSlateBlue;
extern const Color DarkSlateGray;
extern const Color DarkSlateGrey;
extern const Color DarkTurquoise;
extern const Color DarkViolet;
extern const Color DeepPink;
extern const Color DeepSkyBlue;
extern const Color DimGray;
extern const Color DimGrey;
extern const Color DodgerBlue;
extern const Color FireBrick;
extern const Color FloralWhite;
extern const Color ForestGreen;
extern const Color Fuchsia;
extern const Color Gainsboro;
extern const Color GhostWhite;
extern const Color Gold;
extern const Color GoldenRod;
extern const Color Gray;
extern const Color Grey;
extern const Color Green;
extern const Color GreenYellow;
extern const Color HoneyDew;
extern const Color HotPink;
extern const Color IndianRed;
extern const Color Indigo;
extern const Color Ivory;
extern const Color Khaki;
extern const Color Lavender;
extern const Color LavenderBlush;
extern const Color LawnGreen;
extern const Color LemonChiffon;
extern const Color LightBlue;
extern const Color LightCoral;
extern const Color LightCyan;
extern const Color LightGoldenRodYellow;
extern const Color LightGray;
extern const Color LightGrey;
extern const Color LightGreen;
extern const Color LightPink;
extern const Color LightSalmon;
extern const Color LightSeaGreen;
extern const Color LightSkyBlue;
extern const Color LightSlateGray;
extern const Color LightSlateGrey;
extern const Color LightSteelBlue;
extern const Color LightYellow;
extern const Color Lime;
extern const Color LimeGreen;
extern const Color Linen;
extern const Color Magenta;
extern const Color Maroon;
extern const Color MediumAquaMarine;
extern const Color MediumBlue;
extern const Color MediumOrchid;
extern const Color MediumPurple;
extern const Color MediumSeaGreen;
extern const Color MediumSlateBlue;
extern const Color MediumSpringGreen;
extern const Color MediumTurquoise;
extern const Color MediumVioletRed;
extern const Color MidnightBlue;
extern const Color MintCream;
extern const Color MistyRose;
extern const Color Moccasin;
extern const Color NavajoWhite;
extern const Color Navy;
extern const Color OldLace;
extern const Color Olive;
extern const Color OliveDrab;
extern const Color Orange;
extern const Color OrangeRed;
extern const Color Orchid;
extern const Color PaleGoldenRod;
extern const Color PaleGreen;
extern const Color PaleTurquoise;
extern const Color PaleVioletRed;
extern const Color PapayaWhip;
extern const Color PeachPuff;
extern const Color Peru;
extern const Color Pink;
extern const Color Plum;
extern const Color PowderBlue;
extern const Color Purple;
extern const Color RebeccaPurple;
extern const Color Red;
extern const Color RosyBrown;
extern const Color SaddleBrown;
extern const Color Salmon;
extern const Color SandyBrown;
extern const Color SeaGreen;
extern const Color SeaShell;
extern const Color Sienna;
extern const Color Silver;
extern const Color SkyBlue;
extern const Color SlateBlue;
extern const Color SlateGray;
extern const Color SlateGrey;
extern const Color Snow;
extern const Color SpringGreen;
extern const Color SteelBlue;
extern const Color Tan;
extern const Color Teal;
extern const Color Thistle;
extern const Color Tomato;
extern const Color Turquoise;
extern const Color Violet;
extern const Color Wheat;
extern const Color White;
extern const Color WhiteSmoke;
extern const Color Yellow;
extern const Color YellowGreen;
};
};

View File

@ -0,0 +1,24 @@
#pragma once
#include "Color.hpp"
#include <vector>
namespace Tesses::Framework::Graphics {
class Image {
uint32_t w=0;
uint32_t h=0;
std::vector<Color> data={};
public:
Image();
Image(uint32_t w, uint32_t h);
Image(uint32_t w,uint32_t h,std::vector<Color> data);
uint32_t Width();
uint32_t Height();
void SetSize(uint32_t w, uint32_t h);
void SetSize(uint32_t w, uint32_t h, Color c);
void SetPixel(uint32_t x, uint32_t y, Color c);
Color GetPixel(uint32_t x, uint32_t y);
std::vector<Color>& Data();
};
}

View File

@ -0,0 +1,10 @@
#pragma once
#include "ImageFormat.hpp"
namespace Tesses::Framework::Graphics::ImageFormats {
class Bitmap : public ImageFormat {
public:
Bitmap();
void Load(Tesses::Framework::Streams::Stream* strm, Image* image);
void Save(Tesses::Framework::Streams::Stream* strm, Image* image,std::string flags="");
};
};

View File

@ -0,0 +1,13 @@
#pragma once
#include "../../Streams/Stream.hpp"
#include "../Image.hpp"
namespace Tesses::Framework::Graphics::ImageFormats {
class ImageFormat {
public:
virtual void Load(Tesses::Framework::Streams::Stream* strm, Image* image)=0;
virtual void Save(Tesses::Framework::Streams::Stream* strm, Image* image,std::string flags="")=0;
virtual ~ImageFormat();
};
}

View File

@ -0,0 +1,23 @@
#pragma once
#include <cstdint>
#include <string>
namespace Tesses::Framework::Graphics {
class Point {
public:
Point()
{
}
Point(int32_t x, int32_t y)
{
this->X = x;
this->Y = y;
}
int32_t X=0;
int32_t Y=0;
std::string ToString()
{
return std::to_string(X) + ", " + std::to_string(Y);
}
};
};

View File

@ -0,0 +1,42 @@
#pragma once
#include "Point.hpp"
#include "Size.hpp"
namespace Tesses::Framework::Graphics {
class Rectangle {
public:
Rectangle()
{
}
Rectangle(Point pt, int32_t square) : Rectangle(pt, Graphics::Size(square))
{
}
Rectangle(int32_t x, int32_t y, int32_t square) : Rectangle(Point(x,y),square)
{
}
Rectangle(int32_t x, int32_t y, int32_t width, int32_t height) : Rectangle(Point(x,y),Graphics::Size(width,height))
{
}
Rectangle(Point pt, Size sz)
{
this->Location = pt;
this->Size = sz;
}
Graphics::Point Location;
Graphics::Size Size;
std::string ToString()
{
return std::to_string(Location.X) + ", " + std::to_string(Location.Y) + ", " + std::to_string(Size.Width) + ", " + std::to_string(Size.Height);
}
bool Intersects(Point pt)
{
}
};
};

View File

@ -0,0 +1,17 @@
#pragma once
#include "Renderer.hpp"
namespace Tesses::Framework::Graphics::Renderers {
class ImageRenderer : public Renderer {
Image* image;
public:
ImageRenderer(Image* image);
uint32_t Width();
uint32_t Height();
void SetPixel(Point pt,Color c);
};
};

View File

@ -0,0 +1,17 @@
#pragma once
#include "../Image.hpp"
#include "../Rectangle.hpp"
namespace Tesses::Framework::Graphics::Renderers {
class Renderer {
public:
virtual uint32_t Width()=0;
virtual uint32_t Height()=0;
virtual void SetPixel(Point pt,Color c) = 0;
virtual void DrawRectangle(Rectangle rect,Color c,bool fill);
virtual void DrawImage(Point pt, Image* image);
virtual ~Renderer();
};
};

View File

@ -0,0 +1,32 @@
#pragma once
#include <cstdint>
#include <string>
namespace Tesses::Framework::Graphics {
class Size {
public:
Size()
{
}
Size(int32_t square)
{
this->Width = square;
this->Height = square;
}
Size(int32_t width, int32_t height)
{
this->Width = width;
this->Height = height;
}
int32_t Width=0;
int32_t Height=0;
bool IsSquare()
{
return Width == Height;
}
std::string ToString()
{
return std::to_string(Width) + "x" + std::to_string(Height);
}
};
};

View File

@ -0,0 +1,32 @@
#pragma once
#include <functional>
namespace Tesses::Framework {
class HiddenFieldData {
public:
virtual ~HiddenFieldData();
};
class HiddenField {
private:
HiddenFieldData* ptr;
public:
HiddenField();
HiddenField(HiddenFieldData* data);
void SetField(HiddenFieldData* data);
template<typename T>
T GetField()
{
return dynamic_cast<T>(ptr);
}
template<typename T>
T AllocField()
{
auto v = new T();
SetField(v);
return v;
}
~HiddenField();
};
}

View File

@ -68,14 +68,9 @@ namespace Tesses::Framework::Http
NotExtended=510,
NetworkAuthenticationRequired=511
} StatusCode;
struct CaseInsensitiveLess {
bool operator() (const std::string& s1, const std::string& s2) const {
std::string str1(s1.length(),' ');
std::string str2(s2.length(),' ');
std::transform(s1.begin(), s1.end(), str1.begin(), tolower);
std::transform(s2.begin(), s2.end(), str2.begin(), tolower);
return str1 < str2;
}
bool operator() (const std::string& s1, const std::string& s2) const;
};
class HttpDictionary {
public:
@ -146,6 +141,8 @@ struct CaseInsensitiveLess {
static std::string HtmlEncode(std::string v);
static std::vector<std::string> SplitString(std::string text, std::string delimiter,std::size_t maxCnt = std::string::npos);
static std::string StatusCodeString(StatusCode code);
static std::string ToLower(std::string str);
static std::string ToUpper(std::string str);
};

View File

@ -0,0 +1,33 @@
#pragma once
#include "Stream.hpp"
namespace Tesses::Framework::Streams
{
class ByteReader {
Stream* strm;
bool owns;
public:
Stream* GetStream();
ByteReader(Stream* strm, bool owns);
ByteReader(Stream& strm);
uint8_t ReadU8();
uint16_t ReadU16BE();
uint16_t ReadU16LE();
uint32_t ReadU32BE();
uint32_t ReadU32LE();
uint64_t ReadU64BE();
uint64_t ReadU64LE();
int8_t ReadI8();
int16_t ReadI16BE();
int16_t ReadI16LE();
int32_t ReadI32BE();
int32_t ReadI32LE();
int64_t ReadI64BE();
int64_t ReadI64LE();
float ReadF32BE();
float ReadF32LE();
double ReadF64BE();
double ReadF64LE();
~ByteReader();
};
}

View File

@ -0,0 +1,33 @@
#pragma once
#include "Stream.hpp"
namespace Tesses::Framework::Streams
{
class ByteWriter {
Stream* strm;
bool owns;
public:
Stream* GetStream();
ByteWriter(Stream* strm, bool owns);
ByteWriter(Stream& strm);
void WriteU8(uint8_t v);
void WriteU16BE(uint16_t v);
void WriteU16LE(uint16_t v);
void WriteU32BE(uint32_t v);
void WriteU32LE(uint32_t v);
void WriteU64BE(uint64_t v);
void WriteU64LE(uint64_t v);
void WriteI8(int8_t v);
void WriteI16BE(int16_t v);
void WriteI16LE(int16_t v);
void WriteI32BE(int32_t v);
void WriteI32LE(int32_t v);
void WriteI64BE(int64_t v);
void WriteI64LE(int64_t v);
void WriteF32BE(float v);
void WriteF32LE(float v);
void WriteF64BE(double v);
void WriteF64LE(double v);
~ByteWriter();
};
}

View File

@ -9,6 +9,8 @@
#include "Streams/MemoryStream.hpp"
#include "Streams/NetworkStream.hpp"
#include "Streams/BufferedStream.hpp"
#include "Streams/ByteReader.hpp"
#include "Streams/ByteWriter.hpp"
#include "TextStreams/StreamReader.hpp"
#include "TextStreams/StreamWriter.hpp"
#include "Threading/Thread.hpp"
@ -21,4 +23,11 @@
#include "Filesystem/MemoryFilesystem.hpp"
#include "Crypto/ClientTLSStream.hpp"
#include "Crypto/MbedHelpers.hpp"
#include "Lazy.hpp"
#include "Lazy.hpp"
#include "Graphics/ImageFormats/ImageFormat.hpp"
#include "Graphics/ImageFormats/Bitmap.hpp"
#include "Graphics/Renderers/ImageRenderer.hpp"
#include "Graphics/Renderers/Renderer.hpp"
#include "Graphics/Image.hpp"
#include "Graphics/Color.hpp"
#include "HiddenField.hpp"

View File

@ -1,22 +1,10 @@
#pragma once
#if defined(_WIN32)
#include <windows.h>
#elif defined(GEKKO)
#include <ogc/mutex.h>
#else
#include <pthread.h>
#endif
#include "../HiddenField.hpp"
namespace Tesses::Framework::Threading
{
class Mutex {
#if defined(_WIN32)
HANDLE mtx;
#elif defined(GEKKO)
mutex_t mtx;
#else
pthread_mutex_t mtx;
pthread_mutexattr_t attr;
#endif
HiddenField data;
public:
Mutex();
void Lock();

View File

@ -8,26 +8,13 @@
#include <pthread.h>
#endif
#include <atomic>
#include "../HiddenField.hpp"
namespace Tesses::Framework::Threading
{
class Thread
{
#if defined(_WIN32)
HANDLE thrd;
DWORD thrdId;
public:
#elif defined(GEKKO)
lwp_t thrd;
static void* cb(void* ptr);
#else
pthread_t thrd;
static void* cb(void* ptr);
#endif
std::function<void()> fn;
std::atomic<bool> hasInvoked;
HiddenField data;
public:
Thread(std::function<void()> fn);
void Join();

432
src/Graphics/Color.cpp Normal file
View File

@ -0,0 +1,432 @@
#include "TessesFramework/Graphics/Color.hpp"
#include "TessesFramework/Http/HttpUtils.hpp"
using HttpUtils = Tesses::Framework::Http::HttpUtils;
namespace Tesses::Framework::Graphics {
namespace Colors {
const Color AliceBlue(240,248,255);
const Color AntiqueWhite(250,235,215);
const Color Aqua(0,255,255);
const Color Aquamarine(127,255,212);
const Color Azure(240,255,255);
const Color Beige(245,245,220);
const Color Bisque(255,228,196);
const Color Black(0,0,0);
const Color BlanchedAlmond(255,235,205);
const Color Blue(0,0,255);
const Color BlueViolet(138,43,226);
const Color Brown(165,42,42);
const Color BurlyWood(222,184,135);
const Color CadetBlue(95,158,160);
const Color Chartreuse(127,255,0);
const Color Chocolate(210,105,30);
const Color Coral(255,127,80);
const Color CornflowerBlue(100,149,237);
const Color Cornsilk(255,248,220);
const Color Crimson(220,20,60);
const Color Cyan(0,255,255);
const Color DarkBlue(0,0,139);
const Color DarkCyan(0,139,139);
const Color DarkGoldenRod(184,134,11);
const Color DarkGray(169,169,169);
const Color DarkGrey(169,169,169);
const Color DarkGreen(0,100,0);
const Color DarkKhaki(189,183,107);
const Color DarkMagenta(139,0,139);
const Color DarkOliveGreen(85,107,47);
const Color DarkOrange(255,140,0);
const Color DarkOrchid(153,50,204);
const Color DarkRed(139,0,0);
const Color DarkSalmon(233,150,122);
const Color DarkSeaGreen(143,188,143);
const Color DarkSlateBlue(72,61,139);
const Color DarkSlateGray(47,79,79);
const Color DarkSlateGrey(47,79,79);
const Color DarkTurquoise(0,206,209);
const Color DarkViolet(148,0,211);
const Color DeepPink(255,20,147);
const Color DeepSkyBlue(0,191,255);
const Color DimGray(105,105,105);
const Color DimGrey(105,105,105);
const Color DodgerBlue(30,144,255);
const Color FireBrick(178,34,34);
const Color FloralWhite(255,250,240);
const Color ForestGreen(34,139,34);
const Color Fuchsia(255,0,255);
const Color Gainsboro(220,220,220);
const Color GhostWhite(248,248,255);
const Color Gold(255,215,0);
const Color GoldenRod(218,165,32);
const Color Gray(128,128,128);
const Color Grey(128,128,128);
const Color Green(0,128,0);
const Color GreenYellow(173,255,47);
const Color HoneyDew(240,255,240);
const Color HotPink(255,105,180);
const Color IndianRed(205,92,92);
const Color Indigo(75,0,130);
const Color Ivory(255,255,240);
const Color Khaki(240,230,140);
const Color Lavender(230,230,250);
const Color LavenderBlush(255,240,245);
const Color LawnGreen(124,252,0);
const Color LemonChiffon(255,250,205);
const Color LightBlue(173,216,230);
const Color LightCoral(240,128,128);
const Color LightCyan(224,255,255);
const Color LightGoldenRodYellow(250,250,210);
const Color LightGray(211,211,211);
const Color LightGrey(211,211,211);
const Color LightGreen(144,238,144);
const Color LightPink(255,182,193);
const Color LightSalmon(255,160,122);
const Color LightSeaGreen(32,178,170);
const Color LightSkyBlue(135,206,250);
const Color LightSlateGray(119,136,153);
const Color LightSlateGrey(119,136,153);
const Color LightSteelBlue(176,196,222);
const Color LightYellow(255,255,224);
const Color Lime(0,255,0);
const Color LimeGreen(50,205,50);
const Color Linen(250,240,230);
const Color Magenta(255,0,255);
const Color Maroon(128,0,0);
const Color MediumAquaMarine(102,205,170);
const Color MediumBlue(0,0,205);
const Color MediumOrchid(186,85,211);
const Color MediumPurple(147,112,219);
const Color MediumSeaGreen(60,179,113);
const Color MediumSlateBlue(123,104,238);
const Color MediumSpringGreen(0,250,154);
const Color MediumTurquoise(72,209,204);
const Color MediumVioletRed(199,21,133);
const Color MidnightBlue(25,25,112);
const Color MintCream(245,255,250);
const Color MistyRose(255,228,225);
const Color Moccasin(255,228,181);
const Color NavajoWhite(255,222,173);
const Color Navy(0,0,128);
const Color OldLace(253,245,230);
const Color Olive(128,128,0);
const Color OliveDrab(107,142,35);
const Color Orange(255,165,0);
const Color OrangeRed(255,69,0);
const Color Orchid(218,112,214);
const Color PaleGoldenRod(238,232,170);
const Color PaleGreen(152,251,152);
const Color PaleTurquoise(175,238,238);
const Color PaleVioletRed(219,112,147);
const Color PapayaWhip(255,239,213);
const Color PeachPuff(255,218,185);
const Color Peru(205,133,63);
const Color Pink(255,192,203);
const Color Plum(221,160,221);
const Color PowderBlue(176,224,230);
const Color Purple(128,0,128);
const Color RebeccaPurple(102,51,153);
const Color Red(255,0,0);
const Color RosyBrown(188,143,143);
const Color SaddleBrown(139,69,19);
const Color Salmon(250,128,114);
const Color SandyBrown(244,164,96);
const Color SeaGreen(46,139,87);
const Color SeaShell(255,245,238);
const Color Sienna(160,82,45);
const Color Silver(192,192,192);
const Color SkyBlue(135,206,235);
const Color SlateBlue(106,90,205);
const Color SlateGray(112,128,144);
const Color SlateGrey(112,128,144);
const Color Snow(255,250,250);
const Color SpringGreen(0,255,127);
const Color SteelBlue(70,130,180);
const Color Tan(210,180,140);
const Color Teal(0,128,128);
const Color Thistle(216,191,216);
const Color Tomato(255,99,71);
const Color Turquoise(64,224,208);
const Color Violet(238,130,238);
const Color Wheat(245,222,179);
const Color White(255,255,255);
const Color WhiteSmoke(245,245,245);
const Color Yellow(255,255,0);
const Color YellowGreen(154,205,50);
}
Color::Color()
{
}
Color::Color(uint8_t r, uint8_t g, uint8_t b) : Color(r,g,b,255)
{
}
Color::Color(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
{
this->Red = r;
this->Green = g;
this->Blue = b;
this->Alpha = a;
}
Color::Color(Color c, uint8_t a) : Color(c.Red,c.Green,c.Blue,a)
{
}
Color::Color(uint8_t* color_data) : Color(color_data[0],color_data[1],color_data[2],color_data[3])
{
}
std::string Color::ToString(bool alphaIf255)
{
std::string str={
'#',
HttpUtils::NibbleToHex((Red >> 4) & 0x0F),
HttpUtils::NibbleToHex(Red & 0x0F),
HttpUtils::NibbleToHex((Green >> 4) & 0x0F),
HttpUtils::NibbleToHex(Green & 0x0F),
HttpUtils::NibbleToHex((Blue >> 4) & 0x0F),
HttpUtils::NibbleToHex(Blue & 0x0F)
};
if(alphaIf255 || this->Alpha < 255)
{
str.push_back(HttpUtils::NibbleToHex((Blue >> 4) & 0x0F));
str.push_back(HttpUtils::NibbleToHex(Blue & 0x0F));
}
return str;
}
void Color::ToArray(uint8_t* color_data)
{
color_data[0] = Red;
color_data[1] = Green;
color_data[2] = Blue;
color_data[3] = Alpha;
}
bool Color::TryParse(std::string color, Color& col)
{
color = HttpUtils::ToLower(color);
if(color.size() < 1) return false;
else if(color[0] != '#') {
if(color == "aliceblue") {col = Colors::AliceBlue; return true;}
else if(color == "antiquewhite") {col = Colors::AntiqueWhite; return true;}
else if(color == "aqua") {col = Colors::Aqua; return true;}
else if(color == "aquamarine") {col = Colors::Aquamarine; return true;}
else if(color == "azure"){ col = Colors::Azure; return true; }
else if(color == "beige"){ col = Colors::Beige; return true; }
else if(color == "bisque"){ col = Colors::Bisque; return true; }
else if(color == "black"){ col = Colors::Black; return true; }
else if(color == "blanchedalmond"){ col = Colors::BlanchedAlmond; return true; }
else if(color == "blue"){ col = Colors::Blue; return true; }
else if(color == "blueviolet"){ col = Colors::BlueViolet; return true; }
else if(color == "brown"){ col = Colors::Brown; return true; }
else if(color == "burlywood"){ col = Colors::BurlyWood; return true; }
else if(color == "cadetblue"){ col = Colors::CadetBlue; return true; }
else if(color == "chartreuse"){ col = Colors::Chartreuse; return true; }
else if(color == "chocolate"){ col = Colors::Chocolate; return true; }
else if(color == "coral"){ col = Colors::Coral; return true; }
else if(color == "cornflowerblue"){ col = Colors::CornflowerBlue; return true; }
else if(color == "cornsilk"){ col = Colors::Cornsilk; return true; }
else if(color == "crimson"){ col = Colors::Crimson; return true; }
else if(color == "cyan"){ col = Colors::Cyan; return true; }
else if(color == "darkblue"){ col = Colors::DarkBlue; return true; }
else if(color == "darkcyan"){ col = Colors::DarkCyan; return true; }
else if(color == "darkgoldenrod"){ col = Colors::DarkGoldenRod; return true; }
else if(color == "darkgray"){ col = Colors::DarkGray; return true; }
else if(color == "darkgrey"){ col = Colors::DarkGrey; return true; }
else if(color == "darkgreen"){ col = Colors::DarkGreen; return true; }
else if(color == "darkkhaki"){ col = Colors::DarkKhaki; return true; }
else if(color == "darkmagenta"){ col = Colors::DarkMagenta; return true; }
else if(color == "darkolivegreen"){ col = Colors::DarkOliveGreen; return true; }
else if(color == "darkorange"){ col = Colors::DarkOrange; return true; }
else if(color == "darkorchid"){ col = Colors::DarkOrchid; return true; }
else if(color == "darkred"){ col = Colors::DarkRed; return true; }
else if(color == "darksalmon"){ col = Colors::DarkSalmon; return true; }
else if(color == "darkseagreen"){ col = Colors::DarkSeaGreen; return true; }
else if(color == "darkslateblue"){ col = Colors::DarkSlateBlue; return true; }
else if(color == "darkslategray"){ col = Colors::DarkSlateGray; return true; }
else if(color == "darkslategrey"){ col = Colors::DarkSlateGrey; return true; }
else if(color == "darkturquoise"){ col = Colors::DarkTurquoise; return true; }
else if(color == "darkviolet"){ col = Colors::DarkViolet; return true; }
else if(color == "deeppink"){ col = Colors::DeepPink; return true; }
else if(color == "deepskyblue"){ col = Colors::DeepSkyBlue; return true; }
else if(color == "dimgray"){ col = Colors::DimGray; return true; }
else if(color == "dimgrey"){ col = Colors::DimGrey; return true; }
else if(color == "dodgerblue"){ col = Colors::DodgerBlue; return true; }
else if(color == "firebrick"){ col = Colors::FireBrick; return true; }
else if(color == "floralwhite"){ col = Colors::FloralWhite; return true; }
else if(color == "forestgreen"){ col = Colors::ForestGreen; return true; }
else if(color == "fuchsia"){ col = Colors::Fuchsia; return true; }
else if(color == "gainsboro"){ col = Colors::Gainsboro; return true; }
else if(color == "ghostwhite"){ col = Colors::GhostWhite; return true; }
else if(color == "gold"){ col = Colors::Gold; return true; }
else if(color == "goldenrod"){ col = Colors::GoldenRod; return true; }
else if(color == "gray"){ col = Colors::Gray; return true; }
else if(color == "grey"){ col = Colors::Grey; return true; }
else if(color == "green"){ col = Colors::Green; return true; }
else if(color == "greenyellow"){ col = Colors::GreenYellow; return true; }
else if(color == "honeydew"){ col = Colors::HoneyDew; return true; }
else if(color == "hotpink"){ col = Colors::HotPink; return true; }
else if(color == "indianred"){ col = Colors::IndianRed; return true; }
else if(color == "indigo"){ col = Colors::Indigo; return true; }
else if(color == "ivory"){ col = Colors::Ivory; return true; }
else if(color == "khaki"){ col = Colors::Khaki; return true; }
else if(color == "lavender"){ col = Colors::Lavender; return true; }
else if(color == "lavenderblush"){ col = Colors::LavenderBlush; return true; }
else if(color == "lawngreen"){ col = Colors::LawnGreen; return true; }
else if(color == "lemonchiffon"){ col = Colors::LemonChiffon; return true; }
else if(color == "lightblue"){ col = Colors::LightBlue; return true; }
else if(color == "lightcoral"){ col = Colors::LightCoral; return true; }
else if(color == "lightcyan"){ col = Colors::LightCyan; return true; }
else if(color == "lightgoldenrodyellow"){ col = Colors::LightGoldenRodYellow; return true; }
else if(color == "lightgray"){ col = Colors::LightGray; return true; }
else if(color == "lightgrey"){ col = Colors::LightGrey; return true; }
else if(color == "lightgreen"){ col = Colors::LightGreen; return true; }
else if(color == "lightpink"){ col = Colors::LightPink; return true; }
else if(color == "lightsalmon"){ col = Colors::LightSalmon; return true; }
else if(color == "lightseagreen"){ col = Colors::LightSeaGreen; return true; }
else if(color == "lightskyblue"){ col = Colors::LightSkyBlue; return true; }
else if(color == "lightslategray"){ col = Colors::LightSlateGray; return true; }
else if(color == "lightslategrey"){ col = Colors::LightSlateGrey; return true; }
else if(color == "lightsteelblue"){ col = Colors::LightSteelBlue; return true; }
else if(color == "lightyellow"){ col = Colors::LightYellow; return true; }
else if(color == "lime"){ col = Colors::Lime; return true; }
else if(color == "limegreen"){ col = Colors::LimeGreen; return true; }
else if(color == "linen"){ col = Colors::Linen; return true; }
else if(color == "magenta"){ col = Colors::Magenta; return true; }
else if(color == "maroon"){ col = Colors::Maroon; return true; }
else if(color == "mediumaquamarine"){ col = Colors::MediumAquaMarine; return true; }
else if(color == "mediumblue"){ col = Colors::MediumBlue; return true; }
else if(color == "mediumorchid"){ col = Colors::MediumOrchid; return true; }
else if(color == "mediumpurple"){ col = Colors::MediumPurple; return true; }
else if(color == "mediumseagreen"){ col = Colors::MediumSeaGreen; return true; }
else if(color == "mediumslateblue"){ col = Colors::MediumSlateBlue; return true; }
else if(color == "mediumspringgreen"){ col = Colors::MediumSpringGreen; return true; }
else if(color == "mediumturquoise"){ col = Colors::MediumTurquoise; return true; }
else if(color == "mediumvioletred"){ col = Colors::MediumVioletRed; return true; }
else if(color == "midnightblue"){ col = Colors::MidnightBlue; return true; }
else if(color == "mintcream"){ col = Colors::MintCream; return true; }
else if(color == "mistyrose"){ col = Colors::MistyRose; return true; }
else if(color == "moccasin"){ col = Colors::Moccasin; return true; }
else if(color == "navajowhite"){ col = Colors::NavajoWhite; return true; }
else if(color == "navy"){ col = Colors::Navy; return true; }
else if(color == "oldlace"){ col = Colors::OldLace; return true; }
else if(color == "olive"){ col = Colors::Olive; return true; }
else if(color == "olivedrab"){ col = Colors::OliveDrab; return true; }
else if(color == "orange"){ col = Colors::Orange; return true; }
else if(color == "orangered"){ col = Colors::OrangeRed; return true; }
else if(color == "orchid"){ col = Colors::Orchid; return true; }
else if(color == "palegoldenrod"){ col = Colors::PaleGoldenRod; return true; }
else if(color == "palegreen"){ col = Colors::PaleGreen; return true; }
else if(color == "paleturquoise"){ col = Colors::PaleTurquoise; return true; }
else if(color == "palevioletred"){ col = Colors::PaleVioletRed; return true; }
else if(color == "papayawhip"){ col = Colors::PapayaWhip; return true; }
else if(color == "peachpuff"){ col = Colors::PeachPuff; return true; }
else if(color == "peru"){ col = Colors::Peru; return true; }
else if(color == "pink"){ col = Colors::Pink; return true; }
else if(color == "plum"){ col = Colors::Plum; return true; }
else if(color == "powderblue"){ col = Colors::PowderBlue; return true; }
else if(color == "purple"){ col = Colors::Purple; return true; }
else if(color == "rebeccapurple"){ col = Colors::RebeccaPurple; return true; }
else if(color == "red"){ col = Colors::Red; return true; }
else if(color == "rosybrown"){ col = Colors::RosyBrown; return true; }
else if(color == "saddlebrown"){ col = Colors::SaddleBrown; return true; }
else if(color == "salmon"){ col = Colors::Salmon; return true; }
else if(color == "sandybrown"){ col = Colors::SandyBrown; return true; }
else if(color == "seagreen"){ col = Colors::SeaGreen; return true; }
else if(color == "seashell"){ col = Colors::SeaShell; return true; }
else if(color == "sienna"){ col = Colors::Sienna; return true; }
else if(color == "silver"){ col = Colors::Silver; return true; }
else if(color == "skyblue"){ col = Colors::SkyBlue; return true; }
else if(color == "slateblue"){ col = Colors::SlateBlue; return true; }
else if(color == "slategray"){ col = Colors::SlateGray; return true; }
else if(color == "slategrey"){ col = Colors::SlateGrey; return true; }
else if(color == "snow"){ col = Colors::Snow; return true; }
else if(color == "springgreen"){ col = Colors::SpringGreen; return true; }
else if(color == "steelblue"){ col = Colors::SteelBlue; return true; }
else if(color == "tan"){ col = Colors::Tan; return true; }
else if(color == "teal"){ col = Colors::Teal; return true; }
else if(color == "thistle"){ col = Colors::Thistle; return true; }
else if(color == "tomato"){ col = Colors::Tomato; return true; }
else if(color == "turquoise"){ col = Colors::Turquoise; return true; }
else if(color == "violet"){ col = Colors::Violet; return true; }
else if(color == "wheat"){ col = Colors::Wheat; return true; }
else if(color == "white"){ col = Colors::White; return true; }
else if(color == "whitesmoke"){ col = Colors::WhiteSmoke; return true; }
else if(color == "yellow"){ col = Colors::Yellow; return true; }
else if(color == "yellowgreen"){ col = Colors::YellowGreen; return true; }
}
else if(color.size() == 4)
{
for(size_t i = 1; i < 4; i++)
if((color[i] < 'a' || color[i] > 'f') && (color[i] < '0' || color[i] > '9')) return false;
uint8_t r = HttpUtils::HexToNibble(color[1]);
uint8_t g = HttpUtils::HexToNibble(color[2]);
uint8_t b = HttpUtils::HexToNibble(color[3]);
col.Red = r | r << 4;
col.Green = g | g << 4;
col.Blue = b | b << 4;
col.Alpha = 255;
return true;
}
else if(color.size() == 5)
{
for(size_t i = 1; i < 5; i++)
if((color[i] < 'a' || color[i] > 'f') && (color[i] < '0' || color[i] > '9')) return false;
uint8_t r = HttpUtils::HexToNibble(color[1]);
uint8_t g = HttpUtils::HexToNibble(color[2]);
uint8_t b = HttpUtils::HexToNibble(color[3]);
uint8_t a = HttpUtils::HexToNibble(color[4]);
col.Red = r | r << 4;
col.Green = g | g << 4;
col.Blue = b | b << 4;
col.Alpha = a | a << 4;
return true;
}
else if(color.size() == 7)
{
for(size_t i = 1; i < 7; i++)
if((color[i] < 'a' || color[i] > 'f') && (color[i] < '0' || color[i] > '9')) return false;
uint8_t r = (HttpUtils::HexToNibble(color[1]) << 4) | HttpUtils::HexToNibble(color[2]);
uint8_t g = (HttpUtils::HexToNibble(color[3]) << 4) | HttpUtils::HexToNibble(color[4]);
uint8_t b = (HttpUtils::HexToNibble(color[5]) << 4) | HttpUtils::HexToNibble(color[6]);
col.Red = r;
col.Green = g;
col.Blue = b;
col.Alpha = 255;
return true;
}
else if(color.size() == 9)
{
for(size_t i = 1; i < 9; i++)
if((color[i] < 'a' || color[i] > 'f') && (color[i] < '0' || color[i] > '9')) return false;
uint8_t r = (HttpUtils::HexToNibble(color[1]) << 4) | HttpUtils::HexToNibble(color[2]);
uint8_t g = (HttpUtils::HexToNibble(color[3]) << 4) | HttpUtils::HexToNibble(color[4]);
uint8_t b = (HttpUtils::HexToNibble(color[5]) << 4) | HttpUtils::HexToNibble(color[6]);
uint8_t a = (HttpUtils::HexToNibble(color[7]) << 4) | HttpUtils::HexToNibble(color[8]);
col.Red = r;
col.Green = g;
col.Blue = b;
col.Alpha = a;
return true;
return true;
}
return false;
}
Color Color::Parse(std::string color)
{
Color c;
if(Color::TryParse(color,c)) return c;
throw TextException("Could not parse color");
}
bool Color::operator!=(Color other)
{
return !(*this == other);
}
bool Color::operator==(Color other)
{
return Red == other.Red && Green == other.Green && Blue == other.Blue && Alpha == other.Alpha;
}
}

56
src/Graphics/Image.cpp Normal file
View File

@ -0,0 +1,56 @@
#include "TessesFramework/Graphics/Image.hpp"
namespace Tesses::Framework::Graphics {
Image::Image()
{
}
Image::Image(uint32_t w, uint32_t h)
{
this->w = w;
this->h = h;
SetSize(w,h);
}
Image::Image(uint32_t w,uint32_t h,std::vector<Color> data)
{
this->w = w;
this->h = h;
this->data = data;
if(this->data.size() != w * h) throw TextException("data size does not match the factor of width and height");
}
uint32_t Image::Width()
{
return this->w;
}
uint32_t Image::Height()
{
return this->h;
}
void Image::SetSize(uint32_t w, uint32_t h)
{
this->w = w;
this->h = h;
this->data.resize(w * h);
}
void Image::SetSize(uint32_t w, uint32_t h, Color c)
{
this->w = w;
this->h = h;
this->data.resize(w * h);
for(size_t i = 0; i < this->data.size(); i++) this->data[i] = c;
}
void Image::SetPixel(uint32_t x, uint32_t y, Color c)
{
this->data[y*w+x] = c;
}
Color Image::GetPixel(uint32_t x, uint32_t y)
{
return this->data[y*w+x];
}
std::vector<Color>& Image::Data()
{
return this->data;
}
}

View File

@ -0,0 +1,201 @@
#include "TessesFramework/Graphics/ImageFormats/Bitmap.hpp"
#include "TessesFramework/Streams/ByteWriter.hpp"
#include "TessesFramework/Streams/MemoryStream.hpp"
#include <iostream>
namespace Tesses::Framework::Graphics::ImageFormats {
Bitmap::Bitmap()
{
}
void Bitmap::Load(Tesses::Framework::Streams::Stream* strm, Image* image)
{
uint8_t header[14];
if(strm->ReadBlock(header,14) < 14) throw TextException("Invalid bmp file, header to small.");
if(header[0] != 0x42 || header[1] != 0x4D) throw TextException("Invalid bmp file, does not start with BM.");
uint8_t info_header[40];
if(strm->ReadBlock(info_header,40) < 40) throw TextException("Invalid bmp file, info header is too small.");
if(info_header[0] != 40 || info_header[1] != 0 || info_header[2] != 0 || info_header[3] != 0) throw TextException("Invald bmp file, info header size is corrupt.");
uint32_t width = 0;
width |= (uint32_t)info_header[4];
width |= (uint32_t)info_header[5] << 8;
width |= (uint32_t)info_header[6] << 16;
width |= (uint32_t)info_header[7] << 24;
uint32_t height = 0;
height |= (uint32_t)info_header[8];
height |= (uint32_t)info_header[9] << 8;
height |= (uint32_t)info_header[10] << 16;
height |= (uint32_t)info_header[11] << 24;
int32_t h0= *(int32_t*)&height;
bool isInverted=h0 < 0;
if(isInverted) height = (uint32_t)(-h0);
image->SetSize(width,height);
uint16_t planes = 0;
planes |= (uint16_t)info_header[12];
planes |= (uint16_t)info_header[13] << 8;
if(planes != 1) throw TextException("Planes is not 1");
uint16_t bpp = 0;
bpp |= (uint16_t)info_header[14];
bpp |= (uint16_t)info_header[15] << 8;
uint32_t compression = 0;
compression |= (uint32_t)info_header[16];
compression |= (uint32_t)info_header[17] << 8;
compression |= (uint32_t)info_header[18] << 16;
compression |= (uint32_t)info_header[19] << 24;
if(compression != 0) throw TextException("This bmp decoder does not support compression");
uint32_t imageSize = 0;
imageSize |= (uint32_t)info_header[20];
imageSize |= (uint32_t)info_header[21] << 8;
imageSize |= (uint32_t)info_header[22] << 16;
imageSize |= (uint32_t)info_header[23] << 24;
uint32_t colorsUsed = 0;
colorsUsed |= (uint32_t)info_header[32];
colorsUsed |= (uint32_t)info_header[33] << 8;
colorsUsed |= (uint32_t)info_header[34] << 16;
colorsUsed |= (uint32_t)info_header[35] << 24;
std::vector<Color> col={};
if(colorsUsed > 0)
{
col.resize(colorsUsed);
uint8_t* buff = new uint8_t[colorsUsed*4];
if(strm->ReadBlock(buff,colorsUsed*4) != colorsUsed*4) { delete buff; throw TextException("Could not read colors");}
for(size_t i = 0; i < colorsUsed; i++)
{
col[i].Red = buff[i * 4 + 2];
col[i].Green = buff[i * 4 + 1];
col[i].Blue = buff[i * 4];
col[i].Alpha = 255;
}
delete buff;
}
std::vector<Color>& pixel_out = image->Data();
if(bpp == 24)
{
uint32_t stride = 3 * width;
uint32_t m = stride % 4;
if(m != 0) stride += 4 - (m % 4);
uint8_t* buffer = new uint8_t[stride];
for(uint32_t y = 0; y < height; y++)
{
uint32_t yOut = isInverted ? y : ((height - y)-1);
if(strm->ReadBlock(buffer,stride) != stride)
{
delete buffer;
throw TextException("Bmp image data is truncated");
}
for(uint32_t x = 0; x < width; x++)
{
pixel_out[yOut * width + x].Red = buffer[x*3+2];
pixel_out[yOut * width + x].Green = buffer[x*3+1];
pixel_out[yOut * width + x].Blue = buffer[x*3];
pixel_out[yOut * width + x].Alpha=255;
}
}
delete buffer;
}
else if(bpp == 16)
{
uint32_t stride = 2 * width;
uint32_t m = stride % 4;
if(m != 0) stride += 4 - (m % 4);
uint8_t* buffer = new uint8_t[stride];
for(uint32_t y = 0; y < height; y++)
{
uint32_t yOut =isInverted ? y : ((height - y)-1);
if(strm->ReadBlock(buffer,stride) != stride)
{
delete buffer;
throw TextException("Bmp image data is truncated");
}
for(uint32_t x = 0; x < width; x++)
{
uint16_t px = (uint16_t)(buffer[x*2+1] << 8) | (uint16_t)buffer[x*2];
uint16_t red = (px & 0xF800) >> 11;
uint16_t green = (px & 0x07E0) >> 5;
uint16_t blue = (px & 0x001F);
red = (red * 255 + 15) / 31;
green = (green * 255 + 31) / 63;
blue = (blue * 255 + 15) / 31;
pixel_out[yOut * width + x].Red = red;
pixel_out[yOut * width + x].Green = green;
pixel_out[yOut * width + x].Blue = blue;
pixel_out[yOut * width + x].Alpha=255;
}
}
delete buffer;
}
else if(bpp == 8)
{
uint32_t stride = width;
uint8_t* buffer = new uint8_t[stride];
for(uint32_t y = 0; y < height; y++)
{
uint32_t yOut =isInverted ? y : ((height - y)-1);
if(strm->ReadBlock(buffer,stride) != stride)
{
delete buffer;
throw TextException("Bmp image data is truncated");
}
for(uint32_t x = 0; x < width; x++)
{
pixel_out[yOut * width + x] = col.at (buffer[x]);
}
}
delete buffer;
}
else throw TextException("Bitdepth " + std::to_string(bpp) + "bpp is not supported yet.");
}
void Bitmap::Save(Tesses::Framework::Streams::Stream* strm, Image* image,std::string flags)
{
Tesses::Framework::Streams::MemoryStream memStrm(true);
Tesses::Framework::Streams::ByteWriter writer(memStrm);
uint32_t stride = image->Width() * 3;
uint32_t m = stride % 4;
if(m != 0) stride += 4 - (m % 4);
uint32_t sz = (stride * image->Height())+14+40;
memStrm.WriteBlock((const uint8_t*)"BM",2);
writer.WriteU32LE(sz);
writer.WriteU32LE(0);
writer.WriteU32LE(14+40);
writer.WriteU32LE(40);
writer.WriteU32LE(image->Width());
writer.WriteU32LE(image->Height());
writer.WriteU16LE(1);
writer.WriteU16LE(24);
writer.WriteU32LE(0);
writer.WriteU32LE(0);
writer.WriteU32LE(0);
writer.WriteU32LE(0);
writer.WriteU32LE(0);
writer.WriteU32LE(0);
memStrm.Seek(0,Tesses::Framework::Streams::SeekOrigin::Begin);
memStrm.CopyTo(strm);
uint8_t* buffer = new uint8_t[stride];
memset(buffer,0,stride);
auto width = image->Width();
auto height = image->Height();
for(uint32_t y = 0; y < height; y++)
{
uint32_t yOut = (height - y)-1;
for(uint32_t x = 0; x < width; x++)
{
auto c = image->GetPixel(x,yOut);
buffer[x*3+2] = c.Red;
buffer[x*3+1] = c.Green;
buffer[x*3] = c.Blue;
}
strm->WriteBlock(buffer,stride);
}
}
}

View File

@ -0,0 +1,11 @@
#include "TessesFramework/Graphics/ImageFormats/ImageFormat.hpp"
namespace Tesses::Framework::Graphics::ImageFormats
{
ImageFormat::~ImageFormat()
{
}
};

View File

@ -0,0 +1,24 @@
#include "TessesFramework/Graphics/Renderers/ImageRenderer.hpp"
namespace Tesses::Framework::Graphics::Renderers {
ImageRenderer::ImageRenderer(Image* image)
{
this->image = image;
}
uint32_t ImageRenderer::Width()
{
return this->image->Width();
}
uint32_t ImageRenderer::Height()
{
return this->image->Height();
}
void ImageRenderer::SetPixel(Point pt,Color c)
{
this->image->SetPixel(pt.X,pt.Y,c);
}
};

View File

@ -0,0 +1,53 @@
#include "TessesFramework/Graphics/Renderers/Renderer.hpp"
namespace Tesses::Framework::Graphics::Renderers {
void Renderer::DrawImage(Point pt, Image* image)
{
auto width = std::min(image->Width(),Width()- pt.X);
auto height = std::min(image->Height(),Height()-pt.Y);
for(uint32_t y = 0; y < height; y++)
{
for(uint32_t x = 0; x < width; x++)
{
this->SetPixel(Point(x+pt.X,y+pt.Y),image->GetPixel(x,y));
}
}
}
void Renderer::DrawRectangle(Rectangle rect, Color c, bool fill)
{
int32_t xMin = rect.Location.X;
int32_t xMax = (rect.Size.Width + xMin)-1;
int64_t yMin = rect.Location.Y;
int64_t yMax = (rect.Size.Height + yMin)-1;
if(fill)
{
for(int32_t y = yMin; y <= yMax;y++)
{
for(int32_t x = xMin; x <=xMax;x++)
{
SetPixel(Point(x,y),c);
}
}
}
else
{
for(int32_t x = xMin; x <=xMax;x++)
{
SetPixel(Point(x,yMin),c);
SetPixel(Point(x,yMax),c);
}
for(int32_t y = yMin; y <= yMax;y++)
{
SetPixel(Point(xMin,y),c);
SetPixel(Point(xMax,y),c);
}
}
}
Renderer::~Renderer()
{
}
};

30
src/HiddenField.cpp Normal file
View File

@ -0,0 +1,30 @@
#include "TessesFramework/HiddenField.hpp"
namespace Tesses::Framework
{
HiddenFieldData::~HiddenFieldData()
{
}
HiddenField::HiddenField()
{
this->ptr = nullptr;
}
HiddenField::HiddenField(HiddenFieldData* data)
{
this->ptr = data;
}
void HiddenField::SetField(HiddenFieldData* data)
{
if(this->ptr != nullptr) delete this->ptr;
this->ptr = data;
}
HiddenField::~HiddenField()
{
if(this->ptr != nullptr) delete this->ptr;
}
}

View File

@ -923,15 +923,17 @@ namespace Tesses::Framework::Http
std::string connection;
if(ctx.requestHeaders.TryGetFirst("Connection", connection))
{
if(connection != "keep-alive") return;
if(HttpUtils::ToLower(connection) != "keep-alive") return;
}
if(ctx.responseHeaders.TryGetFirst("Connection", connection))
{
if(connection != "keep-alive") return;
if(HttpUtils::ToLower(connection) != "keep-alive") return;
}
if(bStrm.EndOfStream()) return;
if(bStrm.EndOfStream()) {
return;
}
}
}

View File

@ -2,6 +2,7 @@
#include "TessesFramework/Filesystem/VFS.hpp"
using VFSPath = Tesses::Framework::Filesystem::VFSPath;
namespace Tesses::Framework::Http {
bool Uri::Relative(std::string url, Uri& uri)
{
auto index = url.find_first_of("//");
@ -727,6 +728,24 @@ namespace Tesses::Framework::Http {
}
return true;
}
bool CaseInsensitiveLess::operator() (const std::string& s1, const std::string& s2) const {
return HttpUtils::ToLower(s1) < HttpUtils::ToLower(s2);
}
std::string HttpUtils::ToLower(std::string str)
{
std::string str1(str.length(),' ');
std::transform(str.begin(), str.end(), str1.begin(), tolower);
return str1;
}
std::string HttpUtils::ToUpper(std::string str)
{
std::string str1(str.length(),' ');
std::transform(str.begin(), str.end(), str1.begin(), toupper);
return str1;
}
bool HttpDictionary::GetFirstBoolean(std::string key)
{

160
src/Streams/ByteReader.cpp Normal file
View File

@ -0,0 +1,160 @@
#include "TessesFramework/Streams/ByteReader.hpp"
namespace Tesses::Framework::Streams
{
Stream* ByteReader::GetStream()
{
return this->strm;
}
ByteReader::ByteReader(Stream* strm, bool owns)
{
this->strm = strm;
this->owns = owns;
}
ByteReader::ByteReader(Stream& strm) : ByteReader(&strm,false)
{
}
uint8_t ByteReader::ReadU8()
{
auto r = this->strm->ReadByte();
if(r < 0) throw TextException("End of file");
return (uint8_t)r;
}
uint16_t ByteReader::ReadU16BE()
{
uint8_t data[2];
if(this->strm->ReadBlock(data,2) != 2) throw TextException("End of file");
uint16_t n = 0;
n |= (uint16_t)data[0] << 8;
n |= (uint16_t)data[1];
return n;
}
uint16_t ByteReader::ReadU16LE()
{
uint8_t data[2];
if(this->strm->ReadBlock(data,2) != 2) throw TextException("End of file");
uint16_t n = 0;
n |= (uint16_t)data[0];
n |= (uint16_t)data[1] << 8;
return n;
}
uint32_t ByteReader::ReadU32BE()
{
uint8_t data[4];
if(this->strm->ReadBlock(data,4) != 4) throw TextException("End of file");
uint32_t n = 0;
n |= (uint32_t)data[0] << 24;
n |= (uint32_t)data[1] << 16;
n |= (uint32_t)data[2] << 8;
n |= (uint32_t)data[3];
return n;
}
uint32_t ByteReader::ReadU32LE()
{
uint8_t data[4];
if(this->strm->ReadBlock(data,4) != 4) throw TextException("End of file");
uint32_t n = 0;
n |= (uint32_t)data[0];
n |= (uint32_t)data[1] << 8;
n |= (uint32_t)data[2] << 16;
n |= (uint32_t)data[3] << 24;
return n;
}
uint64_t ByteReader::ReadU64BE()
{
uint8_t data[8];
if(this->strm->ReadBlock(data,8) != 8) throw TextException("End of file");
uint64_t n = 0;
n |= (uint64_t)data[0] << 56;
n |= (uint64_t)data[1] << 48;
n |= (uint64_t)data[2] << 40;
n |= (uint64_t)data[3] << 32;
n |= (uint64_t)data[4] << 24;
n |= (uint64_t)data[5] << 16;
n |= (uint64_t)data[6] << 8;
n |= (uint64_t)data[7];
return n;
}
uint64_t ByteReader::ReadU64LE()
{
uint8_t data[8];
if(this->strm->ReadBlock(data,8) != 8) throw TextException("End of file");
uint64_t n = 0;
n |= (uint64_t)data[0];
n |= (uint64_t)data[1] << 8;
n |= (uint64_t)data[2] << 16;
n |= (uint64_t)data[3] << 24;
n |= (uint64_t)data[4] << 32;
n |= (uint64_t)data[5] << 40;
n |= (uint64_t)data[6] << 48;
n |= (uint64_t)data[7] << 56;
return n;
}
int8_t ByteReader::ReadI8()
{
auto v=ReadU8();
return *(int8_t*)&v;
}
int16_t ByteReader::ReadI16BE()
{
auto v=ReadU16BE();
return *(int16_t*)&v;
}
int16_t ByteReader::ReadI16LE()
{
auto v=ReadU16BE();
return *(int16_t*)&v;
}
int32_t ByteReader::ReadI32BE()
{
auto v=ReadU32BE();
return *(int32_t*)&v;
}
int32_t ByteReader::ReadI32LE()
{
auto v=ReadU32LE();
return *(int32_t*)&v;
}
int64_t ByteReader::ReadI64BE()
{
auto v=ReadU64BE();
return *(int64_t*)&v;
}
int64_t ByteReader::ReadI64LE()
{
auto v=ReadU64LE();
return *(int64_t*)&v;
}
float ByteReader::ReadF32BE()
{
auto v=ReadU32BE();
return *(float*)&v;
}
float ByteReader::ReadF32LE()
{
auto v=ReadU32LE();
return *(float*)&v;
}
double ByteReader::ReadF64BE()
{
auto v=ReadU64BE();
return *(double*)&v;
}
double ByteReader::ReadF64LE()
{
auto v=ReadU64LE();
return *(double*)&v;
}
ByteReader::~ByteReader()
{
if(this->owns) delete this->strm;
}
}

140
src/Streams/ByteWriter.cpp Normal file
View File

@ -0,0 +1,140 @@
#include "TessesFramework/Streams/ByteWriter.hpp"
namespace Tesses::Framework::Streams
{
Stream* ByteWriter::GetStream()
{
return this->strm;
}
ByteWriter::ByteWriter(Stream* strm, bool owns)
{
this->strm = strm;
this->owns = owns;
}
ByteWriter::ByteWriter(Stream& strm) : ByteWriter(&strm,false)
{
}
void ByteWriter::WriteU8(uint8_t v)
{
strm->WriteByte(v);
}
void ByteWriter::WriteU16BE(uint16_t v)
{
uint8_t b[2];
b[0] = (uint8_t)(v >> 8);
b[1] = (uint8_t)v;
strm->WriteBlock(b,2);
}
void ByteWriter::WriteU16LE(uint16_t v)
{
uint8_t b[2];
b[0] = (uint8_t)v;
b[1] = (uint8_t)(v >> 8);
strm->WriteBlock(b,2);
}
void ByteWriter::WriteU32BE(uint32_t v)
{
uint8_t b[4];
b[0] = (uint8_t)(v >> 24);
b[1] = (uint8_t)(v >> 16);
b[2] = (uint8_t)(v >> 8);
b[3] = (uint8_t)v;
strm->WriteBlock(b,4);
}
void ByteWriter::WriteU32LE(uint32_t v)
{
uint8_t b[4];
b[0] = (uint8_t)v;
b[1] = (uint8_t)(v >> 8);
b[2] = (uint8_t)(v >> 16);
b[3] = (uint8_t)(v >> 24);
strm->WriteBlock(b,4);
}
void ByteWriter::WriteU64BE(uint64_t v)
{
uint8_t b[8];
b[0] = (uint8_t)(v >> 56);
b[1] = (uint8_t)(v >> 48);
b[2] = (uint8_t)(v >> 40);
b[3] = (uint8_t)(v >> 32);
b[4] = (uint8_t)(v >> 24);
b[5] = (uint8_t)(v >> 16);
b[6] = (uint8_t)(v >> 8);
b[7] = (uint8_t)v;
strm->WriteBlock(b,8);
}
void ByteWriter::WriteU64LE(uint64_t v)
{
uint8_t b[8];
b[0] = (uint8_t)v;
b[1] = (uint8_t)(v >> 8);
b[2] = (uint8_t)(v >> 16);
b[3] = (uint8_t)(v >> 24);
b[4] = (uint8_t)(v >> 32);
b[5] = (uint8_t)(v >> 40);
b[6] = (uint8_t)(v >> 48);
b[7] = (uint8_t)(v >> 56);
strm->WriteBlock(b,8);
}
void ByteWriter::WriteI8(int8_t v)
{
uint8_t data = *(uint8_t*)&v;
WriteU8(data);
}
void ByteWriter::WriteI16BE(int16_t v)
{
uint16_t data = *(uint16_t*)&v;
WriteU16BE(data);
}
void ByteWriter::WriteI16LE(int16_t v)
{
uint16_t data = *(uint16_t*)&v;
WriteU16LE(data);
}
void ByteWriter::WriteI32BE(int32_t v)
{
uint32_t data = *(uint32_t*)&v;
WriteU32BE(data);
}
void ByteWriter::WriteI32LE(int32_t v)
{
uint32_t data = *(uint32_t*)&v;
WriteU32LE(data);
}
void ByteWriter::WriteI64BE(int64_t v)
{
uint64_t data = *(uint64_t*)&v;
WriteU64BE(data);
}
void ByteWriter::WriteI64LE(int64_t v)
{
uint64_t data = *(uint64_t*)&v;
WriteU64LE(data);
}
void ByteWriter::WriteF32BE(float v)
{
uint32_t data = *(uint32_t*)&v;
WriteU32BE(data);
}
void ByteWriter::WriteF32LE(float v)
{
uint32_t data = *(uint32_t*)&v;
WriteU32LE(data);
}
void ByteWriter::WriteF64BE(double v)
{
uint64_t data = *(uint64_t*)&v;
WriteU64BE(data);
}
void ByteWriter::WriteF64LE(double v)
{
uint64_t data = *(uint64_t*)&v;
WriteU64LE(data);
}
ByteWriter::~ByteWriter()
{
if(this->owns) delete this->strm;
}
}

View File

@ -2,6 +2,9 @@
#include "TessesFramework/Http/HttpUtils.hpp"
using HttpUtils = Tesses::Framework::Http::HttpUtils;
#if defined(TESSESFRAMEWORK_ENABLE_NETWORKING)
#if defined(GEKKO)
#define ss_family sin_family
@ -561,3 +564,110 @@ namespace Tesses::Framework::Streams {
NETWORK_SETSOCKOPT(this->sock, SOL_SOCKET, TCP_NODELAY, (const char*)&noDelay2,(socklen_t)sizeof(noDelay2));
}
}
#else
namespace Tesses::Framework::Streams {
class TcpServer {
int32_t sock;
bool owns;
bool valid;
public:
TcpServer(int32_t sock,bool owns);
TcpServer(uint16_t port, int32_t backlog);
TcpServer(std::string ip, uint16_t port, int32_t backlog);
NetworkStream* GetStream(std::string& ip, uint16_t& port);
~TcpServer();
void Close();
};
TcpServer::TcpServer(int32_t sock,bool owns)
{
}
TcpServer::TcpServer(uint16_t port, int32_t backlog)
{
}
TcpServer::TcpServer(std::string ip, uint16_t port, int32_t backlog)
{
}
NetworkStream* TcpServer::GetStream(std::string& ip, uint16_t& port)
{
return nullptr;
}
TcpServer::~TcpServer()
{
}
void TcpServer::Close()
{
}
bool NetworkStream::EndOfStream() {
return true;
}
bool NetworkStream::CanRead() {
return false;
}
bool NetworkStream::CanWrite() {
return false;
}
NetworkStream::NetworkStream(bool ipV6,bool datagram)
{
}
NetworkStream::NetworkStream(std::string ipOrFqdn, uint16_t port, bool datagram,bool broadcast,bool supportIPv6)
{
}
NetworkStream::NetworkStream(int32_t sock, bool owns)
{
}
void NetworkStream::Listen(int32_t backlog)
{
}
void NetworkStream::Bind(std::string ip, uint16_t port)
{
}
void NetworkStream::SetBroadcast(bool bC)
{
}
NetworkStream* NetworkStream::Accept(std::string& ip, uint16_t& port)
{
return nullptr;
}
size_t NetworkStream::Read(uint8_t* buff, size_t sz)
{
return 0;
}
size_t NetworkStream::Write(const uint8_t* buff, size_t sz)
{
return 0;
}
size_t NetworkStream::ReadFrom(uint8_t* buff, size_t sz, std::string& ip, uint16_t& port)
{
return 0;
}
size_t NetworkStream::WriteTo(const uint8_t* buff, size_t sz, std::string ip, uint16_t port)
{
return 0;
}
std::vector<std::pair<std::string,std::string>> NetworkStream::GetIPs(bool ipV6)
{
return {};
}
NetworkStream::~NetworkStream()
{
}
void NetworkStream::SetNoDelay(bool noDelay)
{
}
}
#endif

View File

@ -1,62 +1,92 @@
#include "TessesFramework/Threading/Mutex.hpp"
#include <cstring>
#include <iostream>
#if defined(_WIN32)
#include <windows.h>
#elif defined(GEKKO)
#include <ogc/mutex.h>
#else
#include <pthread.h>
#endif
namespace Tesses::Framework::Threading
{
class MutexHiddenFieldData : public HiddenFieldData
{
public:
#if defined(_WIN32)
HANDLE mtx;
#elif defined(GEKKO)
mutex_t mtx;
#else
pthread_mutex_t mtx;
pthread_mutexattr_t attr;
#endif
~MutexHiddenFieldData()
{
#if defined(_WIN32)
CloseHandle(mtx);
#elif defined(GEKKO)
LWP_MutexDestroy(mtx);
#else
pthread_mutex_destroy(&mtx);
pthread_mutexattr_destroy(&attr);
#endif
}
};
Mutex::Mutex()
{
auto md=this->data.AllocField<MutexHiddenFieldData*>();
#if defined(_WIN32)
this->mtx = CreateMutex(NULL,false,NULL);
md->mtx = CreateMutex(NULL,false,NULL);
#elif defined(GEKKO)
mtx = LWP_MUTEX_NULL;
LWP_MutexInit(&mtx, true);
md->mtx = LWP_MUTEX_NULL;
LWP_MutexInit(&md->mtx, true);
#else
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&mtx,&attr);
pthread_mutexattr_init(&md->attr);
pthread_mutexattr_settype(&md->attr,PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&md->mtx,&md->attr);
#endif
}
void Mutex::Lock()
{
auto md = this->data.GetField<MutexHiddenFieldData*>();
#if defined(_WIN32)
WaitForSingleObject(mtx, INFINITE);
WaitForSingleObject(md->mtx, INFINITE);
#elif defined(GEKKO)
LWP_MutexLock(mtx);
LWP_MutexLock(md->mtx);
#else
pthread_mutex_lock(&mtx);
pthread_mutex_lock(&md->mtx);
#endif
}
void Mutex::Unlock()
{
auto md = this->data.GetField<MutexHiddenFieldData*>();
#if defined(_WIN32)
ReleaseMutex(mtx);
ReleaseMutex(md->mtx);
#elif defined(GEKKO)
LWP_MutexUnlock(mtx);
LWP_MutexUnlock(md->mtx);
#else
pthread_mutex_unlock(&mtx);
pthread_mutex_unlock(&md->mtx);
#endif
}
bool Mutex::TryLock()
{
auto md = this->data.GetField<MutexHiddenFieldData*>();
#if defined(_WIN32)
return WaitForSingleObject(mtx, 100) == WAIT_OBJECT_0;
return WaitForSingleObject(md->mtx, 100) == WAIT_OBJECT_0;
#elif defined(GEKKO)
return LWP_MutexTryLock(mtx) == 0;
return LWP_MutexTryLock(md->mtx) == 0;
#else
return pthread_mutex_trylock(&mtx) == 0;
return pthread_mutex_trylock(&md->mtx) == 0;
#endif
}
Mutex::~Mutex()
{
#if defined(_WIN32)
CloseHandle(mtx);
#elif defined(GEKKO)
LWP_MutexDestroy(mtx);
#else
pthread_mutex_destroy(&mtx);
pthread_mutexattr_destroy(&attr);
#endif
}
};

View File

@ -1,71 +1,95 @@
#include "TessesFramework/Threading/Thread.hpp"
#include <iostream>
namespace Tesses::Framework::Threading
{
#if defined(TESSESFRAMEWORK_ENABLE_THREADING)
class ThreadHiddenFieldData {
public:
#if defined(_WIN32)
HANDLE thrd;
DWORD thrdId;
public:
#elif defined(GEKKO)
lwp_t thrd;
#else
pthread_t thrd;
#endif
std::function<void()> fn;
std::atomic<bool> hasInvoked;
};
#if defined(_WIN32)
static DWORD __stdcall cb(LPVOID data)
#else
static void* cb(void* data)
#endif
{
auto thrd = static_cast<Thread*>(data);
auto thrd = static_cast<ThreadHiddenFieldData*>(data);
auto fn = thrd->fn;
thrd->hasInvoked=true;
fn();
#if defined(GEKKO)
#if !defined(_WIN32)
return NULL;
#else
return 0;
#endif
}
#else
void* Thread::cb(void* data)
{
auto thrd = static_cast<Thread*>(data);
auto fn = thrd->fn;
thrd->hasInvoked=true;
fn();
return NULL;
}
#endif
Thread::Thread(std::function<void()> fn)
{
this->hasInvoked=false;
this->fn = fn;
#if defined(TESSESFRAMEWORK_ENABLE_THREADING)
auto data = this->data.AllocField<ThreadHiddenFieldData*>();
data->hasInvoked=false;
data->fn = fn;
#if defined(_WIN32)
this->thrd = CreateThread(NULL,0,cb,static_cast<LPVOID>(this), 0, &this->thrdId);
data->thrd = CreateThread(NULL,0,cb,static_cast<LPVOID>(data), 0, &data->thrdId);
#elif defined(GEKKO)
auto res = LWP_CreateThread(&this->thrd, cb, static_cast<void*>(this), nullptr,12000, 98);
auto res = LWP_CreateThread(&data->thrd, cb, static_cast<void*>(data), nullptr,12000, 98);
#else
pthread_create(&thrd,NULL,cb,static_cast<void*>(this));
pthread_create(&data->thrd,NULL,cb,static_cast<void*>(data));
//thrd_create(&thrd, cb, static_cast<void*>(this));
#endif
while(!this->hasInvoked);
while(!data->hasInvoked);
#endif
}
void Thread::Detach()
{
#if defined(TESSESFRAMEWORK_ENABLE_THREADING)
auto data = this->data.AllocField<ThreadHiddenFieldData*>();
#if !defined(GEKKO)
#if defined(_WIN32)
CloseHandle(thrd);
CloseHandle(data->thrd);
#else
pthread_detach(thrd);
pthread_detach(data->thrd);
#endif
#endif
#endif
}
void Thread::Join()
{
#if defined(TESSESFRAMEWORK_ENABLE_THREADING)
auto data = this->data.AllocField<ThreadHiddenFieldData*>();
#if defined(_WIN32)
WaitForSingleObject(this->thrd, INFINITE);
WaitForSingleObject(data->thrd, INFINITE);
#elif defined(GEKKO)
void* res;
LWP_JoinThread(thrd,&res);
LWP_JoinThread(data->thrd,&res);
#else
pthread_join(thrd,NULL);
pthread_join(data->thrd,NULL);
#endif
#endif
}
}

View File

@ -8,12 +8,15 @@ namespace Tesses::Framework::Threading
{
#if defined(GEKKO)
return 1;
#else
#elif defined(TESSESFRAMEWORK_ENABLE_THREADING)
return (size_t)std::thread::hardware_concurrency();
#else
return 1;
#endif
}
ThreadPool::ThreadPool(size_t threads)
{
#if defined(TESSESFRAMEWORK_ENABLE_THREADING)
this->isRunning=true;
for(size_t i = 0; i < threads; i++)
{
@ -41,15 +44,19 @@ namespace Tesses::Framework::Threading
}
}));
}
#endif
}
void ThreadPool::Schedule(std::function<void()> cb)
{
#if defined(TESSESFRAMEWORK_ENABLE_THREADING)
this->mtx.Lock();
this->callbacks.push(cb);
this->mtx.Unlock();
#endif
}
ThreadPool::~ThreadPool()
{
#if defined(TESSESFRAMEWORK_ENABLE_THREADING)
while(true)
{
this->mtx.Lock();
@ -64,6 +71,6 @@ namespace Tesses::Framework::Threading
item->Join();
delete item;
}
#endif
}
}