Add native plugin support, remove SDL2
This commit is contained in:
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@ -72,6 +72,8 @@
|
||||
"mutex": "cpp",
|
||||
"semaphore": "cpp",
|
||||
"stop_token": "cpp",
|
||||
"thread": "cpp"
|
||||
"thread": "cpp",
|
||||
"bitset": "cpp",
|
||||
"regex": "cpp"
|
||||
}
|
||||
}
|
||||
@ -14,9 +14,9 @@ option(CROSSLANG_ENABLE_THREADING "Enable Tesses CrossLang threading" ON)
|
||||
option(CROSSLANG_ENABLE_SQLITE "Enable sqlite (Embedded database, supports Wii)" ON)
|
||||
option(CROSSLANG_ENABLE_JSON "Enable JSON" ON)
|
||||
option(CROSSLANG_ENABLE_PROCESS "Enable process" ON)
|
||||
option(CROSSLANG_ENABLE_SDL2 "Enable SDL2 (For Drawing)" ON)
|
||||
option(CROSSLANG_ENABLE_TERMIOS "Enable termios (For changing terminal options)" ON)
|
||||
option(CROSSLANG_ENABLE_PLATFORM_FOLDERS "Enable platform folders" ON)
|
||||
option(CROSSLANG_SHARED_EXECUTABLES "Link with libcrosslang_shared" ON)
|
||||
|
||||
option(CROSSLANG_CUSTOM_CONSOLE "Enable custom Console" OFF)
|
||||
|
||||
@ -59,22 +59,9 @@ endif()
|
||||
if(CROSSLANG_ENABLE_PLATFORM_FOLDERS)
|
||||
target_compile_definitions(${CROSSLANG_TARGET_NAME} PUBLIC CROSSLANG_ENABLE_PLATFORM_FOLDERS)
|
||||
endif()
|
||||
if(CROSSLANG_ENABLE_SHARED)
|
||||
target_compile_definitions(${CROSSLANG_TARGET_NAME} PUBLIC CROSSLANG_ENABLE_SHARED)
|
||||
|
||||
if(CROSSLANG_ENABLE_SDL2)
|
||||
target_compile_definitions(${CROSSLANG_TARGET_NAME} PUBLIC CROSSLANG_ENABLE_SDL2)
|
||||
find_package(SDL2 REQUIRED)
|
||||
find_package(SDL2_ttf REQUIRED)
|
||||
|
||||
|
||||
target_include_directories(${CROSSLANG_TARGET_NAME} PUBLIC ${SDL2_INCLUDE_DIRS})
|
||||
target_link_libraries(${CROSSLANG_TARGET_NAME} PUBLIC SDL2::SDL2)
|
||||
if("${CMAKE_SYSTEM_NAME}" STREQUAL "NintendoWii" OR "${CMAKE_SYSTEM_NAME}" STREQUAL "NintendoGameCube")
|
||||
target_link_libraries(${CROSSLANG_TARGET_NAME} PUBLIC SDL2_image png jpeg z)
|
||||
else()
|
||||
find_package(SDL2_image REQUIRED)
|
||||
target_link_libraries(${CROSSLANG_TARGET_NAME} PUBLIC ${SDL2_image_LIBRARIES})
|
||||
endif()
|
||||
target_link_libraries(${CROSSLANG_TARGET_NAME} PUBLIC ${SDL2_ttf_LIBRARIES})
|
||||
endif()
|
||||
if("${CMAKE_SYSTEM_NAME}" STREQUAL "NintendoWii" OR "${CMAKE_SYSTEM_NAME}" STREQUAL "NintendoGameCube")
|
||||
target_link_libraries(${CROSSLANG_TARGET_NAME} PUBLIC fat)
|
||||
@ -94,7 +81,6 @@ src/compiler/codegen.cpp
|
||||
src/compiler/lexer.cpp
|
||||
src/compiler/parser.cpp
|
||||
src/compiler/ast.cpp
|
||||
src/runtime_methods/sdl2.cpp
|
||||
src/runtime_methods/console.cpp
|
||||
src/runtime_methods/io.cpp
|
||||
src/runtime_methods/std.cpp
|
||||
@ -204,7 +190,7 @@ endif()
|
||||
|
||||
|
||||
if(CROSSLANG_ENABLE_BINARIES)
|
||||
if(CROSSLANG_ENABLE_SHARED)
|
||||
if(CROSSLANG_ENABLE_SHARED AND CROSSLANG_SHARED_EXECUTABLES)
|
||||
set(CMAKE_MACOSX_RPATH 1)
|
||||
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
|
||||
add_executable(crossc src/crosslangcompiler.cpp ${CROSSLANG_WIN32_EXE_SRC})
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
FROM onedev.site.tesses.net/tesses-framework/tesses-framework:latest
|
||||
RUN apt update -y && \
|
||||
apt install -y --no-install-recommends \
|
||||
libjansson-dev wget libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev && \
|
||||
libjansson-dev wget && \
|
||||
apt clean -y && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
RUN mkdir /src && cd /src && git clone https://onedev.site.tesses.net/crosslang . && cd /src && mkdir build && cd build && cmake -S .. -B . && make -j4 && make install && cd / && rm -r /src
|
||||
|
||||
@ -7,7 +7,6 @@ Tesses Cross Language
|
||||
- [TessesFramework](https://onedev.site.tesses.net/tesses-framework)
|
||||
- Jansson (but can be turned off but is strongly recommended otherwise many programs will not work)
|
||||
- CMake
|
||||
- SDL2 (but can be turned off)
|
||||
|
||||
## Use in docker (use my container)
|
||||
```bash
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
#include <memory>
|
||||
#include <cstring>
|
||||
#include <TessesFramework/TessesFramework.hpp>
|
||||
#include <regex>
|
||||
#define TVM_MAJOR 1
|
||||
#define TVM_MINOR 0
|
||||
#define TVM_PATCH 0
|
||||
@ -650,7 +651,7 @@ class Parser {
|
||||
class MethodInvoker {
|
||||
|
||||
};
|
||||
using TObject = std::variant<int64_t,double,char,bool,std::string,Tesses::Framework::Filesystem::VFSPath,std::nullptr_t,Undefined,MethodInvoker,THeapObjectHolder>;
|
||||
using TObject = std::variant<int64_t,double,char,bool,std::string,std::regex,Tesses::Framework::Filesystem::VFSPath,std::nullptr_t,Undefined,MethodInvoker,THeapObjectHolder>;
|
||||
class TRootEnvironment;
|
||||
class GC;
|
||||
class GC {
|
||||
@ -842,7 +843,6 @@ class GC {
|
||||
bool canRegisterDictionary;
|
||||
bool canRegisterJSON;
|
||||
bool canRegisterCrypto;
|
||||
bool canRegisterSDL2;
|
||||
bool canRegisterRoot;
|
||||
bool canRegisterProcess;
|
||||
bool canRegisterPath;
|
||||
@ -889,7 +889,6 @@ class GC {
|
||||
static void RegisterDictionary(GC* gc, TRootEnvironment* env);
|
||||
static void RegisterJson(GC* gc, TRootEnvironment* env);
|
||||
static void RegisterCrypto(GC* gc,TRootEnvironment* env);
|
||||
static void RegisterSDL2(GC* gc, TRootEnvironment* env);
|
||||
static void RegisterRoot(GC* gc, TRootEnvironment* env);
|
||||
static void RegisterPath(GC* gc, TRootEnvironment* env);
|
||||
static void RegisterOGC(GC* gc, TRootEnvironment* env);
|
||||
@ -1436,6 +1435,13 @@ class GC {
|
||||
}
|
||||
bool GetObjectAsPath(TObject& obj, Tesses::Framework::Filesystem::VFSPath& path, bool allowString=true);
|
||||
bool GetArgumentAsPath(std::vector<TObject>& args, size_t index, Tesses::Framework::Filesystem::VFSPath& path,bool allowString=true);
|
||||
typedef void (*PluginFunction)(GC* gc,TRootEnvironment* env);
|
||||
#if !defined(_WIN32)
|
||||
#define DLLEXPORT
|
||||
#else
|
||||
#define DLLEXPORT __declspec(dllexport)
|
||||
#endif
|
||||
#define CROSSLANG_PLUGIN(plugin) DLLEXPORT extern "C" void CrossLangPluginInit(GC* gc, TRootEnvironment* env) { plugin(gc,env); }
|
||||
|
||||
|
||||
void LoadPlugin(GC* gc, TRootEnvironment* env, Tesses::Framework::Filesystem::VFSPath sharedObjectPath);
|
||||
};
|
||||
@ -451,8 +451,7 @@ namespace Tesses::CrossLang
|
||||
}
|
||||
else
|
||||
{
|
||||
Flush();
|
||||
Symbol({read});
|
||||
buffer.push_back('$');
|
||||
}
|
||||
break;
|
||||
case '\"':
|
||||
@ -529,7 +528,6 @@ namespace Tesses::CrossLang
|
||||
while(true)
|
||||
{
|
||||
int r = Read();
|
||||
std::cout << r <<std::endl;
|
||||
lineInfo.Add(r);
|
||||
if(r == -1)
|
||||
{
|
||||
|
||||
@ -32,7 +32,7 @@ namespace Tesses::CrossLang
|
||||
mbedtls_entropy_init(&entropy);
|
||||
mbedtls_ctr_drbg_init(&ctr_drbg);
|
||||
|
||||
int ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) "personalization_string", strlen("personalization_string"));
|
||||
int ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) personalStr.c_str(), personalStr.size());
|
||||
if(ret != 0)
|
||||
{
|
||||
mbedtls_ctr_drbg_free(&ctr_drbg);
|
||||
@ -290,30 +290,10 @@ namespace Tesses::CrossLang
|
||||
static TObject Crypto_Base64Encode(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
TByteArray* byteArray;
|
||||
int64_t offset;
|
||||
int64_t length;
|
||||
if(GetArgumentHeap(args,0,byteArray) && GetArgument(args,1,offset) && GetArgument(args,2,length))
|
||||
|
||||
if(GetArgumentHeap(args,0,byteArray))
|
||||
{
|
||||
std::string str={};
|
||||
size_t olen;
|
||||
size_t off = (size_t)offset;
|
||||
size_t len = (size_t)length;
|
||||
len = std::min(std::min(byteArray->data.size(),len-off),len);
|
||||
|
||||
if(len > 0)
|
||||
{
|
||||
|
||||
mbedtls_base64_encode((uint8_t*)str.data(), 0, &olen, byteArray->data.data()+offset,len);
|
||||
str.resize(olen);
|
||||
|
||||
|
||||
if(mbedtls_base64_encode((uint8_t*)str.data(), olen, &olen, byteArray->data.data()+offset,len)==0)
|
||||
{
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return Tesses::Framework::Crypto::Base64_Encode(byteArray->data);
|
||||
|
||||
|
||||
}
|
||||
@ -324,23 +304,13 @@ namespace Tesses::CrossLang
|
||||
std::string str;
|
||||
if(GetArgument(args,0,str))
|
||||
{
|
||||
size_t olen;
|
||||
|
||||
TByteArray* bArray = TByteArray::Create(ls);
|
||||
bArray->data = Tesses::Framework::Crypto::Base64_Decode(str);
|
||||
|
||||
|
||||
mbedtls_base64_decode(bArray->data.data(), 0, &olen, (const uint8_t*)str.data(),str.size());
|
||||
str.resize(olen);
|
||||
|
||||
|
||||
if(mbedtls_base64_decode(bArray->data.data(), olen, &olen, (const uint8_t*)str.data(),str.size())==0)
|
||||
{
|
||||
return str;
|
||||
}
|
||||
|
||||
return bArray;
|
||||
|
||||
}
|
||||
return "";
|
||||
return nullptr;
|
||||
}
|
||||
#endif
|
||||
void TStd::RegisterCrypto(GC* gc,TRootEnvironment* env)
|
||||
|
||||
@ -206,8 +206,60 @@ namespace Tesses::CrossLang
|
||||
return nullptr;
|
||||
});
|
||||
// dict->DeclareFunction(gc,"getUrlWithQuery","Get original path with query parameters",{},[ctx](Tesses::CrossLang::GCList &ls2, std::vector<Tesses::CrossLang::TObject> args2)->TObject {return ctx->GetUrlWithQuery();});
|
||||
dict->DeclareFunction(gc,"StartWebSocketSession","Start websocket session",{"dict"}, [ctx](GCList& ls,std::vector<TObject> args)->TObject {
|
||||
TDictionary* dict;
|
||||
if(GetArgumentHeap(args,0,dict))
|
||||
{
|
||||
|
||||
|
||||
ctx->StartWebSocketSession([dict,&ls](std::function<void(WebSocketMessage&)> sendMessage,std::function<void()> ping)->void{
|
||||
GCList ls2(ls.GetGC());
|
||||
dict->CallMethod(ls2,"Open",{
|
||||
TExternalMethod::Create(ls2,"Send a message",{"messageTextOrByteArray"},[sendMessage](GCList& ls,std::vector<TObject> args)->TObject{
|
||||
std::string str;
|
||||
TByteArray* bArray;
|
||||
if(GetArgument(args,0,str))
|
||||
{
|
||||
WebSocketMessage msg(str);
|
||||
sendMessage(msg);
|
||||
}
|
||||
else if(GetArgumentHeap(args,0,bArray))
|
||||
{
|
||||
WebSocketMessage msg(bArray->data);
|
||||
sendMessage(msg);
|
||||
}
|
||||
return nullptr;
|
||||
}),
|
||||
TExternalMethod::Create(ls2, "Ping client", {},[ping](GCList& ls,std::vector<TObject> args)->TObject {
|
||||
ping();
|
||||
return nullptr;
|
||||
})
|
||||
});
|
||||
}, [dict,&ls](WebSocketMessage& msg)->void {
|
||||
GCList ls2(ls.GetGC());
|
||||
|
||||
TObject v;
|
||||
|
||||
if(msg.isBinary)
|
||||
{
|
||||
auto r = TByteArray::Create(ls2);
|
||||
r->data = msg.data;
|
||||
v = r;
|
||||
}
|
||||
else
|
||||
{
|
||||
v = msg.ToString();
|
||||
}
|
||||
|
||||
dict->CallMethod(ls2,"Receive",{v});
|
||||
}, [dict,&ls](bool close)->void {
|
||||
GCList ls2(ls.GetGC());
|
||||
dict->CallMethod(ls2,"Close",{close});
|
||||
});
|
||||
}
|
||||
return nullptr;
|
||||
});
|
||||
|
||||
//dict->DeclareFunction(gc,"getOriginalPathWithQuery","Get original path with query parameters",{},[ctx](Tesses::CrossLang::GCList &ls2, std::vector<Tesses::CrossLang::TObject> args2)->TObject {return ctx->GetOriginalPathWithQuery();});
|
||||
dict->DeclareFunction(gc,"getPath","Get path",{},[ctx](Tesses::CrossLang::GCList &ls2, std::vector<Tesses::CrossLang::TObject> args2)->TObject {return ctx->path;});
|
||||
dict->DeclareFunction(gc,"setPath","Set path",{},[ctx](Tesses::CrossLang::GCList &ls2, std::vector<Tesses::CrossLang::TObject> args2)->TObject {
|
||||
@ -247,6 +299,7 @@ namespace Tesses::CrossLang
|
||||
TObjectHttpServer::TObjectHttpServer(GC* gc,TObject obj)
|
||||
{
|
||||
this->ls=new GCList(gc);
|
||||
this->ls->Add(obj);
|
||||
this->obj = obj;
|
||||
}
|
||||
|
||||
@ -550,7 +603,28 @@ namespace Tesses::CrossLang
|
||||
//http->DeclareFunction(gc, "ProcessServer","Process HTTP server connection",{"networkstream","server","ip","port","encrypted"},, Net_ProcessServer);
|
||||
http->DeclareFunction(gc, "MakeRequest", "Create an http request", {"url","$extra"}, Net_Http_MakeRequest);
|
||||
http->DeclareFunction(gc, "ListenSimpleWithLoop", "Listen (creates application loop)", {"server","port"},Net_Http_ListenSimpleWithLoop);
|
||||
//FileServer svr()
|
||||
http->DeclareFunction(gc, "FileServer","Create a file server",{"path","allowlisting","spa"}, [](GCList& ls, std::vector<TObject> args)->TObject{
|
||||
|
||||
bool allowlisting;
|
||||
bool spa;
|
||||
if(GetArgument(args,1,allowlisting) && GetArgument(args,2,spa))
|
||||
{
|
||||
auto fserver = new FileServer(new TObjectVFS(ls.GetGC(),args[0]),true,allowlisting,spa);
|
||||
return TServerHeapObject::Create(ls,fserver);
|
||||
}
|
||||
return nullptr;
|
||||
});
|
||||
http->DeclareFunction(gc, "MountableServer","Create a server you can mount to, must mount parents before child",{"root"}, [](GCList& ls, std::vector<TObject> args)->TObject{
|
||||
if(args.size() > 0)
|
||||
{
|
||||
auto svr = new TObjectHttpServer(ls.GetGC(), args[0]);
|
||||
auto svr2 = new MountableServer(svr,true);
|
||||
|
||||
return TServerHeapObject::Create(ls,svr2);
|
||||
}
|
||||
return nullptr;
|
||||
});
|
||||
dict->DeclareFunction(gc, "NetworkStream","Create a network stream",{"ipv6","datagram"},Net_NetworkStream);
|
||||
gc->BarrierBegin();
|
||||
dict->SetValue("Http", http);
|
||||
|
||||
@ -1,281 +0,0 @@
|
||||
#include "CrossLang.hpp"
|
||||
#if defined(CROSSLANG_ENABLE_SDL2)
|
||||
#include <SDL2/SDL.h>
|
||||
#endif
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
#if defined(CROSSLANG_ENABLE_SDL2)
|
||||
static void TObjectToRect(TDictionary* dict, SDL_Rect& rect)
|
||||
{
|
||||
|
||||
int64_t number;
|
||||
auto obj = dict->GetValue("x");
|
||||
if(GetObject(obj,number)) rect.x = (int)number;
|
||||
obj = dict->GetValue("y");
|
||||
if(GetObject(obj,number)) rect.y = (int)number;
|
||||
obj = dict->GetValue("w");
|
||||
if(GetObject(obj,number)) rect.w = (int)number;
|
||||
obj = dict->GetValue("h");
|
||||
if(GetObject(obj,number)) rect.h = (int)number;
|
||||
|
||||
}
|
||||
|
||||
static TObject SDL2_RenderDrawRect(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
TNative* nat;
|
||||
TDictionary* dict;
|
||||
if(GetArgumentHeap(args,0, nat) && GetArgumentHeap(args,1,dict))
|
||||
{
|
||||
SDL_Rect rect;
|
||||
TObjectToRect(dict,rect);
|
||||
return (int64_t)SDL_RenderDrawRect((SDL_Renderer*)nat->GetPointer(), &rect);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
static TObject SDL2_RenderFillRect(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
TNative* nat;
|
||||
TDictionary* dict;
|
||||
if(GetArgumentHeap(args,0, nat) && GetArgumentHeap(args,1,dict))
|
||||
{
|
||||
SDL_Rect rect;
|
||||
TObjectToRect(dict,rect);
|
||||
return (int64_t)SDL_RenderFillRect((SDL_Renderer*)nat->GetPointer(), &rect);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
static TObject SDL2_PollEvent(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
SDL_Event event;
|
||||
if(SDL_PollEvent(&event))
|
||||
{
|
||||
TDictionary* dict = TDictionary::Create(ls);
|
||||
ls.GetGC()->BarrierBegin();
|
||||
dict->SetValue("Type",(int64_t)event.common.type);
|
||||
dict->SetValue("Timestamp",(int64_t)event.common.timestamp);
|
||||
switch(event.type)
|
||||
{
|
||||
case SDL_DROPBEGIN:
|
||||
case SDL_DROPCOMPLETE:
|
||||
|
||||
dict->SetValue("WindowId",(int64_t)event.drop.windowID);
|
||||
break;
|
||||
case SDL_DROPFILE:
|
||||
dict->SetValue("File", Tesses::Framework::Filesystem::VFSPath(std::string(event.drop.file)));
|
||||
SDL_free(event.drop.file);
|
||||
break;
|
||||
case SDL_DROPTEXT:
|
||||
dict->SetValue("WindowId",(int64_t)event.drop.windowID);
|
||||
dict->SetValue("Text", std::string(event.drop.file));
|
||||
SDL_free(event.drop.file);
|
||||
break;
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
dict->SetValue("WindowId",(int64_t)event.button.windowID);
|
||||
dict->SetValue("Which",(int64_t)event.button.which);
|
||||
dict->SetValue("Button",(int64_t)event.button.button);
|
||||
dict->SetValue("State",(int64_t)event.button.state);
|
||||
dict->SetValue("Clicks",(int64_t)event.button.clicks);
|
||||
dict->SetValue("X",(int64_t)event.button.x);
|
||||
dict->SetValue("Y",(int64_t)event.button.y);
|
||||
break;
|
||||
case SDL_MOUSEMOTION:
|
||||
dict->SetValue("WindowId",(int64_t)event.motion.windowID);
|
||||
dict->SetValue("Which",(int64_t)event.motion.which);
|
||||
dict->SetValue("State",(int64_t)event.motion.state);
|
||||
dict->SetValue("X",(int64_t)event.motion.x);
|
||||
dict->SetValue("Y",(int64_t)event.motion.y);
|
||||
dict->SetValue("XRel",(int64_t)event.motion.xrel);
|
||||
dict->SetValue("YRel",(int64_t)event.motion.yrel);
|
||||
break;
|
||||
case SDL_MOUSEWHEEL:
|
||||
dict->SetValue("Direction", (int64_t)event.wheel.direction);
|
||||
dict->SetValue("MouseX",(int64_t)event.wheel.mouseX);
|
||||
dict->SetValue("MouseY",(int64_t)event.wheel.mouseY);
|
||||
dict->SetValue("PreciseX",(double)event.wheel.preciseX);
|
||||
dict->SetValue("PreciseY",(double)event.wheel.preciseY);
|
||||
dict->SetValue("Which",(int64_t)event.wheel.which);
|
||||
dict->SetValue("WindowId",(int64_t)event.wheel.windowID);
|
||||
dict->SetValue("X",(int64_t)event.wheel.x);
|
||||
dict->SetValue("Y",(int64_t)event.wheel.y);
|
||||
break;
|
||||
case SDL_KEYUP:
|
||||
case SDL_KEYDOWN:
|
||||
dict->SetValue("WindowId",(int64_t)event.key.windowID);
|
||||
dict->SetValue("Repeat",(int64_t)event.key.repeat);
|
||||
dict->SetValue("State",(int64_t)event.key.state);
|
||||
{
|
||||
TDictionary* dict2=TDictionary::Create(ls);
|
||||
dict2->SetValue("Mod",(int64_t)event.key.keysym.mod);
|
||||
dict2->SetValue("Scancode",(int64_t)event.key.keysym.scancode);
|
||||
dict2->SetValue("Sym",(int64_t)event.key.keysym.sym);
|
||||
dict->SetValue("Keysym",dict2);
|
||||
}
|
||||
break;
|
||||
case SDL_EventType::SDL_FINGERMOTION:
|
||||
dict->SetValue("Dx",event.tfinger.dx);
|
||||
dict->SetValue("Dy",event.tfinger.dy);
|
||||
//falls into SDL_FINGERUP/DOWN due to having same props
|
||||
case SDL_EventType::SDL_FINGERUP:
|
||||
case SDL_EventType::SDL_FINGERDOWN:
|
||||
dict->SetValue("X",event.tfinger.x);
|
||||
dict->SetValue("Y",event.tfinger.y);
|
||||
|
||||
dict->SetValue("FingerId",(int64_t)event.tfinger.fingerId);
|
||||
|
||||
dict->SetValue("Pressure",event.tfinger.pressure);
|
||||
|
||||
dict->SetValue("TouchId",(int64_t)event.tfinger.touchId);
|
||||
|
||||
dict->SetValue("WindowId",(int64_t)event.tfinger.windowID);
|
||||
break;
|
||||
case SDL_EventType::SDL_TEXTINPUT:
|
||||
dict->SetValue("Text",event.text.text);
|
||||
dict->SetValue("WindowId",(int64_t)event.text.windowID);
|
||||
break;
|
||||
case SDL_EventType::SDL_TEXTEDITING:
|
||||
dict->SetValue("Text",event.edit.text);
|
||||
dict->SetValue("Length",(int64_t)event.edit.length);
|
||||
dict->SetValue("Start",(int64_t)event.edit.start);
|
||||
dict->SetValue("WindowId",(int64_t)event.edit.windowID);
|
||||
break;
|
||||
case SDL_EventType::SDL_TEXTEDITING_EXT:
|
||||
{
|
||||
dict->SetValue("Text",event.editExt.text);
|
||||
dict->SetValue("Length",(int64_t)event.editExt.length);
|
||||
dict->SetValue("Start",(int64_t)event.editExt.start);
|
||||
dict->SetValue("WindowId",(int64_t)event.editExt.windowID);
|
||||
SDL_free(event.editExt.text);
|
||||
}
|
||||
break;
|
||||
case SDL_EventType::SDL_WINDOWEVENT:
|
||||
{
|
||||
dict->SetValue("WindowId",(int64_t)event.window.windowID);
|
||||
dict->SetValue("Event",(int64_t)event.window.event);
|
||||
dict->SetValue("Data1",(int64_t)event.window.data1);
|
||||
dict->SetValue("Data2",(int64_t)event.window.data2);
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return dict;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
static TObject SDL2_RenderPresent(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
TNative* renderer;
|
||||
if(GetArgumentHeap<TNative*>(args,0,renderer) && !renderer->GetDestroyed())
|
||||
{
|
||||
SDL_RenderPresent((SDL_Renderer*)renderer->GetPointer());
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
static TObject SDL2_RenderClear(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
TNative* renderer;
|
||||
if(GetArgumentHeap<TNative*>(args,0,renderer) && !renderer->GetDestroyed())
|
||||
{
|
||||
return SDL_RenderClear((SDL_Renderer*)renderer->GetPointer())==0;
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
static TObject SDL2_SetRenderDrawColor(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
TNative* renderer;
|
||||
int64_t r;
|
||||
int64_t g;
|
||||
int64_t b;
|
||||
int64_t a;
|
||||
if(GetArgumentHeap<TNative*>(args,0,renderer) && !renderer->GetDestroyed() && GetArgument<int64_t>(args,1,r) && GetArgument<int64_t>(args,2,g) && GetArgument<int64_t>(args,3,b) && GetArgument<int64_t>(args,4,a))
|
||||
{
|
||||
return SDL_SetRenderDrawColor((SDL_Renderer*)renderer->GetPointer(),(Uint8)r,(Uint8)g,(Uint8)b,(Uint8)a) == 0;
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
|
||||
static TObject SDL2_Init(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
return (int64_t)SDL_Init(SDL_INIT_EVERYTHING);
|
||||
|
||||
}
|
||||
|
||||
|
||||
static TObject SDL2_CreateRenderer(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
TNative* window;
|
||||
int64_t index;
|
||||
int64_t flags;
|
||||
if(GetArgumentHeap<TNative*>(args,0,window) && !window->GetDestroyed() && GetArgument<int64_t>(args,1,index) && GetArgument<int64_t>(args,2,flags))
|
||||
{
|
||||
SDL_Renderer* _renderer= SDL_CreateRenderer((SDL_Window*)window->GetPointer(),(int)index, (Uint32)flags);
|
||||
if(_renderer == nullptr) return nullptr;
|
||||
return TNative::Create(ls,_renderer,[](void* _ptr)-> void{
|
||||
SDL_DestroyRenderer((SDL_Renderer*)_ptr);
|
||||
});
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
static TObject SDL2_CreateWindow(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
if(args.size() == 6 && std::holds_alternative<std::string>(args[0]) && std::holds_alternative<int64_t>(args[1]) && std::holds_alternative<int64_t>(args[2]) && std::holds_alternative<int64_t>(args[3]) && std::holds_alternative<int64_t>(args[4]) && std::holds_alternative<int64_t>(args[5]))
|
||||
{
|
||||
SDL_Window* window = SDL_CreateWindow(std::get<std::string>(args[0]).c_str(),(int)std::get<int64_t>(args[1]),(int)std::get<int64_t>(args[2]),(int)std::get<int64_t>(args[3]),(int)std::get<int64_t>(args[4]),(uint32_t)std::get<int64_t>(args[5]));
|
||||
if(window == nullptr) return nullptr;
|
||||
|
||||
return TNative::Create(ls,window,[](void* _ptr)->void {
|
||||
SDL_Window* win = (SDL_Window*)_ptr;
|
||||
if(win != nullptr) SDL_DestroyWindow(win);
|
||||
});
|
||||
}
|
||||
return Undefined();
|
||||
}
|
||||
#endif
|
||||
void TStd::RegisterSDL2(GC* gc, TRootEnvironment* env)
|
||||
{
|
||||
|
||||
env->permissions.canRegisterSDL2=true;
|
||||
#if defined(CROSSLANG_ENABLE_SDL2)
|
||||
GCList ls(gc);
|
||||
TDictionary* dict = TDictionary::Create(ls);
|
||||
dict->DeclareFunction(gc, "RenderDrawRect","Draw a rectangle using SDL",{"renderer","dictionary_with_x_y_w_h"}, SDL2_RenderDrawRect);
|
||||
dict->DeclareFunction(gc, "RenderFillRect","Fill a rectangle using SDL",{"renderer","dictionary_with_x_y_w_h"}, SDL2_RenderFillRect);
|
||||
dict->DeclareFunction(gc, "RenderPresent","Present frame (you are finished with the frame)",{"renderer"},SDL2_RenderPresent);
|
||||
dict->DeclareFunction(gc, "RenderClear","Clear renderer with renderer draw color",{"renderer"},SDL2_RenderClear);
|
||||
dict->DeclareFunction(gc, "SetRenderDrawColor","Set SDL2 Renderer Draw Color",{"renderer","r","g","b","a"},SDL2_SetRenderDrawColor);
|
||||
dict->DeclareFunction(gc, "CreateWindow","Create a SDL2 Window",{"title","x","y","w","h","flags"},SDL2_CreateWindow);
|
||||
dict->DeclareFunction(gc, "CreateRenderer","Create a SDL2 Renderer",{"window",""},SDL2_CreateRenderer);
|
||||
dict->DeclareFunction(gc, "PollEvent", "Get events",{},SDL2_PollEvent);
|
||||
dict->DeclareFunction(gc, "Init", "Init SDL2",{},SDL2_Init);
|
||||
|
||||
|
||||
gc->BarrierBegin();
|
||||
dict->SetValue("DROPBEGIN",(int64_t)SDL_DROPBEGIN);
|
||||
dict->SetValue("DROPCOMPLETE",(int64_t)SDL_DROPCOMPLETE);
|
||||
dict->SetValue("DROPFILE",(int64_t)SDL_DROPFILE);
|
||||
dict->SetValue("DROPTEXT",(int64_t)SDL_DROPTEXT);
|
||||
dict->SetValue("MOUSEBUTTONUP",(int64_t)SDL_MOUSEBUTTONUP);
|
||||
dict->SetValue("MOUSEBUTTONDOWN",(int64_t)SDL_MOUSEBUTTONDOWN);
|
||||
dict->SetValue("MOUSEMOTION",(int64_t)SDL_MOUSEMOTION);
|
||||
dict->SetValue("KEYUP",(int64_t)SDL_KEYUP);
|
||||
dict->SetValue("KEYDOWN",(int64_t)SDL_KEYDOWN);
|
||||
dict->SetValue("FINGERMOTION",(int64_t)SDL_FINGERMOTION);
|
||||
dict->SetValue("FINGERUP",(int64_t)SDL_FINGERUP);
|
||||
dict->SetValue("FINGERDOWN",(int64_t)SDL_FINGERDOWN);
|
||||
dict->SetValue("TEXTINPUT",(int64_t)SDL_TEXTINPUT);
|
||||
dict->SetValue("TEXTEDITING",(int64_t)SDL_TEXTEDITING);
|
||||
dict->SetValue("TEXTEDITING_EXT",(int64_t)SDL_TEXTEDITING_EXT);
|
||||
dict->SetValue("WINDOWEVENT",(int64_t)SDL_WINDOWEVENT);
|
||||
dict->SetValue("QUIT",(int64_t)SDL_QUIT);
|
||||
|
||||
dict->SetValue("WINDOW_RESIZABLE",(int64_t)SDL_WINDOW_RESIZABLE);
|
||||
dict->SetValue("WINDOW_BORDERLESS",(int64_t)SDL_WINDOW_BORDERLESS);
|
||||
dict->SetValue("WINDOW_FULLSCREEN",(int64_t)SDL_WINDOW_FULLSCREEN);
|
||||
dict->SetValue("WINDOW_MAXIMIZED",(int64_t)SDL_WINDOW_MAXIMIZED);
|
||||
env->DeclareVariable("SDL2", dict);
|
||||
gc->BarrierEnd();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -39,7 +39,6 @@ namespace Tesses::CrossLang {
|
||||
std::string name = p.ToString();
|
||||
|
||||
sqlite3* sqlite;
|
||||
std::cout << name << std::endl;
|
||||
int rc =sqlite3_open(name.c_str(),&sqlite);
|
||||
if(rc)
|
||||
{
|
||||
|
||||
@ -1,7 +1,61 @@
|
||||
#include "CrossLang.hpp"
|
||||
|
||||
#if defined(CROSSLANG_ENABLE_SHARED)
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
#endif
|
||||
namespace Tesses::CrossLang
|
||||
{
|
||||
#if defined(CROSSLANG_ENABLE_SHARED)
|
||||
class DL {
|
||||
void* handle;
|
||||
public:
|
||||
DL(Tesses::Framework::Filesystem::VFSPath p)
|
||||
{
|
||||
Tesses::Framework::Filesystem::LocalFilesystem lfs;
|
||||
std::string str = lfs.VFSPathToSystem(p);
|
||||
#if defined(_WIN32)
|
||||
handle = LoadLibraryExA(str.c_str() , NULL, LOAD_WITH_ALTERED_SEARCH_PATH );
|
||||
#else
|
||||
handle = dlopen(str.c_str(), RTLD_LAZY);
|
||||
#endif
|
||||
}
|
||||
template<typename T>
|
||||
T Resolve(std::string name)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return (T)GetProcAddress(handle,name.c_str());
|
||||
#else
|
||||
return (T)dlsym(handle,name.c_str());
|
||||
|
||||
#endif
|
||||
}
|
||||
~DL()
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
FreeLibrary(handle);
|
||||
#else
|
||||
dlclose(handle);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
void LoadPlugin(GC* gc, TRootEnvironment* env, Tesses::Framework::Filesystem::VFSPath sharedObjectPath)
|
||||
{
|
||||
#if defined(CROSSLANG_ENABLE_SHARED)
|
||||
auto ptr = std::make_shared<DL>(sharedObjectPath);
|
||||
auto cb = ptr->Resolve<PluginFunction>("CrossLangPluginInit");
|
||||
if(cb == nullptr) return;
|
||||
gc->RegisterEverythingCallback([ptr,cb](GC* gc, TRootEnvironment* env)-> void{
|
||||
cb(gc,env);
|
||||
});
|
||||
cb(gc,env);
|
||||
#endif
|
||||
}
|
||||
|
||||
static TObject TypeIsDefined(GCList& ls,std::vector<TObject> args)
|
||||
{
|
||||
if(args.empty()) return nullptr;
|
||||
@ -67,6 +121,7 @@ namespace Tesses::CrossLang
|
||||
static TObject TypeOf(GCList& ls, std::vector<TObject> args)
|
||||
{
|
||||
if(args.size() < 1) return "Undefined";
|
||||
if(std::holds_alternative<std::regex>(args[0])) return "Regex";
|
||||
if(std::holds_alternative<Undefined>(args[0])) return "Undefined";
|
||||
if(std::holds_alternative<std::nullptr_t>(args[0])) return "Null";
|
||||
if(std::holds_alternative<bool>(args[0])) return "Boolean";
|
||||
@ -91,6 +146,7 @@ namespace Tesses::CrossLang
|
||||
auto native = dynamic_cast<TNative*>(obj);
|
||||
auto vfs = dynamic_cast<TVFSHeapObject*>(obj);
|
||||
auto strm = dynamic_cast<TStreamHeapObject*>(obj);
|
||||
auto svr = dynamic_cast<TServerHeapObject*>(obj);
|
||||
if(dynDict != nullptr) return "DynamicDictionary";
|
||||
if(dynList != nullptr) return "DynamicList";
|
||||
if(strm != nullptr)
|
||||
@ -104,6 +160,20 @@ namespace Tesses::CrossLang
|
||||
|
||||
return "Stream";
|
||||
}
|
||||
if(svr != nullptr)
|
||||
{
|
||||
auto fileServer = dynamic_cast<Tesses::Framework::Http::FileServer*>(svr->server);
|
||||
auto mountableServer = dynamic_cast<Tesses::Framework::Http::MountableServer*>(svr->server);
|
||||
if(fileServer != nullptr)
|
||||
{
|
||||
return "FileServer";
|
||||
}
|
||||
if(mountableServer != nullptr)
|
||||
{
|
||||
return "MountableServer";
|
||||
}
|
||||
return "HttpServer";
|
||||
}
|
||||
if(vfs != nullptr)
|
||||
{
|
||||
auto localVFS = dynamic_cast<Tesses::Framework::Filesystem::LocalFilesystem*>(vfs->vfs);
|
||||
@ -127,6 +197,7 @@ namespace Tesses::CrossLang
|
||||
if(byteArray != nullptr) return "ByteArray";
|
||||
if(native != nullptr) return "Native";
|
||||
|
||||
|
||||
return "HeapObject";
|
||||
}
|
||||
|
||||
@ -222,7 +293,6 @@ namespace Tesses::CrossLang
|
||||
this->canRegisterPath=false;
|
||||
this->canRegisterProcess=false;
|
||||
this->canRegisterRoot=false;
|
||||
this->canRegisterSDL2=false;
|
||||
this->canRegisterSqlite=false;
|
||||
this->canRegisterVM = false;
|
||||
this->locked=false;
|
||||
@ -250,7 +320,59 @@ namespace Tesses::CrossLang
|
||||
env->DeclareFunction(gc, "TypeIsVFS","Get whether object is a virtual filesystem",{"object"},TypeIsVFS);
|
||||
|
||||
|
||||
env->DeclareFunction(gc, "Regex", "Create regex object",{"regex"},[](GCList& ls,std::vector<TObject> args)->TObject {
|
||||
std::string str;
|
||||
if(GetArgument(args,0,str))
|
||||
{
|
||||
std::regex regex(str);
|
||||
return regex;
|
||||
}
|
||||
return nullptr;
|
||||
});
|
||||
env->DeclareFunction(gc, "Mutex", "Create mutex",{}, [](GCList& ls,std::vector<TObject> args)->TObject {
|
||||
ls.GetGC()->BarrierBegin();
|
||||
auto mtx = TDictionary::Create(ls);
|
||||
auto native = TNative::Create(ls, new Tesses::Framework::Threading::Mutex(),[](void* ptr)->void{
|
||||
delete static_cast<Tesses::Framework::Threading::Mutex*>(ptr);
|
||||
});
|
||||
auto lock = TExternalMethod::Create(ls,"Lock the mutex",{},[native](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
if(native->GetDestroyed()) return nullptr;
|
||||
auto r = static_cast<Tesses::Framework::Threading::Mutex*>(native->GetPointer());
|
||||
r->Lock();
|
||||
return nullptr;
|
||||
});
|
||||
lock->watch.push_back(native);
|
||||
mtx->SetValue("Lock",lock);
|
||||
|
||||
auto unlock = TExternalMethod::Create(ls,"Unlock the mutex",{},[native](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
if(native->GetDestroyed()) return nullptr;
|
||||
auto r = static_cast<Tesses::Framework::Threading::Mutex*>(native->GetPointer());
|
||||
r->Unlock();
|
||||
return nullptr;
|
||||
});
|
||||
unlock->watch.push_back(native);
|
||||
mtx->SetValue("Unlock",unlock);
|
||||
|
||||
|
||||
auto trylock = TExternalMethod::Create(ls,"Try to lock the mutex, returns true if we aquire the lock, false if we can't due to another thread owning it",{},[native](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
if(native->GetDestroyed()) return true;
|
||||
auto r = static_cast<Tesses::Framework::Threading::Mutex*>(native->GetPointer());
|
||||
return r->TryLock();
|
||||
});
|
||||
trylock->watch.push_back(native);
|
||||
mtx->SetValue("TryLock",trylock);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
|
||||
|
||||
auto close = TExternalMethod::Create(ls,"Try to lock the mutex, returns true if we aquire the lock, false if we can't due to another thread owning it",{},[native](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
native->Destroy();
|
||||
return nullptr;
|
||||
});
|
||||
close->watch.push_back(native);
|
||||
mtx->SetValue("Close",close);
|
||||
ls.GetGC()->BarrierEnd();
|
||||
return mtx;
|
||||
});
|
||||
env->DeclareFunction(gc, "Thread","Create thread",{"callback"},[](GCList& ls, std::vector<TObject> args)-> TObject
|
||||
{
|
||||
if(args.size() == 1 && std::holds_alternative<THeapObjectHolder>(args[0]))
|
||||
@ -282,7 +404,6 @@ namespace Tesses::CrossLang
|
||||
RegisterJson(gc, env);
|
||||
RegisterDictionary(gc, env);
|
||||
RegisterCrypto(gc,env);
|
||||
RegisterSDL2(gc, env);
|
||||
RegisterOGC(gc, env);
|
||||
RegisterProcess(gc,env);
|
||||
|
||||
@ -291,6 +412,14 @@ namespace Tesses::CrossLang
|
||||
GCList ls(gc);
|
||||
|
||||
TDictionary* dict = TDictionary::Create(ls);
|
||||
dict->DeclareFunction(gc,"LoadNativePlugin","Load a native plugin, requires a dynamic linker and shared build of libcrosslang",{"path"},[gc,env](GCList& ls, std::vector<TObject> args)->TObject {
|
||||
Tesses::Framework::Filesystem::VFSPath path;
|
||||
if(GetArgumentAsPath(args,0,path))
|
||||
{
|
||||
LoadPlugin(gc,env,path);
|
||||
}
|
||||
return nullptr;
|
||||
});
|
||||
gc->BarrierBegin();
|
||||
env->SetVariable("Reflection",dict);
|
||||
gc->BarrierEnd();
|
||||
|
||||
196
src/vm/vm.cpp
196
src/vm/vm.cpp
@ -1372,7 +1372,42 @@ namespace Tesses::CrossLang {
|
||||
if(!cse.empty())
|
||||
{
|
||||
GCList ls(gc);
|
||||
if(std::holds_alternative<bool>(instance))
|
||||
std::regex regex;
|
||||
if(GetObject(instance,regex))
|
||||
{
|
||||
if(key == "Search")
|
||||
{
|
||||
std::string str;
|
||||
if(GetArgument(args,0,str))
|
||||
{
|
||||
std::smatch m;
|
||||
if(std::regex_search(str,m,regex))
|
||||
{
|
||||
auto myLs = TList::Create(ls);
|
||||
gc->BarrierBegin();
|
||||
for(auto item : m)
|
||||
{
|
||||
auto itm = TDictionary::Create(ls);
|
||||
itm->SetValue("Offset", (int64_t)(item.first-str.begin()));
|
||||
itm->SetValue("Length",(int64_t)item.length());
|
||||
itm->SetValue("Matched",item.matched);
|
||||
itm->SetValue("Text",item.str());
|
||||
myLs->Add(itm);
|
||||
}
|
||||
|
||||
|
||||
cse.back()->Push(gc, myLs);
|
||||
gc->BarrierEnd();
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
cse.back()->Push(gc, nullptr);
|
||||
return false;
|
||||
}
|
||||
else if(std::holds_alternative<bool>(instance))
|
||||
{
|
||||
bool flag = std::get<bool>(instance);
|
||||
if(key == "ToString")
|
||||
@ -1709,8 +1744,23 @@ namespace Tesses::CrossLang {
|
||||
std::string str = std::get<std::string>(instance);
|
||||
if(key == "IndexOf")
|
||||
{
|
||||
char c;
|
||||
if(GetArgument<char>(args,0,c))
|
||||
std::string str2;
|
||||
char c;
|
||||
if(GetArgument(args,0,str2))
|
||||
{
|
||||
|
||||
int64_t index = str.size();
|
||||
GetArgument(args,1,index);
|
||||
|
||||
auto res = str.find(str2,(std::size_t)index);
|
||||
if(res == std::string::npos)
|
||||
cse.back()->Push(gc, (int64_t)-1);
|
||||
else
|
||||
cse.back()->Push(gc, (int64_t)res);
|
||||
return false;
|
||||
}
|
||||
|
||||
else if(GetArgument<char>(args,0,c))
|
||||
{
|
||||
int64_t index = 0;
|
||||
GetArgument(args,1,index);
|
||||
@ -1727,8 +1777,22 @@ namespace Tesses::CrossLang {
|
||||
}
|
||||
if(key == "LastIndexOf")
|
||||
{
|
||||
std::string str2;
|
||||
char c;
|
||||
if(GetArgument<char>(args,0,c))
|
||||
if(GetArgument(args,0,str2))
|
||||
{
|
||||
|
||||
int64_t index = str.size();
|
||||
GetArgument(args,1,index);
|
||||
|
||||
auto res = str.rfind(str2,(std::size_t)index);
|
||||
if(res == std::string::npos)
|
||||
cse.back()->Push(gc, (int64_t)-1);
|
||||
else
|
||||
cse.back()->Push(gc, (int64_t)res);
|
||||
return false;
|
||||
}
|
||||
else if(GetArgument<char>(args,0,c))
|
||||
{
|
||||
int64_t index = str.size();
|
||||
GetArgument(args,1,index);
|
||||
@ -1914,7 +1978,71 @@ namespace Tesses::CrossLang {
|
||||
auto env = dynamic_cast<TEnvironment*>(obj);
|
||||
auto rootEnv = dynamic_cast<TRootEnvironment*>(obj);
|
||||
auto callable = dynamic_cast<TCallable*>(obj);
|
||||
auto svr = dynamic_cast<TServerHeapObject*>(obj);
|
||||
|
||||
if(svr != nullptr)
|
||||
{
|
||||
auto mountable = dynamic_cast<Tesses::Framework::Http::MountableServer*>(svr->server);
|
||||
if(mountable != nullptr)
|
||||
{
|
||||
if(key == "Mount")
|
||||
{
|
||||
Tesses::Framework::Filesystem::VFSPath p;
|
||||
|
||||
if(args.size() > 1 && GetArgumentAsPath(args,0,p))
|
||||
{
|
||||
mountable->Mount(p.ToString(),new TObjectHttpServer(gc,args[1]),true);
|
||||
cse.back()->Push(gc,nullptr);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(key == "Unmount")
|
||||
{
|
||||
Tesses::Framework::Filesystem::VFSPath p;
|
||||
|
||||
if(GetArgumentAsPath(args,0,p))
|
||||
{
|
||||
mountable->Unmount(p.ToString());
|
||||
cse.back()->Push(gc,nullptr);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(key == "Handle")
|
||||
{
|
||||
|
||||
if(GetArgumentHeap(args,0,dict))
|
||||
{
|
||||
gc->BarrierBegin();
|
||||
auto nat = dict->GetValue("native");
|
||||
gc->BarrierEnd();
|
||||
TNative* nat2;
|
||||
if(GetObjectHeap(nat,nat2))
|
||||
{
|
||||
if(!nat2->GetDestroyed())
|
||||
{
|
||||
auto ctx = static_cast<Tesses::Framework::Http::ServerContext*>(nat2->GetPointer());
|
||||
if(ctx != nullptr)
|
||||
{
|
||||
cse.back()->Push(gc,svr->server->Handle(*ctx));
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
cse.back()->Push(gc,false);
|
||||
return false;
|
||||
}
|
||||
if(key == "Close")
|
||||
{
|
||||
svr->Close();
|
||||
cse.back()->Push(gc, nullptr);
|
||||
return false;
|
||||
}
|
||||
cse.back()->Push(gc,Undefined());
|
||||
return false;
|
||||
}
|
||||
if(rootEnv != nullptr)
|
||||
{
|
||||
//TStd::RegisterCrypto
|
||||
@ -1968,8 +2096,6 @@ namespace Tesses::CrossLang {
|
||||
if(myEnv->permissions.canRegisterRoot && !rootEnv->permissions.locked)
|
||||
TStd::RegisterRoot(gc, rootEnv);
|
||||
|
||||
if(myEnv->permissions.canRegisterSDL2 && !rootEnv->permissions.locked)
|
||||
TStd::RegisterSDL2(gc, rootEnv);
|
||||
|
||||
if(myEnv->permissions.canRegisterSqlite && !rootEnv->permissions.locked)
|
||||
TStd::RegisterSqlite(gc, rootEnv);
|
||||
@ -2066,13 +2192,6 @@ namespace Tesses::CrossLang {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(key == "RegisterSDL2")
|
||||
{
|
||||
if((myEnv->permissions.canRegisterEverything || myEnv->permissions.canRegisterSDL2) && !rootEnv->permissions.locked)
|
||||
TStd::RegisterSDL2(gc, rootEnv);
|
||||
cse.back()->Push(gc,nullptr);
|
||||
return false;
|
||||
}
|
||||
if(key == "RegisterSqlite")
|
||||
{
|
||||
if((myEnv->permissions.canRegisterEverything || myEnv->permissions.canRegisterSqlite) && !rootEnv->permissions.locked)
|
||||
@ -4457,10 +4576,57 @@ namespace Tesses::CrossLang {
|
||||
}
|
||||
else
|
||||
{
|
||||
for(size_t i = 0; i < std::min(args.size(),closure->closure->args.size()); i++)
|
||||
auto requiredArguments = [closure]()->size_t
|
||||
{
|
||||
cse->env->DeclareVariable(closure->closure->args[i], args[i]);
|
||||
for(size_t i =0;i<closure->closure->args.size();i++)
|
||||
{
|
||||
if(closure->closure->args[i].find("$") == 0)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return closure->closure->args.size();
|
||||
};
|
||||
auto optionalArguments = [closure](size_t argLen)->size_t
|
||||
{
|
||||
for(size_t i =0;i<closure->closure->args.size();i++)
|
||||
{
|
||||
if(closure->closure->args[i].find("$$") == 0)
|
||||
{
|
||||
return std::min(argLen,i);
|
||||
}
|
||||
}
|
||||
return std::min(argLen,closure->closure->args.size());
|
||||
};
|
||||
auto trimStart = [](std::string txt)->std::string {
|
||||
if(txt.empty()) return {};
|
||||
if(txt[0] != '$') return txt;
|
||||
auto idx = txt.find_first_not_of('$');
|
||||
if(idx == std::string::npos) return {};
|
||||
return txt.substr(idx);
|
||||
};
|
||||
size_t required = requiredArguments();
|
||||
|
||||
if(args.size() < requiredArguments())
|
||||
{
|
||||
throw VMException("Called a function that expected at least " + std::to_string(required) + " args but got " + std::to_string(args.size()));
|
||||
}
|
||||
|
||||
size_t i;
|
||||
for( i = 0; i < optionalArguments(args.size()); i++)
|
||||
{
|
||||
cse->env->DeclareVariable(trimStart(closure->closure->args[i]), args[i]);
|
||||
}
|
||||
if(i == closure->closure->args.size()-1)
|
||||
{
|
||||
auto lsArgs = TList::Create(ls);
|
||||
for(;i<args.size(); i++)
|
||||
lsArgs->Add(args[i]);
|
||||
cse->env->DeclareVariable(trimStart(closure->closure->args[i]), lsArgs);
|
||||
i = args.size();
|
||||
}
|
||||
if(i<args.size())
|
||||
throw VMException("Too many arguments");
|
||||
}
|
||||
|
||||
current_function = cse;
|
||||
|
||||
Reference in New Issue
Block a user