diff --git a/README.md b/README.md index 55501c9..1d6b059 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,63 @@ ## Installation -## Server - -sudo apt install git cmake lua5.1 liblua5.1-0-dev libssl-dev libcurl4-openssl-dev libsqlite3-dev libmicrohttpd-dev libjson-c-dev libenet-dev +## Server Linux + +Install the required libraries: +```bash +sudo apt install git cmake libluajit-5.1-dev libssl-dev libcurl4-openssl-dev libjson-c-dev libmicrohttpd-dev libsqlite3-dev libzmq3-dev libavcodec-dev libavformat-dev libavutil-dev libswresample-dev libswscale-dev libopencv-dev +``` + +Optional install nosql ejdb2 database: +```bash +sudo apt-get install software-properties-common +sudo add-apt-repository ppa:adamansky/ejdb2 +sudo apt-get install ejdb2 +``` + +Install Tensorflow Lite: +```bash +git clone https://github.com/tensorflow/tensorflow.git tensorflow_src +mkdir tflite_build +cd tflite_build +cmake ../tensorflow_src/tensorflow/lite/c -DTFLITE_ENABLE_GPU=ON +cmake --build . -j +``` + +Clone repository and use cmake: +```bash +git clone https://github.com/massimobernava/proteo.git +cd proteo/server +mkdir build +cd build +cmake -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl .. +make +``` + +Update config.json: +```json +{ "version":"0.1", + "basedir":"/usr/local/etc/Proteo/", + "baseurl":"YOUR_LOCAL_IP", + "port":8888,"master":1,"ssl":0, + "server_key":"01234567890123456789012345678901", + "client_key":"01234567890123456789012345678901", + "ssl_key":"", + "ssl_cert":"", + "admin_enabled":1,"plugins":["proteo","admin","edit","deepcrimson","deepindigo"], + "servers":[] +} +``` +Install it as a service: +```bash +chmod +x ./install.sh +sudo ./install.sh +``` ## Client +Choose, red pill and continue to compile, [blue pill](https://github.com/massimobernava/proteo/releases) and download one of the releases. + ### Linux Test: Ubuntu ... Raspberry ... diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 2660d1e..7ef5fdf 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -17,6 +17,8 @@ find_package(JSONC REQUIRED) #find_package(ENet REQUIRED) find_package(OpenCV REQUIRED) find_package(ZeroMQ REQUIRED) +find_package(OpenGL) +find_package(GLEW 2.0) find_path( AVCODEC_INCLUDE_DIR libavcodec/avcodec.h ) find_library( AVCODEC_LIBRARY avcodec ) @@ -25,27 +27,103 @@ find_library( SWSCALE_LIBRARY swscale ) find_path(AVUTIL_INCLUDE_DIR libavutil/avutil.h) find_library(AVUTIL_LIBRARY avutil) -include_directories(${SWSCALE_INCLUDE_DIR} ${AVCODEC_INCLUDE_DIR} ${AVUTIL_INCLUDE_DIR} ${SDL2_INCLUDE_DIRS} ${SDL2_TTF_INCLUDE_DIRS} ${SDL2_IMAGE_INCLUDE_DIRS} ${SDL2_GFX_INCLUDE_DIRS} ${LUAJIT_INCLUDE_DIR} ${OPENSSL_INCLUDE_DIR} ${CURL_INCLUDE_DIRS} ${JSONC_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS} ${ZMQ_INCLUDE_DIRS}) #${ENET_INCLUDE_DIRS} +find_path(TensorFlowLite_INCLUDE_DIR +NAMES +tensorflow/lite +tensorflow +HINTS +${CMAKE_SOURCE_DIR}/tflite/include +/usr/local/include) + +find_library(TensorFlowLite_LIBRARY +NAMES +tensorflowlite_c +tensorflowlite +HINTS +${CMAKE_SOURCE_DIR}/tflite/lib +/usr/lib +/usr/local/lib) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(TFLITE DEFAULT_MSG TensorFlowLite_INCLUDE_DIR) + +if(TFLITE_FOUND) + include_directories(${TensorFlowLite_INCLUDE_DIR}) + add_definitions(-DTFLITE) +endif() + +if (GLEW_FOUND) + include_directories(${GLEW_INCLUDE_DIRS} ${OPENGL_INCLUDE_DIR}) + add_definitions(-DGLEW) +endif() + +include_directories( ${SWSCALE_INCLUDE_DIR} ${AVCODEC_INCLUDE_DIR} ${AVUTIL_INCLUDE_DIR} ${SDL2_INCLUDE_DIRS} ${SDL2_TTF_INCLUDE_DIRS} ${SDL2_IMAGE_INCLUDE_DIRS} ${SDL2_GFX_INCLUDE_DIRS} ${LUAJIT_INCLUDE_DIR} ${OPENSSL_INCLUDE_DIR} ${CURL_INCLUDE_DIRS} ${JSONC_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS} ${ZMQ_INCLUDE_DIRS}) #${ENET_INCLUDE_DIRS} if(ANDROID) add_executable(proteo SHARED proteo.c) +elseif(APPLE) + set(ICON_NAME "Proteo.icns") + set(ICON_PATH ${CMAKE_SOURCE_DIR}/${ICON_NAME}) + set(proteo_ICON ${ICON_PATH}) + set_source_files_properties(${proteo_ICON} PROPERTIES MACOSX_PACKAGE_LOCATION Resources) + + set(FONT1_NAME "ColabReg.otf") + set(FONT1_PATH ${CMAKE_SOURCE_DIR}/${FONT1_NAME}) + set(proteo_FONT1 ${FONT1_PATH}) + set_source_files_properties(${proteo_FONT1} PROPERTIES MACOSX_PACKAGE_LOCATION Resources) + + set(FONT2_NAME "OpenSans-Regular.ttf") + set(FONT2_PATH ${CMAKE_SOURCE_DIR}/${FONT2_NAME}) + set(proteo_FONT2 ${FONT2_PATH}) + set_source_files_properties(${proteo_FONT2} PROPERTIES MACOSX_PACKAGE_LOCATION Resources) + + set(CONFIG_NAME "config.json") + set(CONFIG_PATH ${CMAKE_SOURCE_DIR}/${CONFIG_NAME}) + set(proteo_CONFIG ${CONFIG_PATH}) + set_source_files_properties(${proteo_CONFIG} PROPERTIES MACOSX_PACKAGE_LOCATION Resources) + + file(COPY ${ICON_PATH} DESTINATION "proteo.app/Contents/Resources") + add_executable(proteo MACOSX_BUNDLE ${ICON_PATH} ${FONT1_PATH} ${FONT2_PATH} ${CONFIG_PATH} proteo.c proteo_opencv.cpp) + set_target_properties(proteo PROPERTIES MACOSX_BUNDLE_ICONFILE ${ICON_NAME}) + set_target_properties(proteo PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_SOURCE_DIR}/MacOSXBundleInfo.plist.in) + + SET(APPS "\${CMAKE_INSTALL_PREFIX}/proteo.app") + + #Copia il file nella directory principale + #INSTALL(TARGETS proteo BUNDLE DESTINATION ${CMAKE_SOURCE_DIR} COMPONENT Runtime) + + #set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}) + install(CODE " + + MESSAGE(\"Fixup\") + include(BundleUtilities) + fixup_bundle(${CMAKE_SOURCE_DIR}/install/proteo.app \"\" \"\") + + " COMPONENT Runtime) else() add_executable(proteo proteo.c proteo_opencv.cpp) endif() -target_link_libraries(proteo ${SWSCALE_LIBRARY} ${AVCODEC_LIBRARY} ${AVUTIL_LIBRARY} ${SDL2_LIBRARIES} ${SDL2_TTF_LIBRARIES} ${SDL2_IMAGE_LIBRARIES} ${SDL2_GFX_LIBRARIES} ${OPENSSL_LIBRARIES} ${LUAJIT_LIBRARIES} ${CURL_LIBRARIES} ${JSONC_LIBRARIES} ${OpenCV_LIBS} ${ZMQ_LIBRARIES}) #${ENET_LIBRARIES} +if(TFLITE_FOUND) + target_link_libraries(proteo ${TensorFlowLite_LIBRARY}) +endif() + +if (GLEW_FOUND) + target_link_libraries(proteo ${GLEW_LIBRARIES} ${OPENGL_gl_LIBRARY}) +endif() + +target_link_libraries(proteo ${SWSCALE_LIBRARY} ${AVCODEC_LIBRARY} ${AVUTIL_LIBRARY} ${SDL2_LIBRARIES} ${SDL2_TTF_LIBRARIES} ${SDL2_IMAGE_LIBRARIES} ${SDL2_GFX_LIBRARIES} ${OPENSSL_LIBRARIES} ${LUAJIT_LIBRARIES} ${CURL_LIBRARIES} ${JSONC_LIBRARIES} ${OpenCV_LIBS} ${ZMQ_LIBRARIES}) #${ENET_LIBRARIES} + +#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -latomic") + +#set(CMAKE_XCODE_GENERATE_SCHEME TRUE) +#set_property (TARGET proteo PROPERTY XCODE_SCHEME_ARGUMENTS " -g -d") +#set_property (TARGET proteo PROPERTY XCODE_SCHEME_ADDRESS_SANITIZER TRUE) -#include(InstallRequiredSystemLibraries) -#set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt") -#set(CPACK_GENERATOR "DragNDrop") -#set(CPACK_PACKAGE_NAME "Proteo") -#set(CPACK_PACKAGE_VERSION,1.0) +#set(CPACK_BUNDLE_NAME "Proteo") +#set(CPACK_BUNDLE_ICON "Proteo.icns") +#set(CPACK_BUNDLE_PLIST "Info.plist") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -latomic") +#include(CPack) -set(CMAKE_XCODE_GENERATE_SCHEME TRUE) -set_property (TARGET proteo PROPERTY XCODE_SCHEME_ARGUMENTS " -g -d") -set_property (TARGET proteo PROPERTY XCODE_SCHEME_ADDRESS_SANITIZER TRUE) -include(CPack) diff --git a/client/Logo.ico b/client/Logo.ico new file mode 100644 index 0000000..9bbd2eb Binary files /dev/null and b/client/Logo.ico differ diff --git a/client/Proteo.icns b/client/Proteo.icns new file mode 100644 index 0000000..ef55d5a Binary files /dev/null and b/client/Proteo.icns differ diff --git a/client/config.json b/client/config.json new file mode 100644 index 0000000..7a97414 --- /dev/null +++ b/client/config.json @@ -0,0 +1 @@ +{"version":"2.0.0","basedir":"./","server":"http://localhost:8888","username":"demo","password":"demo","script":"","appkey":"01234567890123456789012345678901","ssl":0} diff --git a/client/em.sh b/client/em.sh index bc66dbe..a3b8a94 100755 --- a/client/em.sh +++ b/client/em.sh @@ -1,12 +1,20 @@ +#./emsdk install latest +#./emsdk activate latest +#source ./emsdk_env.sh + #emcc -Iem-include proteo_opencv.c em-lib/liblua.a -o proteo_opencv.html --shell-file ./proteo_shell_minimal.html if [[ $1 == DEBUG ]]; then echo "DEBUG MODE" - emcc -Iem-include proteo.c em-lib/liblua.a -lidbfs.js -O2 -g1 -s ASSERTIONS=2 -s SAFE_HEAP=1 -s STACK_OVERFLOW_CHECK=2 -s WASM=1 -s USE_SDL=2 -s USE_SDL_IMAGE=2 -s SDL2_IMAGE_FORMATS='["bmp","png"]' -s USE_SDL_TTF=2 -s USE_SDL_GFX=2 -s FETCH=1 -s EXPORTED_FUNCTIONS='["_main","_em_login_function","_em_header_callback","_proteo_get_callback","_proteo_post_callback"]' -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]' -o index.html --shell-file ./proteo_shell_minimal.html + #emcc -Iem-include proteo_opencv.cpp em-lib/liblua.a em-lib/libopencv_core.a -lidbfs.js -O2 -g1 -s LLD_REPORT_UNDEFINED -s ASSERTIONS=2 -s SAFE_HEAP=1 -s STACK_OVERFLOW_CHECK=2 -s WASM=1 -s FETCH=1 + emcc -Iem-include proteo_opencv.cpp proteo.c em-lib/liblua.a em-lib/libopencv_*.a -lidbfs.js -O2 -g1 -s LLD_REPORT_UNDEFINED -s ASSERTIONS=2 -s STACK_OVERFLOW_CHECK=2 -s WASM=1 -s USE_SDL=2 -s USE_SDL_IMAGE=2 -s SDL2_IMAGE_FORMATS='["bmp","png"]' -s USE_SDL_TTF=2 -s USE_SDL_GFX=2 -s FETCH=1 -s EXPORTED_FUNCTIONS='["_main","_em_login_function","_em_header_callback","_proteo_get_callback","_proteo_post_callback"]' -s EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]' -o index.html --shell-file ./proteo_shell_minimal.html elif [[ $1 == SAN ]]; then echo "SANITIZER MODE" - emcc -Iem-include proteo.c em-lib/liblua.a -lidbfs.js -O2 -g1 -fsanitize=address -s ALLOW_MEMORY_GROWTH -s WASM=1 -s USE_SDL=2 -s USE_SDL_IMAGE=2 -s SDL2_IMAGE_FORMATS='["bmp","png"]' -s USE_SDL_TTF=2 -s USE_SDL_GFX=2 -s FETCH=1 -s EXPORTED_FUNCTIONS='["_main","_em_login_function","_em_header_callback","_proteo_get_callback","_proteo_post_callback"]' -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]' -o index.html --shell-file ./proteo_shell_minimal.html + emcc -Iem-include proteo_opencv.cpp proteo.c em-lib/liblua.a em-lib/libopencv_*.a -lidbfs.js -O2 -g1 -fsanitize=address -s ALLOW_MEMORY_GROWTH -s WASM=1 -s USE_SDL=2 -s USE_SDL_IMAGE=2 -s SDL2_IMAGE_FORMATS='["bmp","png"]' -s USE_SDL_TTF=2 -s USE_SDL_GFX=2 -s FETCH=1 -s EXPORTED_FUNCTIONS='["_main","_em_login_function","_em_header_callback","_proteo_get_callback","_proteo_post_callback"]' -s EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]' -o index.html --shell-file ./proteo_shell_minimal.html +elif [[ $1 == NOOPENCV ]]; then + echo "NO OPENCV MODE" + emcc -Iem-include proteo.c em-lib/liblua.a -lidbfs.js -Oz -fsanitize=undefined -s ALLOW_MEMORY_GROWTH=1 -s ASSERTIONS=1 -g1 -s WASM=1 -s USE_SDL=2 -s USE_SDL_IMAGE=2 -s SDL2_IMAGE_FORMATS='["bmp","png"]' -s USE_SDL_TTF=2 -s USE_SDL_GFX=2 -s FETCH=1 -s EXPORTED_FUNCTIONS='["_main","_em_login_function","_em_header_callback","_proteo_get_callback","_proteo_post_callback","_image_to_mat"]' -s EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]' -s NO_DISABLE_EXCEPTION_CATCHING -o index.html --shell-file ./proteo_shell_minimal.html else - emcc -Iem-include proteo.c em-lib/liblua.a -lidbfs.js -Oz -s ASSERTIONS=1 -g1 -s WASM=1 -s USE_SDL=2 -s USE_SDL_IMAGE=2 -s SDL2_IMAGE_FORMATS='["bmp","png"]' -s USE_SDL_TTF=2 -s USE_SDL_GFX=2 -s FETCH=1 -s EXPORTED_FUNCTIONS='["_main","_em_login_function","_em_header_callback","_proteo_get_callback","_proteo_post_callback"]' -s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]' -o index.html --shell-file ./proteo_shell_minimal.html + emcc -Iem-include proteo_opencv.cpp proteo.c em-lib/liblua.a em-lib/libopencv_*.a -lidbfs.js -Oz -fsanitize=undefined -s ALLOW_MEMORY_GROWTH=1 -s ASSERTIONS=1 -g1 -s WASM=1 -s USE_SDL=2 -s USE_SDL_IMAGE=2 -s SDL2_IMAGE_FORMATS='["bmp","png"]' -s USE_SDL_TTF=2 -s USE_SDL_GFX=2 -s FETCH=1 -s EXPORTED_FUNCTIONS='["_main","_em_login_function","_em_header_callback","_proteo_get_callback","_proteo_post_callback","_image_to_mat"]' -s EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]' -s NO_DISABLE_EXCEPTION_CATCHING -o index.html --shell-file ./proteo_shell_minimal.html fi diff --git a/client/icon.rc b/client/icon.rc new file mode 100644 index 0000000..c356d64 --- /dev/null +++ b/client/icon.rc @@ -0,0 +1,2 @@ + +MAINICON ICON "Logo.ico" diff --git a/client/proteo.c b/client/proteo.c index 6f6d948..980fa6e 100644 --- a/client/proteo.c +++ b/client/proteo.c @@ -1,20 +1,27 @@ //============================================================================== -//=> Proteo v2.0 +//=> Proteo v0.2 //=> //=> //=> CC BY-NC-SA 3.0 //=> //=> Massimo Bernava //=> massimo.bernava@gmail.com -//=> 2021-05-13 +//=> 2021-06-15 //============================================================================== +//#define TFLITE //CMAKE +//#define GLEW //CMAKE + //#if defined(__MINGW32__) || defined(__MINGW64__) // #define _WIN32 //#endif +#define TARGET_OS_WINDOWS 0 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) - //define something for Windows (32-bit and 64-bit, this part is common) + + #define TARGET_OS_WINDOWS 1 + #define TFLITE //For code::blocks + #ifdef _WIN64 //define something for Windows (64-bit only) #else @@ -47,21 +54,26 @@ #define PROTEO_USE_TINYJSON #define PROTEO_USE_INTERNALMD5 -#elif defined(_WIN32) - #define PROTEO_USE_TINYJSON - +#else //if defined(_WIN32) + // #define PROTEO_USE_TINYJSON + #define PROTEO_ZMQ + #define PROTEO_FFMPEG + #define LUA_JIT + #endif -//#define PROTEO_USE_TINYJSON +#ifdef GLEW +//#define USEOPENGL +#endif -#define PROTEO_ZMQ #define PROTEO_OPENCV -#define PROTEO_FFMPEG +//#define BACKBUFFER + +//#define PROTEO_USE_TINYJSON //TODO //#define DLINK_LIST_COMPONENT - #define PROTEO_ENET #define BEZIER @@ -72,6 +84,9 @@ #include "proteo_b64.c" #include "proteo_config.c" #include "proteo_sdl.c" +#ifdef USEOPENGL +#include "proteo_gl.c" +#endif #include "proteo_gui.c" #include "proteo_lua.c" #include "proteo_network.c" @@ -87,548 +102,24 @@ #ifdef PROTEO_ENET #include "proteo_enet.c" #endif -#ifdef __EMSCRIPTEN__ - #ifdef PROTEO_OPENCV - #include "proteo_opencv.c" - #endif -#endif +//#ifdef __EMSCRIPTEN__ + //#ifdef PROTEO_OPENCV + //#include "proteo_opencv.c" + //#endif +//#endif #ifdef PROTEO_FFMPEG #include "proteo_ffmpeg.c" #endif -//============================================================================== -// TODO -//============================================================================== - -// -//============================================================================== -// UTILITY -//============================================================================== - -ProteoColor brightness(ProteoColor color,float bright) -{ - ProteoColor col={255, - MIN(255,color.r*bright), - MIN(255,color.g*bright), - MIN(255,color.b*bright)}; - - return col; -} - -ProteoColor saturation(ProteoColor color, float sat) -{ - const float Pr=0.299; - const float Pg=0.587; - const float Pb=0.114; - - float P=sqrt(color.r*color.r*Pr+color.g*color.g*Pg+color.b*color.b*Pb); - - ProteoColor col={255, - P+(color.r-P)*sat, - P+(color.g-P)*sat, - P+(color.b-P)*sat}; - - return col; -} - -char font_path[256]; -char* font2path(const char* font) -{ - //#ifdef __EMSCRIPTEN__ - //strcpy(font_path,""); - //#else - strcpy(font_path,config.basedir); - //#endif - - size_t n = sizeof(nfonts)/sizeof(nfonts[0]); - for(int i=0;i> 24) & 0xff; - col.r = (value >> 16) & 0xff; - col.g = (value >> 8) & 0xff; - col.b = (value >> 0) & 0xff; - //return color; - - return col; -} - -void mkpath(const char* dir) { - char tmp[256]; - char *p = NULL; - size_t len; - - snprintf(tmp, sizeof(tmp),"%s",dir); - dirname(tmp); - len = strlen(tmp); - if(tmp[len - 1] == '/') - tmp[len - 1] = 0; - for(p = tmp + 1; *p; p++) - if(*p == '/') { - *p = 0; - #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined(__MINGW64__) - _mkdir(tmp); - #else - mkdir(tmp, S_IRWXU); - #endif - *p = '/'; - } - #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined(__MINGW64__) - _mkdir(tmp); - #else - mkdir(tmp, S_IRWXU); - #endif -} - -int writefile(char* filename,char* data) -{ - FILE *handler=fopen(filename,"w"); - if (handler) - { - fprintf(handler,"%s",data); - fclose(handler); - return 0; - } - - return 1; -} - -int writedatafile(char* filename,char* data,int data_size) -{ - int write_size; - FILE *handler=fopen(filename,"wb"); - if (handler) - { - write_size = fwrite(data, sizeof(char), data_size, handler); - fclose(handler); - if(debug) printf("Write data file: %s,%d,%d\n",filename,data_size,write_size); - return write_size; - } - else printf("Write data %s error: %s\n",filename,strerror(errno)); - - return 0; -} - -char* loadfile(char *filename) -{ - char *buffer = NULL; - int string_size, read_size; - FILE *handler = fopen(filename, "r"); - - if (handler) - { - fseek(handler, 0, SEEK_END); - string_size = ftell(handler); - rewind(handler); - - buffer = (char*) malloc(sizeof(char) * (string_size + 1) ); - if(buffer!=NULL) - { - read_size = fread(buffer, sizeof(char), string_size, handler); - buffer[string_size] = '\0'; - - if (string_size != read_size) - { - free(buffer); - buffer = NULL; - } - } - - fclose(handler); - } - else printf("Load file %s error: %s\n",filename,strerror(errno)); - - return buffer; -} - -int loaddatafile(char *filename,char **buffer) -{ - int data_size, read_size; - FILE *handler = fopen(filename, "r"); - - if (handler) - { - fseek(handler, 0, SEEK_END); - data_size = ftell(handler); - rewind(handler); - - *buffer = (char*) malloc(sizeof(char) * (data_size) ); - if(buffer!=NULL) - { - read_size = fread(*buffer, sizeof(char), data_size, handler); - - if (data_size != read_size) - { - free(*buffer); - *buffer = NULL; - return 0; - } - //if(debug) printf("Load data file: %s,%d,%d\n",filename,data_size,read_size); - if(debug) printf("Load data file: %s\n",filename); - } - fclose(handler); - } - else printf("Load data %s error: %s\n",filename,strerror(errno)); - - return read_size; -} - -void hexDump (const char * desc, const void * addr, const int len) { - int i; - unsigned char buff[17]; - const unsigned char * pc = (const unsigned char *)addr; - - // Output description if given. - - if (desc != NULL) - printf ("%s:\n", desc); - - // Length checks. - - if (len == 0) { - printf(" ZERO LENGTH\n"); - return; - } - else if (len < 0) { - printf(" NEGATIVE LENGTH: %d\n", len); - return; - } - - // Process every byte in the data. - - for (i = 0; i < len; i++) { - // Multiple of 16 means new line (with line offset). - - if ((i % 16) == 0) { - // Don't print ASCII buffer for the "zeroth" line. - - if (i != 0) - printf (" %s\n", buff); - - // Output the offset. - - printf (" %04x ", i); - } - - // Now the hex code for the specific character. - printf (" %02x", pc[i]); - - // And buffer a printable ASCII character for later. - - if ((pc[i] < 0x20) || (pc[i] > 0x7e)) // isprint() may be better. - buff[i % 16] = '.'; - else - buff[i % 16] = pc[i]; - buff[(i % 16) + 1] = '\0'; - } - - // Pad out last line if not exactly 16 characters. - - while ((i % 16) != 0) { - printf (" "); - i++; - } - - // And print the final ASCII buffer. - - printf (" %s\n", buff); -} - -char* concat(const char *s1, const char *s2) -{ - const size_t len1 = strlen(s1); - const size_t len2 = strlen(s2); - char *result = malloc(len1 + len2 + 1); - - if(result!=NULL) - { - memcpy(result, s1, len1); - memcpy(result + len1, s2, len2 + 1); - } - result[len1 + len2]=0; - - return result; -} - -char* concat3(const char *s1, const char *s2, const char *s3) -{ - const size_t len1 = strlen(s1); - const size_t len2 = strlen(s2); - const size_t len3 = strlen(s3); - - char *result = malloc(len1 + len2 + len3 + 1); - - if(result!=NULL) - { - memcpy(result, s1, len1); - memcpy(result + len1, s2, len2); - memcpy(result + len1 + len2, s3, len3 + 1); // +1 to copy the null-terminator - } - result[len1 + len2 + len3]=0; - - return result; -} - -int c_quote(const char* src, char* dest, int maxlen) { - int count = 0; - if(maxlen < 0) { - maxlen = strlen(src)+1; /* add 1 for NULL-terminator */ - } - - while(src && maxlen > 0) { - switch(*src) { - - /* these normal, printable chars just need a slash appended */ - case '\\': - case '\"': - case '\'': - if(dest) { - *dest++ = '\\'; - *dest++ = *src; - } - count += 2; - break; - - /* newlines/tabs and unprintable characters need a special code. - * Use the macro CASE_CHAR defined below. - * The first arg for the macro is the char to compare to, - * the 2nd arg is the char to put in the result string, after the '\' */ -#define CASE_CHAR(c, d) case c:\ - if(dest) {\ - *dest++ = '\\'; *dest++ = (d);\ - }\ -count += 2;\ -break; - /* -------------- */ - CASE_CHAR('\n', 'n'); - CASE_CHAR('\t', 't'); - CASE_CHAR('\b', 'b'); - /* ------------- */ - -#undef CASE_CHAR - - - /* by default, just copy the char over */ - default: - if(dest) { - *dest++ = *src; - } - count++; - } - - ++src; - --maxlen; - } - return count; -} - -//simple encrypt-decrypt function -void encryptDecrypt(char inpString[]) -{ - char xorKey[] = "Key"; - int len = strlen(inpString); - - for (int i = 0; i < len; i++) - { - inpString[i] = inpString[i] ^ xorKey[i%strlen(xorKey)]; - printf("%c",inpString[i]); - } -} - -#ifdef AFFINE -SDL_Point affineTrasformation(SDL_Point point,float affine[3][3]) -{ - SDL_Point ret; - - ret.x=point.x*affine[0][0]+point.y*affine[1][0]+affine[2][0]; - ret.y=point.x*affine[0][1]+point.y*affine[1][1]+affine[2][1]; - - return ret; -} +#ifdef TFLITE +#include "proteo_tensorflow.c" #endif -void mult_matrices(float a[3][3], float b[3][3], float result[3][3]) -{ - int i, j, k; - for(i = 0; i < 3; i++) - { - for(j = 0; j < 3; j++) - { - for(k = 0; k < 3; k++) - { - result[i][j] += a[i][k] * b[k][j]; - } - } - } -} - - -void laderman_mul(const float a[3][3],const float b[3][3],float c[3][3]) { - - float m[24]; // not off by one, just wanted to match the index from the paper - - m[1 ]= (a[0][0]+a[0][1]+a[0][2]-a[1][0]-a[1][1]-a[2][1]-a[2][2])*b[1][1]; - m[2 ]= (a[0][0]-a[1][0])*(-b[0][1]+b[1][1]); - m[3 ]= a[1][1]*(-b[0][0]+b[0][1]+b[1][0]-b[1][1]-b[1][2]-b[2][0]+b[2][2]); - m[4 ]= (-a[0][0]+a[1][0]+a[1][1])*(b[0][0]-b[0][1]+b[1][1]); - m[5 ]= (a[1][0]+a[1][1])*(-b[0][0]+b[0][1]); - m[6 ]= a[0][0]*b[0][0]; - m[7 ]= (-a[0][0]+a[2][0]+a[2][1])*(b[0][0]-b[0][2]+b[1][2]); - m[8 ]= (-a[0][0]+a[2][0])*(b[0][2]-b[1][2]); - m[9 ]= (a[2][0]+a[2][1])*(-b[0][0]+b[0][2]); - m[10]= (a[0][0]+a[0][1]+a[0][2]-a[1][1]-a[1][2]-a[2][0]-a[2][1])*b[1][2]; - m[11]= a[2][1]*(-b[0][0]+b[0][2]+b[1][0]-b[1][1]-b[1][2]-b[2][0]+b[2][1]); - m[12]= (-a[0][2]+a[2][1]+a[2][2])*(b[1][1]+b[2][0]-b[2][1]); - m[13]= (a[0][2]-a[2][2])*(b[1][1]-b[2][1]); - m[14]= a[0][2]*b[2][0]; - m[15]= (a[2][1]+a[2][2])*(-b[2][0]+b[2][1]); - m[16]= (-a[0][2]+a[1][1]+a[1][2])*(b[1][2]+b[2][0]-b[2][2]); - m[17]= (a[0][2]-a[1][2])*(b[1][2]-b[2][2]); - m[18]= (a[1][1]+a[1][2])*(-b[2][0]+b[2][2]); - m[19]= a[0][1]*b[1][0]; - m[20]= a[1][2]*b[2][1]; - m[21]= a[1][0]*b[0][2]; - m[22]= a[2][0]*b[0][1]; - m[23]= a[2][2]*b[2][2]; - - c[0][0] = m[6]+m[14]+m[19]; - c[0][1] = m[1]+m[4]+m[5]+m[6]+m[12]+m[14]+m[15]; - c[0][2] = m[6]+m[7]+m[9]+m[10]+m[14]+m[16]+m[18]; - c[1][0] = m[2]+m[3]+m[4]+m[6]+m[14]+m[16]+m[17]; - c[1][1] = m[2]+m[4]+m[5]+m[6]+m[20]; - c[1][2] = m[14]+m[16]+m[17]+m[18]+m[21]; - c[2][0] = m[6]+m[7]+m[8]+m[11]+m[12]+m[13]+m[14]; - c[2][1] = m[12]+m[13]+m[14]+m[15]+m[22]; - c[2][2] = m[6]+m[7]+m[8]+m[9]+m[23]; -} - -SDL_FPoint I2FPoint(SDL_Point p) -{ - SDL_FPoint ret={p.x,p.y}; - return ret; -} -SDL_Point F2IPoint(SDL_FPoint p) -{ - SDL_Point ret={p.x,p.y}; - return ret; -} -SDL_FPoint subtract(SDL_FPoint p0, SDL_FPoint p1) -{ - SDL_FPoint ret={p0.x-p1.x,p0.y-p1.y}; - - return ret; -} - -SDL_FPoint sum(SDL_FPoint p0, SDL_FPoint p1) -{ - SDL_FPoint ret={p0.x+p1.x,p0.y+p1.y}; - - return ret; -} - -SDL_FPoint multiply(SDL_FPoint p, float f) -{ - SDL_FPoint ret={p.x*f,p.y*f}; - - return ret; -} - -float dot(SDL_FPoint p0, SDL_FPoint p1) -{ - float ret=(p0.x*p1.x)+(p0.y*p1.y); - - return ret; -} - -float distance(SDL_FPoint p0,SDL_FPoint p1) -{ - return hypotf(p0.x-p1.x,p0.y-p1.y); -} - -SDL_FPoint normalize(SDL_FPoint p) -{ - float mag=hypotf(p.x,p.y); - SDL_FPoint ret={p.x/mag,p.y/mag}; - - //problema di normalizzazione? vettore spesso 0 - return ret; -} - -float magnitude(SDL_FPoint p) -{ - float len=hypotf(p.x,p.y); +#include "proteo_utility.c" - return len; -} - -SDL_FPoint getClosestPointOnSegment(SDL_FPoint p0, SDL_FPoint p1, SDL_FPoint p) -{ - SDL_FPoint d=subtract(p1,p0); - float c=dot(subtract(p,p0),d)/dot(d,d); - if(c>=1) return p1; - else if(c<=0) return p0; - else return sum(p0,multiply(d,c)); -} +//============================================================================== +// TODO +//============================================================================== -/*static getClosestPointOnSegment(p0, p1, p) { - let d = p1.subtract(p0); - let c = p.subtract(p0).dot(d) / (d.dot(d)); - if (c >= 1) { - return p1.clone(); - } else if (c <= 0) { - return p0.clone(); - } else { - return p0.add(d.multiply(c)); - } -} -*/ //============================================================================== // PROTEO //============================================================================== @@ -755,7 +246,10 @@ LUALIB_API int luaopen_proteo (lua_State *state) { lua_newtable(state); lua_setfield(state, -2, "ffmpeg"); - + + lua_newtable(state); + lua_setfield(state, -2, "tflite"); + lua_setglobal(state,"proteo"); lua_pushinteger(state, PROTEO_MAJOR_VERSION); @@ -790,7 +284,11 @@ LUALIB_API int luaopen_proteo (lua_State *state) { #ifdef PROTEO_FFMPEG add_ffmpeg_proteo(state); #endif - + + #ifdef TFLITE + add_tensorflow_proteo(state); + #endif + return 1; } @@ -895,7 +393,7 @@ int initLUA() addFunction_proteo(L,"opencv","getAffineTransform",opencv_getaffinetransform); addFunction_proteo(L,"opencv","warpAffine",opencv_warpaffine); addFunction_proteo(L,"opencv","toTable",opencv_totable); - + addTable_proteo(L,"opencv","matType"); addEnum_proteo(L,"opencv","matType","CV_8U",0); addEnum_proteo(L,"opencv","matType","CV_8S",1); @@ -1048,7 +546,7 @@ void eventloop(ProteoComponent* list) else if(e.type == SDL_FINGERDOWN) { if(verbose) printf("SDL_FINGERDOWN\n"); - + lua_getglobal(L,"touch"); if(lua_isfunction(L, -1) ) { @@ -1065,7 +563,7 @@ void eventloop(ProteoComponent* list) else if(e.type == SDL_FINGERUP) { if(verbose) printf("SDL_FINGERUP\n"); - + lua_getglobal(L,"release"); if(lua_isfunction(L, -1) ) { @@ -1121,66 +619,143 @@ void eventloop(ProteoComponent* list) } } } -void mainloop() -{ - if(components==NULL) sleep(1); - - //SDL_RenderClear(gRenderer); - //SDL_RenderCopy(renderer, texture, NULL, NULL); - //SDL_RenderCopy(renderer, spriteTexture, &rcSprite, &gdSprite); - SDL_SetRenderDrawColor( gRenderer, backgroundColor.r, backgroundColor.g, backgroundColor.b, 255 ); - //frameStart = SDL_GetTicks(); - // Clear window - SDL_RenderClear( gRenderer ); +void drawloop(ProteoComponent* current) +{ + //SDL_RenderClear(gRenderer); + //SDL_RenderCopy(renderer, texture, NULL, NULL); + //SDL_RenderCopy(renderer, spriteTexture, &rcSprite, &gdSprite); + SDL_SetRenderDrawColor( gRenderer, backgroundColor.r, backgroundColor.g, backgroundColor.b, 255 ); + + //frameStart = SDL_GetTicks(); + // Clear window +#ifdef BACKBUFFER + SDL_SetRenderTarget(gRenderer, gTarget); //BACKBUFFER +#endif + SDL_RenderClear( gRenderer ); - ProteoComponent* current=components; + //ProteoComponent* current=components; #ifdef DLINK_LIST_COMPONENT - ProteoComponent* last=NULL; + ProteoComponent* last=NULL; #endif - while(current!=NULL) - { - if(current->type!=Deleted && current->hidden==FALSE && current->parent==NULL) - { - SDL_SetRenderDrawBlendMode(gRenderer,SDL_BLENDMODE_BLEND); - - if(current->type==Rect) graphics_drawRect (gRenderer,current); - else if(current->type==Ellips) graphics_drawEllipse (gRenderer,current); - else if(current->type==Label) gui_drawLabel (gRenderer,current); - else if(current->type==Image) graphics_drawImage (gRenderer,current); - else if(current->type==Icon) graphics_drawIcon (gRenderer,current); - else if(current->type==Button) gui_drawButton (gRenderer,current); - else if(current->type==TextField) gui_drawTextField (gRenderer,current); - else if(current->type==List) gui_drawList (gRenderer,current); - else if(current->type==Checkbox) gui_drawCheckbox (gRenderer,current); - else if(current->type==Sprite) graphics_drawSprite (gRenderer,current); - else if(current->type==Polyg) graphics_drawPolygon (gRenderer,current); - //else if(current->type==Bezier) graphics_drawBezier (gRenderer,current); - else if(current->type==Shape) graphics_drawShape (gRenderer,current); - else if(current->type==DropDown) gui_drawDropDown (gRenderer,current); - else if(current->type==Form) gui_drawForm (gRenderer,current); - else if(current->type==Container) gui_drawContainer (gRenderer,current); - } + while(current!=NULL) + { + if(current->type!=Deleted && current->hidden==FALSE && current->parent==NULL) + { + SDL_SetRenderDrawBlendMode(gRenderer,SDL_BLENDMODE_BLEND); + + if(current->type==Rect) graphics_drawRect (gRenderer,current); + else if(current->type==Ellips) graphics_drawEllipse (gRenderer,current); + else if(current->type==Label) gui_drawLabel (gRenderer,current); + else if(current->type==Image) graphics_drawImage (gRenderer,current); + else if(current->type==Icon) graphics_drawIcon (gRenderer,current); + else if(current->type==Button) gui_drawButton (gRenderer,current); + else if(current->type==TextField) gui_drawTextField (gRenderer,current); + else if(current->type==List) gui_drawList (gRenderer,current); + else if(current->type==Checkbox) gui_drawCheckbox (gRenderer,current); + else if(current->type==Sprite) graphics_drawSprite (gRenderer,current); + else if(current->type==Particle) graphics_drawParticle (gRenderer,current); + else if(current->type==Polyg) graphics_drawPolygon (gRenderer,current); + //else if(current->type==Bezier) graphics_drawBezier (gRenderer,current); + else if(current->type==Shape) graphics_drawShape (gRenderer,current); + else if(current->type==DropDown) gui_drawDropDown (gRenderer,current); + else if(current->type==Form) gui_drawForm (gRenderer,current); + else if(current->type==Container) gui_drawContainer (gRenderer,current); + } #ifdef DLINK_LIST_COMPONENT - last=current; + last=current; #endif - if(current->next!=NULL && current->next->type==Deleted) //TODO non cancella il primo elemento - freecomponent(current,current->next); - current=current->next; - } + if(current->next!=NULL && current->next->type==Deleted) //TODO non cancella il primo elemento + freecomponent(current,current->next); + current=current->next; + } - ProteoSkeleton* current_sk=skeletons; - while(current_sk!=NULL) + ProteoSkeleton* current_sk=skeletons; + while(current_sk!=NULL) + { + if(current_sk->hidden==FALSE) { - if(current_sk->hidden==FALSE) - { - graphics_drawSkeleton (gRenderer,current_sk); - } + graphics_drawSkeleton (gRenderer,current_sk); + } + + current_sk=current_sk->next; + } +#ifdef BACKBUFFER +SDL_SetRenderTarget(gRenderer, NULL); //BACKBUFFER +SDL_RenderCopy(gRenderer, gTarget, NULL, NULL ); //BACKBUFFER +#endif + +SDL_RenderPresent(gRenderer); + +} + +#ifdef USEOPENGL +void drawloop_GL(ProteoComponent* current) +{ + glViewport(0, 0, gWidth, gHeight); + glClearColor(backgroundColor.r/255.0f, backgroundColor.g/255.0f, backgroundColor.b/255.0f, backgroundColor.a/255.0f); + glClear(GL_COLOR_BUFFER_BIT); - current_sk=current_sk->next; + //glColor3f(0.8f, 0.2f, 0.4f); + //glRectf(-0.5f, -0.5f, 0.5f, 0.5f); + + //glEnable(GL_TEXTURE_2D); + //glActiveTexture(GL_TEXTURE0); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + +#ifdef DLINK_LIST_COMPONENT + ProteoComponent* last=NULL; +#endif + while(current!=NULL) + { + if(current->type!=Deleted && current->hidden==FALSE && current->parent==NULL) + { + //SDL_SetRenderDrawBlendMode(gRenderer,SDL_BLENDMODE_BLEND); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + if(current->type==Rect) graphics_drawRect_GL (current); + //else if(current->type==Ellips) graphics_drawEllipse (gRenderer,current); + else if(current->type==Label) gui_drawLabel_GL (current); + //else if(current->type==Image) graphics_drawImage (gRenderer,current); + //else if(current->type==Icon) graphics_drawIcon (gRenderer,current); + else if(current->type==Button) gui_drawButton_GL (current); + else if(current->type==TextField) gui_drawTextField_GL (current); + //else if(current->type==List) gui_drawList (gRenderer,current); + //else if(current->type==Checkbox) gui_drawCheckbox (gRenderer,current); + //else if(current->type==Sprite) graphics_drawSprite (gRenderer,current); + //else if(current->type==Sprite) graphics_drawParticle (gRenderer,current); + //else if(current->type==Polyg) graphics_drawPolygon (gRenderer,current); + //else if(current->type==Bezier) graphics_drawBezier (gRenderer,current); + //else if(current->type==Shape) graphics_drawShape (gRenderer,current); + //else if(current->type==DropDown) gui_drawDropDown (gRenderer,current); + else if(current->type==Form) gui_drawForm_GL (current); + //else if(current->type==Container) gui_drawContainer (gRenderer,current); } +#ifdef DLINK_LIST_COMPONENT + last=current; +#endif + if(current->next!=NULL && current->next->type==Deleted) //TODO non cancella il primo elemento + freecomponent(current,current->next); + current=current->next; + } + + SDL_GL_SwapWindow(gWindow); +} +#endif + +void mainloop() +{ + if(components==NULL) sleep(1); + +#ifdef USEOPENGL + drawloop_GL(components); +#else + drawloop(components); +#endif - SDL_RenderPresent(gRenderer); #ifdef DLINK_LIST_COMPONENT eventloop(last); #else @@ -1203,11 +778,11 @@ void mainloop() struct timespec now; clock_gettime(CLOCK_REALTIME, &now); - double n=now.tv_sec*1000; + double n=now.tv_sec*1000.0; n=n+(now.tv_nsec/1000000.0); ProteoTimer* timer=timers; - double min=25; + double min=25; while(timer!=NULL) { if(timer->state==1) @@ -1259,7 +834,19 @@ int main(int argc,char **argv) pthread_t t_update; +#ifdef __EMSCRIPTEN__ + printf("Proteo Emscripten\n"); +#else printf("Proteo %s\n",argv[0]); +#endif + +#if TARGET_OS_MAC + wordexp_t exp_result; + wordexp("~/Library/Preferences/Proteo", &exp_result, 0); + mkpath(exp_result.we_wordv[0]); + wordfree(&exp_result); + +#endif //char luafile[50]; char username[50]; @@ -1269,9 +856,13 @@ int main(int argc,char **argv) int opt_password=FALSE; int opt_script=FALSE; int opt_gmode=FALSE; - + +#ifdef __EMSCRIPTEN__ + strcpy(app_path,""); +#else strcpy(app_path,dirname(argv[0])); - +#endif + //int opt_appkey=FALSE; config=load_config(); if(config.load_error!=0) @@ -1333,16 +924,22 @@ int main(int argc,char **argv) char basedir_tmp[PATH_MAX]; strcpy(basedir_tmp,config.basedir); strcpy(config.basedir,app_path); - strcat(config.basedir,"/"); + strcat(config.basedir,"/../Resources/"); + //strcpy(config.basedir,"~/Library/Preferences/Proteo/"); strcat(config.basedir,basedir_tmp); - + + debug=TRUE; verbose=FALSE; +#elif TARGET_OS_WINDOWS + opt_gmode=TRUE; + opt_remoteconsole=TRUE; + #elif __EMSCRIPTEN__ opt_gmode=TRUE; - debug=FALSE;//TRUE; - verbose=FALSE;//TRUE; + debug=TRUE; + verbose=FALSE; EM_ASM( // Make a directory other than '/' @@ -1369,7 +966,7 @@ int main(int argc,char **argv) case 'f': //Fullscreen opt_fullscreen=TRUE; break; - case 'e': //REmote Console + case 'e': //Remote Console opt_remoteconsole=TRUE; break; case 'c': //loadconfig @@ -1447,6 +1044,13 @@ int main(int argc,char **argv) } #endif // TARGET_OS_IPHONE +#ifdef LUAJIT_VERSION + printf("%s\n",LUAJIT_VERSION); +#else + printf("%s\n",LUA_VERSION); +#endif + + //if(opt_appkey==FALSE) return 0; #ifdef PROTEO_ENET enet_initialize(); @@ -1456,6 +1060,25 @@ int main(int argc,char **argv) printf( "Failed to initialize LUA!\n" ); return 1; } +#ifdef LUA_JIT + lua_pushinteger(L, 1); +#else + lua_pushinteger(L, 0); +#endif + lua_setglobal(L, "LUAJIT"); + +#ifdef __EMSCRIPTEN__ + lua_pushinteger(L, 1); +#else + lua_pushinteger(L, 0); +#endif + lua_setglobal(L, "EMSCRIPTEN"); + + lua_pushboolean(L, debug); + lua_setglobal(L, "DEBUG"); + + lua_pushboolean(L, verbose); + lua_setglobal(L, "VERBOSE"); if( initSDL() == FALSE) { @@ -1463,6 +1086,15 @@ int main(int argc,char **argv) return 2; } +#ifdef USEOPENGL + printf("GLEW Version: %s \n",glewGetString(GLEW_VERSION)); + printf("Shader Version: %s \n",glGetString(GL_SHADING_LANGUAGE_VERSION)); + lua_pushinteger(L, 1); +#else + lua_pushinteger(L, 0); +#endif + lua_setglobal(L,"SHADER"); + setLuaScreenSize(L); if(opt_gmode) @@ -1549,7 +1181,7 @@ int main(int argc,char **argv) #ifdef PROTEO2 proteo_login(username,password,script); #else - proteo_login(username,password,"8756c123-4567-9876-9876-1234567"); + proteo_login(username,password,"8756c442-3e57-4754-b3b2-0a82b7b5d295"); #endif } } @@ -1569,6 +1201,7 @@ int main(int argc,char **argv) #ifdef __EMSCRIPTEN__ emscripten_set_main_loop(mainloop, -1, 1); + //emscripten_set_main_loop_timing(EM_TIMING_RAF,2); //emscripten_request_animation_frame_loop(mainloop,0); #else while(run) @@ -1585,7 +1218,7 @@ int main(int argc,char **argv) //pthread_cancel(t_update); //free(Appkey); - + //CLOSE lua_getglobal(L,"close"); if(lua_isfunction(L, -1) ) diff --git a/client/proteo.h b/client/proteo.h index 23c5fac..a0eb49b 100644 --- a/client/proteo.h +++ b/client/proteo.h @@ -19,16 +19,25 @@ #include #include +#if !defined(_WIN32) +#include +#endif // defined + //#include "lua.h" //#include "lauxlib.h" //#include "lualib.h" #ifdef __EMSCRIPTEN__ #include -#elif defined(_WIN32) -#include +//#elif defined(_WIN32) +//#include +//#include #else +#ifdef LUA_JIT #include +#else +#include +#endif #endif //emscripten #include @@ -39,6 +48,17 @@ #include #include +#ifdef GLEW +#include +#include +//#include +//#include +#endif + +#ifdef TFLITE +#include +#endif + #ifdef __EMSCRIPTEN__ #include #include @@ -219,17 +239,18 @@ typedef struct font_name { char * name; char* path; + int base; } font_name; font_name nfonts[]= { - {"ColaborateThin","ColabThi.otf"}, - {"ColaborateBold","ColabBol.otf"}, - {"ColaborateLight","ColabLig.otf"}, - {"ColaborateMedium","ColabMed.otf"}, - {"Colaborate","ColabReg.otf"}, - {"Helvetica","Helvetica 400.ttf"}, - {"OpenSans","OpenSans-Regular.ttf"} + {"ColaborateThin","ColabThi.otf",FALSE}, + {"ColaborateBold","ColabBol.otf",FALSE}, + {"ColaborateLight","ColabLig.otf",FALSE}, + {"ColaborateMedium","ColabMed.otf",FALSE}, + {"Colaborate","ColabReg.otf",TRUE}, + {"Helvetica","Helvetica 400.ttf",FALSE}, + {"OpenSans","OpenSans-Regular.ttf",TRUE} }; @@ -364,7 +385,7 @@ const char server_form[] = "local label_server=nil \n" "label_server=proteo.gui.newLabel('label_server','Server:','OpenSans',18,'black','Clear',proteo.gui.LabelAlignment.Left,MIN_X +80,MIN_Y + 250,150,30) \n" "text_server=proteo.gui.newTextField('text_server',config.server,'OpenSans',18,'Black','White',MIN_X +200,MIN_Y + 250,380,30,'') \n" - + "label_appkey=proteo.gui.newLabel('label_appkey','AppKey:','OpenSans',18,'black','Clear',proteo.gui.LabelAlignment.Left,MIN_X +80,MIN_Y + 300,150,30) \n" "text_appkey=proteo.gui.newTextField('text_appkey',config.appkey,'OpenSans',18,'Black','White',MIN_X +200,MIN_Y + 300,380,30,'') \n" @@ -462,7 +483,8 @@ enum ProteoType Icon, Container, Shape, - Polyg + Polyg, + Particle //Bezier }; @@ -583,6 +605,36 @@ typedef struct SDL_RendererFlip flip; } _sprite; +typedef struct +{ + Uint32 frameTick; + + SDL_FPoint position; + + float speed; + float direction; + float rotation; + int life; + int lifeTime; + + float linearAccelerationX; + float linearAccelerationY; + float angularSpeed; + + float spin; + float size; + float startSize; + float endSize; + + ProteoColor startColor; + ProteoColor endColor; + SDL_BlendMode blendMode; + + SDL_Rect frameRect; + ProteoTexture* image; + +} _particle; + typedef struct { ProteoTexture* image; @@ -596,6 +648,9 @@ typedef struct typedef struct { ProteoColor color; + unsigned int shaderId; + int ref_render; + } _rect; /*typedef struct @@ -688,6 +743,7 @@ typedef union _container container; _sprite sprite; + _particle particle; _image image; _ellipse ellipse; _rect rect; @@ -764,6 +820,8 @@ void addFunction_proteo(lua_State *state,const char *lib,const char *fname,lua_C void addTable_proteo(lua_State *state,const char *lib,const char *tname); void addEnum_proteo(lua_State *state,const char *lib,const char *enumname,const char *vname,int value); +ProteoColor ColorInterpolation(ProteoColor startColor, float t, ProteoColor endColor); +float interpolation(float start, float t, float end); ProteoColor brightness(ProteoColor color,float bright); ProteoColor saturation(ProteoColor color,float sat); void mkpath(const char* dir); @@ -939,6 +997,7 @@ static int graphics_drawEllipse (SDL_Renderer* renderer,ProteoComponent* ellipse static int graphics_newEllipse (lua_State *state); //static int graphics_eventRect (lua_State *state,ProteoComponent* rect,SDL_Event e,SDL_Renderer* renderer); static int graphics_drawRect (SDL_Renderer* renderer,ProteoComponent* rect); +static int graphics_drawRect_GL(ProteoComponent* rect); static int graphics_newRect (lua_State *state); //static int graphics_eventImage (lua_State *state,ProteoComponent* image,SDL_Event e,SDL_Renderer* renderer); static int graphics_drawImage (SDL_Renderer* renderer,ProteoComponent* image); @@ -1006,7 +1065,7 @@ typedef struct OCVImage int height; int type; - + unsigned char *data; unsigned long step; diff --git a/client/proteo_config.c b/client/proteo_config.c index e71bb9d..0fe95f7 100644 --- a/client/proteo_config.c +++ b/client/proteo_config.c @@ -22,19 +22,35 @@ typedef struct conf } conf; conf config; +conf load_config(); //TODO conf default_config() { conf _config; +#if TARGET_OS_MAC + char path_config[PATH_MAX]; + strcpy(path_config,app_path); + strcat(path_config,"/../Resources/config.json"); + + char* json_config=loadfile(path_config); + wordexp_t exp_result; + wordexp("~/Library/Preferences/Proteo/config.json", &exp_result, 0); + writefile(exp_result.we_wordv[0],json_config); + wordfree(&exp_result); + + return load_config(); +#else + strcpy(_config.basedir,"./"); strcpy(_config.version,PROTEO_VERSION); strcpy(_config.username,""); strcpy(_config.password,""); strcpy(_config.server,"http://localhost:8888"); - strcpy(_config.appkey,"1234567890123456789012"); + strcpy(_config.appkey,"12345678901234567890123456789012"); _config.ssl=0; +#endif #ifdef __EMSCRIPTEN__ //Nella versione web si può scrivere un config parziale dentro il js (default_config), se non presente chiede il server @@ -53,6 +69,22 @@ conf default_config() ); strcpy(_config.server,server); free(server); + + char* appkey=(char*)EM_ASM_INT( + + var jsString = default_config.appkey; + + if(jsString==null) + jsString=window.prompt('App Key: '); + + + var lengthBytes = lengthBytesUTF8(jsString)+1; + var stringOnWasmHeap = _malloc(lengthBytes); + stringToUTF8(jsString, stringOnWasmHeap, lengthBytes); + return stringOnWasmHeap; + ); + strcpy(_config.appkey,appkey); + free(appkey); #endif if(verbose) printf("Default config server: %s\n",_config.server); @@ -82,6 +114,15 @@ conf load_config() char *home = getenv("HOME"); strcpy(path_config,home); strcat(path_config,"/Documents/config.json"); +#elif TARGET_OS_MAC + char path_config[PATH_MAX]; + //strcpy(path_config,app_path); + //strcat(path_config,"/../Resources/config.json"); + + wordexp_t exp_result; + wordexp("~/Library/Preferences/Proteo/config.json", &exp_result, 0); + strcpy(path_config,exp_result.we_wordv[0]); + wordfree(&exp_result); #else char path_config[PATH_MAX]; strcpy(path_config,app_path); @@ -92,13 +133,15 @@ conf load_config() char* json_config=loadfile(path_config); #endif - if(verbose) printf("CONFIG: %s\n",json_config); if(json_config==NULL) { + if(verbose) printf("CONFIG NOT FOUND\n"); _config.load_error=2; return _config; } + + if(verbose) printf("CONFIG: %s\n",json_config); #ifdef PROTEO_USE_TINYJSON json_t mem[32]; @@ -106,6 +149,7 @@ conf load_config() if(json==NULL) { + if(verbose) printf("CONFIG JSON ERROR\n"); _config.load_error=1; return _config; } @@ -139,12 +183,12 @@ conf load_config() if ( !server || JSON_TEXT != json_getType( server ) ) printf("Error, the server property is not found."); else strcpy(_config.server,json_getValue(server)); - + json_t const* appkey = json_getProperty( json, "appkey" ); if ( !appkey || JSON_TEXT != json_getType( appkey ) ) printf("Error, the appkey property is not found."); else strcpy(_config.appkey,json_getValue(appkey)); - + json_t const* ssl = json_getProperty( json, "ssl" ); if ( !ssl || JSON_INTEGER != json_getType( ssl ) ) printf("Error, the ssl property is not found."); else @@ -154,6 +198,7 @@ conf load_config() json_object * jobj = json_tokener_parse(json_config); if(jobj==NULL) { + if(verbose) printf("CONFIG JSON ERROR\n"); _config.load_error=1; return _config; } @@ -187,7 +232,7 @@ conf load_config() json_object_object_get_ex(jobj, "appkey", &obj); const char* appkey=json_object_get_string(obj); if(appkey!=NULL) strcpy(_config.appkey,appkey); - + json_object_object_get_ex(jobj, "ssl", &obj); _config.ssl=json_object_get_int(obj); @@ -206,6 +251,11 @@ int save_config(conf _config) { #ifdef __EMSCRIPTEN__ char json_config[512]; + + int dest_len=c_quote(_config.appkey,NULL,-1); + char* q_appkey=malloc(dest_len+1); + c_quote(_config.appkey,q_appkey,-1); + sprintf(json_config,"{" "\"version\":\"%s\"," "\"basedir\":\"%s\"," @@ -216,9 +266,12 @@ int save_config(conf _config) "\"appkey\":\"%s\"," "\"ssl\":%d" "}",_config.version,_config.basedir,_config.server, - _config.username,_config.password,_config.script,_config.appkey,_config.ssl); + _config.username,_config.password,_config.script,q_appkey,_config.ssl); + + free(q_appkey); + EM_ASM({ - var d = new Date(2021, 01, 01); + var d = new Date(2077, 04, 24); var p = '/'; document.cookie = escape(UTF8ToString($0)) + ';path=' + p @@ -226,10 +279,18 @@ int save_config(conf _config) },json_config); #else #if TARGET_OS_IPHONE - char path_config[256]; + char path_config[PATH_MAX]; char *home = getenv("HOME"); strcpy(path_config,home); strcat(path_config,"/Documents/config.json"); + #elif TARGET_OS_MAC + char path_config[PATH_MAX]; + //strcpy(path_config,app_path); + //strcat(path_config,"/../Resources/config.json"); + wordexp_t exp_result; + wordexp("~/Library/Preferences/Proteo/config.json", &exp_result, 0); + strcpy(path_config,exp_result.we_wordv[0]); + wordfree(&exp_result); #else char path_config[PATH_MAX]; strcpy(path_config,app_path); @@ -241,13 +302,13 @@ int save_config(conf _config) { return 1; } - + int dest_len=c_quote(_config.appkey,NULL,-1); - char* q_appkey=malloc(dest_len); + char* q_appkey=malloc(dest_len+1); c_quote(_config.appkey,q_appkey,-1); //printf("q appkey: %s",q_appkey); - - + + fprintf(f, "{" "\"version\":\"%s\"," "\"basedir\":\"%s\"," @@ -261,7 +322,7 @@ int save_config(conf _config) _config.username,_config.password,_config.script,q_appkey,_config.ssl); fclose(f); free(q_appkey); - + #endif return 0; } @@ -307,7 +368,7 @@ static int system_loadConfig (lua_State *state) { lua_pushstring(state, _config.appkey); lua_setfield(state, -2, "appkey"); - + lua_pushinteger(state, _config.ssl); lua_setfield(state, -2, "ssl"); @@ -329,20 +390,24 @@ static int system_saveConfig (lua_State *state) { { double value = lua_tonumber(state, -2); if(strcmp(key,"ssl")==0) _config.ssl=(int)value; + + //TODO nel caso in cui password o appkey sono formate solo da numeri senza punto funziona, + if(strcmp(key,"appkey")==0) snprintf(_config.appkey,32,"%d",(int)value); + if(strcmp(key,"password")==0) snprintf(_config.password,50,"%d",(int)value); //printf("%s => %f\n", key, value); } else { const char *value = lua_tostring(state, -2); - if(strcmp(key,"server")==0) strcpy(_config.server,value); - else if(strcmp(key,"basedir")==0) strcpy(_config.basedir,value); - else if(strcmp(key,"version")==0) strcpy(_config.version,value); - else if(strcmp(key,"username")==0) strcpy(_config.username,value); - else if(strcmp(key,"password")==0) strcpy(_config.password,value); - else if(strcmp(key,"script")==0) strcpy(_config.script,value); - else if(strcmp(key,"appkey")==0) strcpy(_config.appkey,value); - + if(strcmp(key,"server")==0) strlcpy(_config.server,value,sizeof(_config.server)); + else if(strcmp(key,"basedir")==0) strlcpy(_config.basedir,value,sizeof(_config.basedir)); + else if(strcmp(key,"version")==0) strlcpy(_config.version,value,sizeof(_config.version)); + else if(strcmp(key,"username")==0) strlcpy(_config.username,value,sizeof(_config.username)); + else if(strcmp(key,"password")==0) strlcpy(_config.password,value,sizeof(_config.password)); + else if(strcmp(key,"script")==0) strlcpy(_config.script,value,sizeof(_config.script)); + else if(strcmp(key,"appkey")==0) strlcpy(_config.appkey,value,sizeof(_config.appkey)); + //printf("%s => %s\n", key, value); } diff --git a/client/proteo_enet.c b/client/proteo_enet.c index 6ec2b00..d99d4f9 100644 --- a/client/proteo_enet.c +++ b/client/proteo_enet.c @@ -241,7 +241,7 @@ static int host_create(lua_State *l) { if (!lua_isnil(l, 2)) peer_count = luaL_checkint(l, 2); } - if(debug) printf("host create, peers=%d, channels=%d, in=%d, out=%d\n", + if(debug) printf("host create, peers=%zu, channels=%zu, in=%d, out=%d\n", peer_count, channel_count, in_bandwidth, out_bandwidth); host = enet_host_create(have_address ? &address : NULL, peer_count, channel_count, in_bandwidth, out_bandwidth); diff --git a/client/proteo_gl.c b/client/proteo_gl.c new file mode 100644 index 0000000..99179b4 --- /dev/null +++ b/client/proteo_gl.c @@ -0,0 +1,202 @@ + +unsigned int power_two_floor(unsigned int val) { + unsigned int power = 2, nextVal = power*2; + + while((nextVal *= 2) <= val) + power*=2; + + return power*2; + } + +void GL_SetRenderDrawColor(Uint8 r,Uint8 g,Uint8 b,Uint8 a) +{ + glColor4ub(r,g,b,a ); +} + +void GL_RenderFillRect(const SDL_Rect * rect) +{ + float x1=(2.0f*(float)rect->x/(float)gWidth)-1.0f; + float y1=(-2.0f*(float)rect->y/(float)gHeight)+1.0f; + float x2=(2.0f*(float)(rect->x+rect->w)/(float)gWidth)-1.0f; + float y2=(-2.0f*(float)(rect->y+rect->h)/(float)gHeight)+1.0f; + + glRectf(x1,y1,x2,y2); +} + +void GL_RenderCopy(SDL_Surface * surface,const SDL_Rect * srcrect,const SDL_Rect * texture_rect) +{ + float x1=(2.0f*(float)texture_rect->x/(float)gWidth)-1.0f; + float y1=(-2.0f*(float)texture_rect->y/(float)gHeight)+1.0f; + float x2=(2.0f*(float)(texture_rect->x+texture_rect->w)/(float)gWidth)-1.0f; + float y2=(-2.0f*(float)(texture_rect->y+texture_rect->h)/(float)gHeight)+1.0f; + + //Draw the SDL_Texture * as a Quad + glEnable(GL_TEXTURE_2D); + //glActiveTexture(GL_TEXTURE0); + //glEnable(GL_BLEND); + //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + //Bind the SDL_Texture in OpenGL + /*if(SDL_GL_BindTexture(form->texture, NULL, NULL)!=0) + { + printf("Error binding texture form %s\n",SDL_GetError()); + }*/ + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture_rect->w, texture_rect->h, 0, GL_BGRA, GL_UNSIGNED_BYTE, surface->pixels); + + glBegin(GL_QUADS); { + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glTexCoord2f(0, 0); glVertex3f(x1, y1, 0); + glTexCoord2f(1, 0); glVertex3f(x2, y1, 0); + glTexCoord2f(1, 1); glVertex3f(x2, y2, 0); + glTexCoord2f(0, 1); glVertex3f(x1, y2, 0); + } glEnd(); + glDisable(GL_TEXTURE_2D); + + glDisable(GL_TEXTURE_2D); +} + + +#define ROUNDING_POINT_COUNT 8 // Larger values makes circle smoother. +void GL_RenderFillRoundRect(const SDL_Rect * rect, float r) +{ + float x=(2.0f*(float)rect->x/(float)gWidth)-1.0f; + float y=(-2.0f*(float)rect->y/(float)gHeight)+1.0f; + //float x2=(2.0f*(float)(rect->x+rect->w)/(float)gWidth)-1.0f; + //float y2=(-2.0f*(float)(rect->y+rect->h)/(float)gHeight)+1.0f; + float w=2.0f*(float)(rect->w)/(float)gWidth; + float h=2.0f*(float)(rect->h)/(float)gHeight; + + SDL_FPoint top_left[ROUNDING_POINT_COUNT]; + SDL_FPoint bottom_left[ROUNDING_POINT_COUNT]; + SDL_FPoint top_right[ROUNDING_POINT_COUNT]; + SDL_FPoint bottom_right[ROUNDING_POINT_COUNT]; + + + float radius = fmin(w, h); + radius *= r; + + + int i = 0; + float x_offset, y_offset; + float step = ( 2.0f * M_PI ) / (ROUNDING_POINT_COUNT * 4), + angle = 0.0f; + + unsigned int index = 0, segment_count = ROUNDING_POINT_COUNT; + SDL_FPoint bottom_left_corner = { x + radius, y - h + radius }; + + + while( i != segment_count ) + { + x_offset = cosf( angle ); + y_offset = sinf( angle ); + + + top_left[ index ].x = bottom_left_corner.x - + ( x_offset * radius ); + top_left[ index ].y = ( h - ( radius * 2.0f ) ) + + bottom_left_corner.y - + ( y_offset * radius ); + + + top_right[ index ].x = ( w - ( radius * 2.0f ) ) + + bottom_left_corner.x + + ( x_offset * radius ); + top_right[ index ].y = ( h - ( radius * 2.0f ) ) + + bottom_left_corner.y - + ( y_offset * radius ); + + + bottom_right[ index ].x = ( w - ( radius * 2.0f ) ) + + bottom_left_corner.x + + ( x_offset * radius ); + bottom_right[ index ].y = bottom_left_corner.y + + ( y_offset * radius ); + + + bottom_left[ index ].x = bottom_left_corner.x - + ( x_offset * radius ); + bottom_left[ index ].y = bottom_left_corner.y + + ( y_offset * radius ); + + + /*top_left[ index ].x = top_left[ index ].x; + top_left[ index ].y = top_left[ index ].y; + + + top_right[ index ].x = top_right[ index ].x; + top_right[ index ].y = top_right[ index ].y; + + + bottom_right[ index ].x = bottom_right[ index ].x ; + bottom_right[ index ].y = bottom_right[ index ].y; + + + bottom_left[ index ].x = bottom_left[ index ].x ; + bottom_left[ index ].y = bottom_left[ index ].y ;*/ + + angle -= step; + + ++index; + + ++i; + } + + glBegin( GL_TRIANGLE_STRIP ); + { + // Top + for( i = segment_count - 1 ; i >= 0 ; i--) + { + glVertex2f( top_left[ i ].x, top_left[ i ].y ); + glVertex2f( top_right[ i ].x, top_right[ i ].y ); + } + + // In order to stop and restart the strip. + glVertex2f( top_right[ 0 ].x, top_right[ 0 ].y ); + glVertex2f( top_right[ 0 ].x, top_right[ 0 ].y ); + + // Center + glVertex2f( top_right[ 0 ].x, top_right[ 0 ].y ); + glVertex2f( top_left[ 0 ].x, top_left[ 0 ].y ); + glVertex2f( bottom_right[ 0 ].x, bottom_right[ 0 ].y ); + glVertex2f( bottom_left[ 0 ].x, bottom_left[ 0 ].y ); + + // Bottom + for( i = 0; i != segment_count ; i++ ) + { + glVertex2f( bottom_right[ i ].x, bottom_right[ i ].y ); + glVertex2f( bottom_left[ i ].x, bottom_left[ i ].y ); + } + } + glEnd(); +} //DrawRoundRect + +void GL_RenderSetClipRect(const SDL_Rect * rect) +{ + if(rect==NULL) + { + glDisable(GL_SCISSOR_TEST); + return; + } + + float x=(2.0f*(float)rect->x/(float)gWidth)-1.0f; + float y=(-2.0f*(float)rect->y/(float)gHeight)+1.0f; + //float x2=(2.0f*(float)(rect->x+rect->w)/(float)gWidth)-1.0f; + //float y2=(-2.0f*(float)(rect->y+rect->h)/(float)gHeight)+1.0f; + float w=2.0f*(float)(rect->w)/(float)gWidth; + float h=2.0f*(float)(rect->h)/(float)gHeight; + + glEnable(GL_SCISSOR_TEST); + //glScissor(x, y, w, h); + glScissor(rect->x,rect->y,rect->w,rect->h); +} + +void GL_ResizeSurface(ProteoComponent* pc) +{ + pc->texture_rect.w = power_two_floor(pc->texture_rect.w)*2; + pc->texture_rect.h = power_two_floor(pc->texture_rect.h)*2; + + SDL_Surface *tmp_surface = SDL_CreateRGBSurface(0, pc->texture_rect.w, pc->texture_rect.h, 32, 0x00ff0000,0x0000ff00,0x000000ff,0xff000000); + SDL_BlitSurface(pc->surface, NULL, tmp_surface, NULL); + SDL_FreeSurface(pc->surface); + pc->surface=tmp_surface; +} diff --git a/client/proteo_graphics.c b/client/proteo_graphics.c index 24fb706..d29f990 100644 --- a/client/proteo_graphics.c +++ b/client/proteo_graphics.c @@ -878,7 +878,7 @@ static int graphics_changeImage (lua_State *state) void* mat = luaL_checkudata(L, 2, "OpenCVMat"); OCVImage opencvimg=getImage(mat); - //if(debug) printf("graphics.changeImage OpenCV(%d,%d) Depth:%d Channels:%d Step:%lu\n",opencvimg.width, opencvimg.height,opencvimg.depth,opencvimg.channels,opencvimg.step); + if(verbose) printf("graphics.changeImage OpenCV(%d,%d) Depth:%d Channels:%d Step:%lu\n",opencvimg.width, opencvimg.height,opencvimg.depth,opencvimg.channels,opencvimg.step); if(pc->surface!=NULL) SDL_FreeSurface(pc->surface); pc->surface = SDL_CreateRGBSurfaceFrom((void*)opencvimg.data, @@ -1035,7 +1035,7 @@ static int graphics_addFrameSource(lua_State *state) { const int pos_y=luaL_checkint(state,3); const int width=luaL_checkint(state,4); const int height=luaL_checkint(state,5); - const int tw=luaL_checkint(state,6); + const int tw=luaL_checkint(state,6); //Destination size const int th=luaL_checkint(state,7); sprite->framesSource[sprite->nFrame].x=pos_x; @@ -2443,7 +2443,7 @@ static int graphics_bindSkeleton(lua_State *state) { ProteoBone* nearBone=getBone(ps,current); - int* bones=getBonesGroup(ps,nearBone,current); + int* bones=getBonesGroup(ps,nearBone,current); //array of bones that impact that shape (1=yes, 0=no) for(int k=0;knbones;k++) { if(bones[k]==1) @@ -2617,7 +2617,7 @@ static int graphics_addItem(lua_State *state) ProteoComponent* shape=toProteoComponent(state,1); ProteoComponent* item=toProteoComponent(state,2); - if(debug) printf("graphics.addItem %s -> %s\n",item->id,shape->id); + if(verbose) printf("graphics.addItem %s -> %s\n",item->id,shape->id); item->parent=shape; //child->child_next=NULL; @@ -2717,6 +2717,35 @@ static int graphics_newEllipse (lua_State *state) { //============================================================================== // RECT //============================================================================== +#ifdef USEOPENGL +static int graphics_drawRect_GL (ProteoComponent* rect) +{ + SDL_Rect rect_rect=rect->rect; + + if(rect->parent!=NULL) + { + rect_rect.x+=rect->parent->rect.x; + rect_rect.y+=rect->parent->rect.y; + } + + if(rect->component.rect.shaderId>0) + glUseProgram(rect->component.rect.shaderId); + + if(rect->component.rect.ref_render!=-1) + { + lua_getref(L,rect->component.rect.ref_render); + lua_pushinteger(L,rect->component.rect.shaderId); + int error = lua_pcall(L, 1, 0, 0); + } + + GL_SetRenderDrawColor(rect->color.r, rect->color.g, rect->color.b, rect->color.a); + GL_RenderFillRect(&rect_rect); + + if(rect->component.rect.shaderId>0) glUseProgram(NULL); + + return 1; +} +#endif static int graphics_drawRect (SDL_Renderer* renderer,ProteoComponent* rect) { @@ -2727,16 +2756,16 @@ static int graphics_drawRect (SDL_Renderer* renderer,ProteoComponent* rect) rect_rect.x+=rect->parent->rect.x; rect_rect.y+=rect->parent->rect.y; } - + rectangleRGBA(renderer, rect_rect.x, rect_rect.y, rect_rect.x+rect_rect.w, rect_rect.y+rect_rect.h, rect->color.r, rect->color.g, rect->color.b, rect->color.a); boxRGBA(renderer, rect_rect.x, rect_rect.y, rect_rect.x+rect_rect.w, rect_rect.y+rect_rect.h,rect->component.rect.color.r, rect->component.rect.color.g, rect->component.rect.color.b, rect->component.rect.color.a); - + /*SDL_SetRenderDrawColor( renderer, rect->component.rect.color.r, rect->component.rect.color.g, rect->component.rect.color.b, rect->component.rect.color.a ); SDL_RenderFillRect( renderer, & rect_rect );*/ - + return 1; } @@ -2776,6 +2805,8 @@ static int graphics_newRect (lua_State *state) { pc->rect.w=width; pc->rect.h=height; pc->component.rect.color=hex2color(color); + pc->component.rect.shaderId=0; + pc->component.rect.ref_render=-1; pc->color=hex2color(border_color); //pc->next=NULL; pc->surface=NULL; @@ -2946,6 +2977,234 @@ static int graphics_newSprite (lua_State *state) { return 1; } +//============================================================================== +// PARTICLE +//============================================================================== + +static int graphics_updateParticle (ProteoComponent* particle) +{ + if(particle->hidden==TRUE) return 3; + + Uint32 frameTime = SDL_GetTicks() - particle->component.particle.frameTick; + particle->component.particle.life-=frameTime; + + if(particle->component.particle.life < 0) + { + particle->hidden=TRUE; + bool callback_valid=false; + if(particle->callback!=NULL) + { + callback_valid=true; + lua_getglobal(L,particle->callback); + } + else if(particle->ref_callback!=-1) + { + callback_valid=true; + //lua_getref(L,particle->ref_callback); + lua_rawgeti(L, LUA_REGISTRYINDEX,particle->ref_callback); + } + + if(callback_valid) + { + lua_pushlightuserdata(L, particle); + int error = lua_pcall(L, 1, 0, 0); + + if (error) { + fprintf(stderr, "ERROR particle callback: %s\n", lua_tostring(L, -1)); + lua_pop(L, 1); + } + } + return 2; + } + + particle->component.particle.frameTick = SDL_GetTicks(); + + //printf("Particle %s life %d\n",particle->id,particle->component.particle.life); + particle->component.particle.direction+=particle->component.particle.angularSpeed*(float)frameTime/1000.0f; + + float speed_x=particle->component.particle.speed * cosf(particle->component.particle.direction); + float speed_y=particle->component.particle.speed * sinf(particle->component.particle.direction); + + speed_x+=(1.0f-(float)particle->component.particle.life/(float)particle->component.particle.lifeTime)*particle->component.particle.linearAccelerationX; + speed_y+=(1.0f-(float)particle->component.particle.life/(float)particle->component.particle.lifeTime)*particle->component.particle.linearAccelerationY; + + + /*speed_x+=(1.0f-(float)particle->component.particle.life/(float)particle->component.particle.lifeTime) * particle->component.particle.tangentialAcceleration * cosf(particle->component.particle.direction+1.5708f);//90° + speed_y+=(1.0f-(float)particle->component.particle.life/(float)particle->component.particle.lifeTime) * particle->component.particle.tangentialAcceleration * sinf(particle->component.particle.direction+1.5708f);//90°*/ + //printf("Particle %s speed_x: %f speed_y: %f\n",particle->id,speed_x,speed_y); + + particle->component.particle.position.x+=speed_x*(float)frameTime/1000.0f; + particle->component.particle.position.y+=speed_y*(float)frameTime/1000.0f; + + particle->component.particle.rotation+=particle->component.particle.spin; + + float t=1.0f-(float)particle->component.particle.life/(float)particle->component.particle.lifeTime; + particle->component.particle.size=interpolation(particle->component.particle.startSize,t,particle->component.particle.endSize); + + ProteoColor color=ColorInterpolation(particle->component.particle.startColor,t,particle->component.particle.endColor); + + SDL_SetTextureAlphaMod( particle->component.particle.image->texture,color.a); + SDL_SetTextureColorMod( particle->component.particle.image->texture, color.r, color.g, color.b ); + SDL_SetTextureBlendMode(particle->component.particle.image->texture,SDL_BLENDMODE_ADD); + + return 1; +} +static int graphics_drawParticle (SDL_Renderer* renderer,ProteoComponent* particle) +{ + graphics_updateParticle (particle); + + if(particle->component.particle.image!=NULL) + { + SDL_Rect location={particle->rect.x+(int)particle->component.particle.position.x, + particle->rect.y+(int)particle->component.particle.position.y, + particle->rect.w*particle->component.particle.size,particle->rect.h*particle->component.particle.size}; + + + SDL_RenderCopyEx(renderer, particle->component.particle.image->texture, &particle->component.particle.frameRect, &location,particle->component.particle.rotation,NULL,SDL_FLIP_NONE); + } + + return 1; +} + +static int set_particle(lua_State *state,int index,_particle* prt) +{ + prt->frameRect.x=0; + prt->frameRect.y=0; + prt->frameRect.w=0; + prt->frameRect.h=0; + + prt->speed=0; + prt->direction=0; + prt->life=prt->lifeTime=0; + + prt->spin=0.0f; + prt->rotation=0.0f; + + prt->linearAccelerationX=0; + prt->linearAccelerationY=0; + + prt->angularSpeed=0.0f; + + float radialAcceleration; //TODO away from the position (rect.x,rect.y) + + prt->startSize=prt->endSize=prt->size=1.0; + + char startColor[10]; + char endColor[10]; + //TODO third color + + SDL_BlendMode blendMode; + + prt->position.x=0; + prt->position.y=0; + + lua_pushvalue(state, index); + lua_pushnil(state); + while (lua_next(state, -2)) + { + lua_pushvalue(state, -2); + const char *key = lua_tostring(state, -1); + if (lua_isnumber(state, -2)==1) + { + double value = lua_tonumber(state, -2); + if(strcmp(key,"frame_x")==0) prt->frameRect.x=(int)value; + if(strcmp(key,"frame_y")==0) prt->frameRect.y=(int)value; + if(strcmp(key,"frame_width")==0) prt->frameRect.w=(int)value; + if(strcmp(key,"frame_height")==0) prt->frameRect.h=(int)value; + if(strcmp(key,"position_x")==0) prt->position.x=(int)value; + if(strcmp(key,"position_y")==0) prt->position.y=(int)value; + + if(strcmp(key,"startSpeed")==0) prt->speed=(float)value; + if(strcmp(key,"startDirection")==0) prt->direction=(float)value; + if(strcmp(key,"lifeTime")==0) prt->life=prt->lifeTime=(int)value; + + if(strcmp(key,"spin")==0) prt->spin=(float)value; + if(strcmp(key,"startRotation")==0) prt->rotation=(float)value; + if(strcmp(key,"angularSpeed")==0) prt->angularSpeed=(float)value; + + if(strcmp(key,"startSize")==0) prt->startSize=prt->size=(float)value; + if(strcmp(key,"endSize")==0) prt->endSize=(float)value; + + if(strcmp(key,"linearAccelerationX")==0) prt->linearAccelerationX=(float)value; + if(strcmp(key,"linearAccelerationY")==0) prt->linearAccelerationY=(float)value; + } + else if(lua_isstring(state, -2)==1) + { + const char *value = lua_tostring(state, -2); + + if(strcmp(key,"startColor")==0) strlcpy(startColor,value,10); + else if(strcmp(key,"endColor")==0) strlcpy(endColor,value,10); + + } + else printf("Key %s is type: %s\n",key, + lua_typename(L, lua_type(L, -2))); + + lua_pop(state, 2); + } + lua_pop(state, 1); + + prt->startColor=hex2color(startColor); + prt->endColor=hex2color(endColor); + + prt->frameTick = SDL_GetTicks(); + + return 1; +} + +static int graphics_setParticle (lua_State *state) { + + ProteoComponent* particle=toProteoComponent(state,1); + set_particle(state,2,&particle->component.particle); + particle->hidden=FALSE; +} + +static int graphics_newParticle (lua_State *state) { + const char* id=luaL_checkstring(state,1); + const char* file=luaL_checkstring(state,2); + const int pos_x=luaL_checkint(state,3); + const int pos_y=luaL_checkint(state,4); + const int width=luaL_checkint(state,5); + const int height=luaL_checkint(state,6); + + _particle prt; + set_particle(state,7,&prt); + + char* callback=NULL; + int ref_callback=-1; + if (lua_isstring(state,8)==1) + callback=(char*)luaL_checkstring(state,8); + else + ref_callback=lua_ref( L, TRUE ); + + ProteoComponent* pc=pushProteoComponent(state); + + //strcpy(pc->id,id); + strlcpy(pc->id,id,PROTEO_MAX_ID); + pc->rect.x=pos_x; + pc->rect.y=pos_y; + pc->rect.w=width; + pc->rect.h=height; + + pc->component.particle=prt; + + pc->component.particle.image=newTexture(gRenderer,file); + if(pc->component.particle.image==NULL) printf("Error newParticle: %s\n",file); + + pc->surface=NULL; + pc->texture=NULL; + pc->parent=NULL; + pc->hidden=FALSE; + pc->type=Particle; + pc->layer=100; + pc->font=NULL; + pc->txt=NULL; + pc->callback=callback; + pc->ref_callback=ref_callback; + + addComponent(pc,&components); + return 1; +} + //============================================================================== // ICON //============================================================================== @@ -3301,6 +3560,119 @@ static int graphics_newShape(lua_State *state) return 1; } +#ifdef USEOPENGL +GLuint compileShader(const char* source, GLuint shaderType) { + GLuint result = glCreateShader(shaderType); + // Define shader text + glShaderSource(result, 1, &source, NULL); + // Compile shader + glCompileShader(result); + + //Check vertex shader for errors + GLint shaderCompiled = GL_FALSE; + glGetShaderiv( result, GL_COMPILE_STATUS, &shaderCompiled ); + if( shaderCompiled != GL_TRUE ) { + printf("Shader compilation error!\n"); + GLint logLength; + glGetShaderiv(result, GL_INFO_LOG_LENGTH, &logLength); + if (logLength > 0) + { + GLchar *log = (GLchar*)malloc(logLength); + glGetShaderInfoLog(result, logLength, &logLength, log); + printf("Shader compile log: %s\n",log); + free(log); + } + glDeleteShader(result); + result = 0; + }else { + + + } + + return result; +} + +static int graphics_setShader (lua_State *state) { + ProteoComponent* pc=toProteoComponent(state,1); + GLuint programId=luaL_checkint(state,2); + int render=lua_ref(state, TRUE); + + if(pc!=NULL) + { + pc->component.rect.shaderId=programId; + pc->component.rect.ref_render=render; + } + + return 0; +} + +static int graphics_setUniform (lua_State *state) { + GLuint programId=luaL_checkint(state,1); + char* uniformName=luaL_checkstring(state,2); + + int uniformLocation=glGetUniformLocation(programId,uniformName); + + //TODO if number .... + float uniformValue=luaL_checknumber(state,3); + glUniform1f(uniformLocation,uniformValue); + + return 0; +} + +//----------------------------------------------------------------------------- +//-- newShader +//-- +//-- @param id component id (string, max size PROTEO_MAX_ID) +//-- @param pos_x position x on the screen +//-- @param pos_y position y on the screen +//-- +//----------------------------------------------------------------------------- + +static int graphics_newShader(lua_State *state) +{ + const char* vertex_shader_source=luaL_checkstring(state,1); + const char* fragment_shader_source=luaL_checkstring(state,2); + + GLuint programId = 0; + GLuint vtxShaderId, fragShaderId; + + programId = glCreateProgram(); + vtxShaderId = compileShader(vertex_shader_source, GL_VERTEX_SHADER); + fragShaderId = compileShader(fragment_shader_source, GL_FRAGMENT_SHADER); + + if(vtxShaderId && fragShaderId) { + // Associate shader with program + glAttachShader(programId, vtxShaderId); + glAttachShader(programId, fragShaderId); + glLinkProgram(programId); + glValidateProgram(programId); + + // Check the status of the compile/link + GLint logLen; + glGetProgramiv(programId, GL_INFO_LOG_LENGTH, &logLen); + if(logLen > 0) { + char* log = (char*) malloc(logLen * sizeof(char)); + // Show any errors as appropriate + glGetProgramInfoLog(programId, logLen, &logLen, log); + printf("Prog Info Log: %s\n" ,log); + free(log); + } + } + if(vtxShaderId) { + glDeleteShader(vtxShaderId); + } + if(fragShaderId) { + glDeleteShader(fragShaderId); + } + + lua_pushinteger(state, programId); + + return 1; +} + + +#endif + //============================================================================== // LUA //============================================================================== @@ -3311,6 +3683,8 @@ void add_graphics_proteo(lua_State* state) addFunction_proteo(state,"graphics","newRect",graphics_newRect); addFunction_proteo(state,"graphics","newEllipse",graphics_newEllipse); addFunction_proteo(state,"graphics","newSprite",graphics_newSprite); + addFunction_proteo(state,"graphics","newParticle",graphics_newParticle); + addFunction_proteo(state,"graphics","setParticle",graphics_setParticle); addFunction_proteo(state,"graphics","newIcon",graphics_newIcon); addFunction_proteo(state,"graphics","newPolygon",graphics_newPolygon); addFunction_proteo(state,"graphics","newShape",graphics_newShape); @@ -3355,4 +3729,9 @@ void add_graphics_proteo(lua_State* state) addFunction_proteo(state,"graphics","saveSkeleton",graphics_saveSkeleton); addFunction_proteo(state,"graphics","updateSkeleton",graphics_updateSkeleton); addFunction_proteo(state,"graphics","hideSkeleton",graphics_hideSkeleton); +#ifdef USEOPENGL + addFunction_proteo(state,"graphics","newShader",graphics_newShader); + addFunction_proteo(state,"graphics","setShader",graphics_setShader); + addFunction_proteo(state,"graphics","setUniform",graphics_setUniform); +#endif } diff --git a/client/proteo_gui.c b/client/proteo_gui.c index bc45749..b392703 100644 --- a/client/proteo_gui.c +++ b/client/proteo_gui.c @@ -176,6 +176,9 @@ void updatetxt(ProteoComponent* pc,SDL_Renderer* renderer) }*/ pc->surface = getTxtSurface(pc); +#ifdef USEOPENGL + GL_ResizeSurface(pc); +#endif pc->texture = SDL_CreateTextureFromSurface(renderer, pc->surface); } @@ -184,6 +187,12 @@ static int gui_getText (lua_State *state) { ProteoComponent* pc=toProteoComponent(state,1); if(verbose) printf("gui.getText\n"); + if(pc->txt==NULL) + { + lua_pushnil(state); + return 1; + } + if(pc->type==DropDown) { //TODO per il dropdown deve tornare il testo del controller o quello del child selezionato? @@ -328,7 +337,7 @@ static int gui_setHidden (lua_State *state) { ProteoComponent* pc=toProteoComponent(state,1); - if(pc!=NULL && pc->type==Deleted) return 0; + if(pc==NULL || pc->type==Deleted) return 0; const int hidden=lua_toboolean(state,2); pc->hidden=hidden; @@ -723,6 +732,7 @@ static int gui_newListItem (lua_State *state) { pc->layer=100; pc->font=newFont(font2path(font), font_size); //strcpy(pc->txt,txt); + pc->txt=NULL; if(txt!=NULL && strlen(txt)>0) { pc->txt=malloc(strlen(txt)+1); @@ -763,6 +773,31 @@ static int gui_eventLabel (lua_State *state,ProteoComponent* label,SDL_Event e,S return FALSE; } +#ifdef USEOPENGL +static int gui_drawLabel_GL (ProteoComponent* label) +{ + SDL_Rect label_rect=label->rect; + SDL_Rect texture_rect=label->texture_rect; + + if(label->parent!=NULL) + { + label_rect.x+=label->parent->rect.x; + label_rect.y+=label->parent->rect.y; + + texture_rect.x+=label->parent->rect.x; + texture_rect.y+=label->parent->rect.y; + } + + GL_SetRenderDrawColor(label->color.r, label->color.g, label->color.b, label->color.a ); + GL_RenderFillRect(& label_rect ); + + if(label->texture) + GL_RenderCopy(label->surface, NULL, & texture_rect ); + + return 1; +} +#endif + static int gui_drawLabel (SDL_Renderer* renderer,ProteoComponent* label) { SDL_Rect label_rect=label->rect; @@ -857,16 +892,28 @@ static int gui_newLabel (lua_State *state) { else { - /*int w,h; - TTF_SizeText(pc->font->font,txt,&w,&h); - pc->texture_rect.x=pos_x; - pc->texture_rect.y=pos_y; - pc->texture_rect.w=w; - pc->texture_rect.h=h;*/ +/*#ifdef USEOPENGL + //Find the first power of two for OpenGL image + int w,h; + TTF_SizeText(pc->font->font,txt,&w,&h); + pc->texture_rect.x=pos_x; + pc->texture_rect.y=pos_y; + SDL_Color Col = {pc->component.label.font_color.r, pc->component.label.font_color.g, pc->component.label.font_color.b}; + SDL_Surface *tmp_surface=TTF_RenderText_Blended(pc->font->font, txt, Col); + pc->texture_rect.w = power_two_floor(w)*2; + pc->texture_rect.h = power_two_floor(h)*2; + + pc->surface = SDL_CreateRGBSurface(0, pc->texture_rect.w, pc->texture_rect.h, 32, 0x00ff0000,0x0000ff00,0x000000ff,0xff000000); + SDL_BlitSurface(tmp_surface, NULL, pc->surface, NULL); + SDL_FreeSurface(tmp_surface); +#else*/ + pc->texture_rect=getTextureRect(pc); - /*SDL_Color Col = {pc->component.label.font_color.r, pc->component.label.font_color.g, pc->component.label.font_color.b}; - pc->surface = TTF_RenderText_Blended(pc->font->font, txt, Col);*/ pc->surface = getTxtSurface(pc); +//#endif +#ifdef USEOPENGL + GL_ResizeSurface(pc); +#endif pc->texture = SDL_CreateTextureFromSurface(gRenderer, pc->surface); } @@ -1047,6 +1094,49 @@ int proteo_makecursor(SDL_Rect *rect,ProteoComponent* textfield) return 0; } +#ifdef USEOPENGL +static int gui_drawTextField_GL (ProteoComponent* textfield) +{ + SDL_Rect textfield_rect=textfield->rect; + SDL_Rect texture_rect=textfield->texture_rect; + + if(textfield->parent!=NULL) + { + textfield_rect.x+=textfield->parent->rect.x; + textfield_rect.y+=textfield->parent->rect.y; + + texture_rect.x+=textfield->parent->rect.x; + texture_rect.y+=textfield->parent->rect.y; + } + + GL_SetRenderDrawColor(textfield->color.r, textfield->color.g, textfield->color.b, textfield->color.a ); + GL_RenderFillRect( & textfield_rect ); + + // GL_RenderSetClipRect(&textfield_rect); + + if(textfield->texture!=NULL) GL_RenderCopy(textfield->surface, NULL, & texture_rect ); + + if(textfield==selected) + { + blinkCursor++; + if(blinkCursor<30) + { + GL_SetRenderDrawColor( textfield->component.textfield.font_color.r, + textfield->component.textfield.font_color.g, + textfield->component.textfield.font_color.b, + 255 ); + SDL_Rect cursor; + proteo_makecursor(&cursor,textfield); + GL_RenderFillRect( & cursor ); + } + else if (blinkCursor>60) blinkCursor=0; + } + // GL_RenderSetClipRect(NULL); + + return TRUE; +} +#endif + static int gui_drawTextField (SDL_Renderer* renderer,ProteoComponent* textfield) { SDL_Rect textfield_rect=textfield->rect; @@ -1217,6 +1307,56 @@ static int gui_eventButton (lua_State *state,ProteoComponent* button,SDL_Event e return FALSE; } +#ifdef USEOPENGL +static int gui_drawButton_GL (ProteoComponent* button) +{ + SDL_Rect button_rect=button->rect; + SDL_Rect texture_rect=button->texture_rect; + + if(button->parent!=NULL) + { + button_rect.x+=button->parent->rect.x; + button_rect.y+=button->parent->rect.y; + + texture_rect.x+=button->parent->rect.x; + texture_rect.y+=button->parent->rect.y; + } + ProteoColor bcol={button->color.a,button->color.r,button->color.g,button->color.b}; + if(button->enabled) + { + int x,y; + + SDL_GetMouseState(&x,&y); + SDL_Point point={x/gScale,y/gScale}; + + if(SDL_PointInRect(&point,&button_rect)) + { + bcol=brightness(button->color,1.1f); + + } + + } + else + { + bcol=saturation(button->color,0.3f); + + } + + GL_SetRenderDrawColor(button->colorB.r, button->colorB.g, button->colorB.b, button->colorB.a); + SDL_Rect border={button_rect.x-button->component.button.border_size,button_rect.y-button->component.button.border_size, + button_rect.w+2*button->component.button.border_size,button_rect.h+2*button->component.button.border_size}; + GL_RenderFillRoundRect(& border,button->component.button.rounded?0.2:0 ); + + GL_SetRenderDrawColor(bcol.r, bcol.g, bcol.b, bcol.a); + + GL_RenderFillRoundRect(& button_rect,button->component.button.rounded?0.2:0 ); + + if(button->texture!=NULL) GL_RenderCopy(button->surface, NULL, & texture_rect ); + + return 1; +} +#endif + static int gui_drawButton (SDL_Renderer* renderer,ProteoComponent* button) { SDL_Rect button_rect=button->rect; @@ -1348,11 +1488,9 @@ static int gui_newButton (lua_State *state) { if(!pc->font->font) { if(verbose) printf("Font newButton(%d) error: %s\n",currentline(state), TTF_GetError()); - } else { - /*int w,h; TTF_SizeText(pc->font->font,txt,&w,&h); pc->texture_rect.x=pos_x+(width-w)/2; @@ -1363,6 +1501,9 @@ static int gui_newButton (lua_State *state) { /*SDL_Color Col = {pc->component.button.font_color.r, pc->component.button.font_color.g, pc->component.button.font_color.b}; pc->surface = TTF_RenderText_Blended(pc->font->font, txt, Col);*/ pc->surface = getTxtSurface(pc); +#ifdef USEOPENGL + GL_ResizeSurface(pc); +#endif pc->texture = SDL_CreateTextureFromSurface(gRenderer, pc->surface); } @@ -1960,6 +2101,90 @@ static int gui_newDropDownItem (lua_State *state) //============================================================================== // Form //============================================================================== +#ifdef USEOPENGL +static int gui_drawForm_GL (ProteoComponent* form) +{ + ProteoColor back_color={form->component.form.back_color.a,form->component.form.back_color.r,form->component.form.back_color.g,form->component.form.back_color.b}; + ProteoColor bar_color={form->component.form.bar_color.a,form->component.form.bar_color.r,form->component.form.bar_color.g,form->component.form.bar_color.b}; + + if(form->enabled) + { + int x,y; + SDL_GetMouseState(&x,&y); + SDL_Point point={x/gScale,y/gScale}; + + + if(SDL_PointInRect(&point,&form->rect)) + { + //back_color=brightness(form->component.form.back_color,1.1f); + bar_color=brightness(form->component.form.bar_color,1.1f); + } + } + else + { + back_color=saturation(form->component.form.back_color,0.3f); + bar_color=saturation(form->component.form.bar_color,0.3f); + } + + if(form->component.form.state==2) + { + GL_SetRenderDrawColor(back_color.r,back_color.g, back_color.b, back_color.a ); + GL_RenderFillRect(& form->rect ); + } + + if((form->component.form.mode & 2) == 0) + { + + GL_SetRenderDrawColor(bar_color.r, + bar_color.g, bar_color.b, bar_color.a ); + SDL_Rect bar; + bar.x=form->rect.x; + bar.y=form->rect.y; + bar.w=form->rect.w; + bar.h=form->component.form.bar_size; + GL_RenderFillRect( & bar); + + SDL_Rect texture_rect=form->texture_rect; + texture_rect.x+=form->rect.x; + texture_rect.y+=form->rect.y;//+(form->component.form.bar_size-form->texture_rect.h)/2; + //if(form->texture!=NULL) SDL_RenderCopy(renderer, form->texture, NULL, & form->texture_rect ); + if(form->texture!=NULL) GL_RenderCopy(form->surface,NULL,&texture_rect); + + ProteoColor button_color=brightness(form->component.form.bar_color,0.9f); + } + + if(form->component.form.state==2) + { + //ProteoComponent* current=form->component.form.child_next; + // while(current!=NULL) + for(int i=0;icomponent.form.nchilds;i++) + { + ProteoComponent* current=form->component.form.childs[i]; + if(current->type!=Deleted && current->hidden==FALSE) + { + //SDL_SetRenderDrawBlendMode(renderer,SDL_BLENDMODE_BLEND); + if(current->type==Rect) graphics_drawRect_GL (current); + //else if(current->type==Ellips) graphics_drawEllipse (renderer,current); + else if(current->type==Label) gui_drawLabel_GL (current); + //else if(current->type==Image) graphics_drawImage (renderer,current); + //else if(current->type==Icon) graphics_drawIcon (renderer,current); + //else if(current->type==Polyg) graphics_drawPolygon (renderer,current); + else if(current->type==Button) gui_drawButton_GL (current); + else if(current->type==TextField) gui_drawTextField_GL (current); + //else if(current->type==List) gui_drawList (renderer,current); + //else if(current->type==Checkbox) gui_drawCheckbox (renderer,current); + //else if(current->type==Sprite) graphics_drawSprite (renderer,current); + //else if(current->type==DropDown) gui_drawDropDown (renderer,current); + else if(current->type==Form) gui_drawForm_GL (current); + } + //current=current->component.form.child_next; + } + } + + return 1; +} +#endif + static int gui_drawForm (SDL_Renderer* renderer,ProteoComponent* form) { ProteoColor back_color={form->component.form.back_color.a,form->component.form.back_color.r,form->component.form.back_color.g,form->component.form.back_color.b}; @@ -2003,9 +2228,10 @@ static int gui_drawForm (SDL_Renderer* renderer,ProteoComponent* form) bar.h=form->component.form.bar_size; SDL_RenderFillRect( renderer, & bar); - form->texture_rect.x=10+form->rect.x; - form->texture_rect.y=form->rect.y+(form->component.form.bar_size-form->texture_rect.h)/2; - if(form->texture!=NULL) SDL_RenderCopy(renderer, form->texture, NULL, & form->texture_rect ); + SDL_Rect texture_rect=form->texture_rect; + texture_rect.x+=form->rect.x; + texture_rect.y+=form->rect.y;//+(form->component.form.bar_size-form->texture_rect.h)/2; + if(form->texture!=NULL) SDL_RenderCopy(renderer, form->texture, NULL, & texture_rect ); ProteoColor button_color=brightness(form->component.form.bar_color,0.9f); @@ -2264,10 +2490,16 @@ static int gui_newForm (lua_State *state) { int w,h; TTF_SizeText(pc->font->font,title,&w,&h); pc->texture_rect.x=10;//(width-w)/2; - pc->texture_rect.y=(bar_size-h)/2; + pc->texture_rect.y=(bar_size-h)/2; //ATTENZIONE vengono sovrascritti durante il draw + pc->texture_rect.w=w; pc->texture_rect.h=h; pc->surface = TTF_RenderText_Blended(pc->font->font, title, Col); + +#ifdef USEOPENGL + GL_ResizeSurface(pc); +#endif + pc->texture = SDL_CreateTextureFromSurface(gRenderer, pc->surface); } diff --git a/client/proteo_network.c b/client/proteo_network.c index 8b2c89d..e372208 100644 --- a/client/proteo_network.c +++ b/client/proteo_network.c @@ -282,10 +282,29 @@ static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream) } #ifdef __EMSCRIPTEN__ + +typedef struct ProteoDownload +{ + char name[256]; + char callback[256]; + +} ProteoDownload; + void downloadSucceeded(emscripten_fetch_t *fetch) { printf("Finished downloading %llu bytes from URL %s.\n", fetch->numBytes, fetch->url); - // The data is now available at fetch->data[0] through fetch->data[fetch->numBytes-1]; + if(fetch->userData!=NULL) + { + writedatafile(((ProteoDownload*)fetch->userData)->name,fetch->data,fetch->numBytes); + + EM_ASM( + FS.syncfs(function (err) { + //console.log("Download font error: "+err); + }); + ); + + free(fetch->userData); + } emscripten_fetch_close(fetch); // Free data associated with the fetch. } @@ -307,15 +326,31 @@ static int network_download(lua_State *state) //TODO completamente da scrivere, vedi newFont - emscripten_fetch_attr_t attr; + /*emscripten_fetch_attr_t attr; emscripten_fetch_attr_init(&attr); strcpy(attr.requestMethod, "GET"); //attr.userData callback + name - attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY | EMSCRIPTEN_FETCH_PERSIST_FILE; + attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY | EMSCRIPTEN_FETCH_PERSIST_FILE; attr.onsuccess = downloadSucceeded; attr.onerror = downloadFailed; - emscripten_fetch(&attr, "myfile.dat"); - + emscripten_fetch(&attr, "myfile.dat");*/ + + emscripten_fetch_attr_t attr; + emscripten_fetch_attr_init(&attr); + strcpy(attr.requestMethod, "GET"); + attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY;// | EMSCRIPTEN_FETCH_PERSIST_FILE; + ProteoDownload* prtDownload=malloc(sizeof(ProteoDownload)); + strcpy(prtDownload->name,name); + strcpy(prtDownload->callback,callback); + attr.userData = prtDownload; + attr.onsuccess = downloadSucceeded; + attr.onerror = downloadFailed; + //attr.destinationPath=path; + const char* full_path=concat3(config.server,"/",url); + if(verbose) printf("Download font: %s\n",full_path); + emscripten_fetch_t *fetch = emscripten_fetch(&attr, full_path); + free(full_path); + } #else static int network_download(lua_State *state) { @@ -554,8 +589,12 @@ void get_lib(json_object * jobj) addLib(name,scr); //printf("Download LUA: %s\n",scr); - luaL_dostring(L,scr); + int error = luaL_dostring(L,scr); + if (error) { + //printf("ERROR pcall(timer->callback,%d): %s\n",currentline(L),lua_tostring(L, -1)); + printf("ERROR pcall(get_lib): %s\n",lua_tostring(L, -1)); + } } } } @@ -592,12 +631,12 @@ void get_script(json_object * jobj) int error = luaL_dostring(L,scr); //lua_pushcfunction(L, traceback); - + if (error) { fprintf(stderr, "ERROR start script: %s\n", lua_tostring(L, -1)); lua_pop(L, 1); } - + lua_getglobal(L,"init"); //int error = lua_pcall(L, 0, 0, -2); error = lua_trace_pcall(L,0,0); @@ -636,8 +675,8 @@ void proteo_post(const char* res,const char* appkey, const char* token,const cha //proteo_post_callback(const char* res,const char* data,const char* callback) var result = Module.ccall('proteo_post_callback', 'null', - ['string','string','string'], - [UTF8ToString($1),this.responseText,UTF8ToString($5)]); + ['string','string','string','number'], + [UTF8ToString($1),this.responseText,UTF8ToString($5),$6]); } } @@ -653,7 +692,7 @@ void proteo_post(const char* res,const char* appkey, const char* token,const cha http.send(UTF8ToString($4)); - },config.server,res,token,appkey,post_data,callback); + },config.server,res,token,appkey,post_data,callback,ref_callback); /*//console.log(data.strValues); var http = new XMLHttpRequest(); @@ -682,11 +721,11 @@ void proteo_post(const char* res,const char* appkey, const char* token,const cha void proteo_post(const char* res,const char* appkey, const char* token,const char* post_data, const char* callback,const int ref_callback) { char* url=NULL; - + char tmp[256]; strcpy(tmp,res); char* app=strtok(tmp+1, "/"); - + /*if(strstr(res,"deepblue")!=NULL) { url=concat(getaccesspoint("deepblue"),res); @@ -701,7 +740,7 @@ void proteo_post(const char* res,const char* appkey, const char* token,const cha } else url=concat(config.server,res); - + char* data=concat(res,post_data); // if(debug) printf("HMAC \n json) %s\n",data); @@ -768,12 +807,14 @@ void proteo_post_callback(const char* res,const char* data,const char* callback, { //printf("%lu bytes retrieved\n", (unsigned long)chunk.size); #ifdef PROTEO_USE_TINYJSON - //int count=0; - //for(int i=0; data[i]; i++) if(data[i]==':') count++; //Very simple estimation - + int count=0; + for(int i=0; data[i]; i++) if(data[i]==':') count++; //Very simple estimation + json_t *mem=malloc(count*2*sizeof(json_t)); + json_t const* jobj = json_create( data, mem, count*2 ); + //TODO - json_t mem[32]; - json_t const* jobj = json_create( data, mem, sizeof mem / sizeof *mem ); + //json_t mem[32]; + //json_t const* jobj = json_create( data, mem, sizeof mem / sizeof *mem ); #else json_object * jobj = json_tokener_parse(data); #endif @@ -811,7 +852,7 @@ void proteo_post_callback(const char* res,const char* data,const char* callback, } } } - + #ifdef PROTEO_USE_TINYJSON free(mem); #endif @@ -877,7 +918,7 @@ void proteo_get(const char* res,const char* appkey, const char* token,const char char tmp[256]; strcpy(tmp,res); char* app=strtok(tmp+1, "/"); - + /*if(strstr(res,"deepblue")!=NULL) { url=concat(getaccesspoint("deepblue"),res); @@ -892,7 +933,7 @@ void proteo_get(const char* res,const char* appkey, const char* token,const char } else url=concat(config.server,res); - + char* data=concat(res,token); /*char data[2000]; @@ -973,8 +1014,14 @@ void proteo_get_callback(const char* res,const char* data,const char* callback) //printf("%lu bytes retrieved\n", (unsigned long)chunk.size); #ifdef PROTEO_USE_TINYJSON - json_t mem[32]; - json_t const* jobj = json_create( data, mem, sizeof mem / sizeof *mem ); + //json_t mem[32]; + //json_t const* jobj = json_create( data, mem, sizeof mem / sizeof *mem ); + + int count=0; + for(int i=0; data[i]; i++) if(data[i]==':') count++; //Very simple estimation + json_t *mem=malloc(count*2*sizeof(json_t)); + json_t const* jobj = json_create( data, mem, count*2 ); + #else json_object * jobj = json_tokener_parse(data); #endif @@ -1006,6 +1053,9 @@ void proteo_get_callback(const char* res,const char* data,const char* callback) } } } +#ifdef PROTEO_USE_TINYJSON + free(mem); +#endif } static int network_proteo_get(lua_State *state) { @@ -1178,9 +1228,9 @@ static int proteo_login_callback(char* ptr) #ifdef PROTEO2 struct json_object *tick; json_object_object_get_ex(jobj, "tickets", &tick); - struct array_list *tickets=json_object_get_array(tick); - for (int i = 0; i < array_list_length(tickets); i++) { - struct json_object *t = (struct json_object *) array_list_get_idx(tickets, i); + //struct array_list *tickets=json_object_get_array(tick); + for (int i = 0; i < /*array_list_length(tickets)*/ json_object_array_length(tick); i++) { + struct json_object *t = (struct json_object *) json_object_array_get_idx(tick, i);//array_list_get_idx(tickets, i); json_object_object_foreach(t, key, val) { //if(strcmp(app,key)==0 && val!=NULL) @@ -1321,7 +1371,7 @@ int em_login_function(void *ptr) strcpy(get_script,"/proteo/scriptandlibs/"); strcat(get_script,script); printf("Download LUA: %s\n",get_script); - proteo_get(get_script,PROTEO_APP_KEY,Token,""); + proteo_get(get_script,config.appkey,Token,""); } else if(res==2) @@ -1458,14 +1508,14 @@ void proteo_login_md5(const char* username,const char* md5_hex, const char* id) strftime (timestamp, 100, "%Y-%m-%d %H:%M:%S", localtime (&now)); //printf ("%s\n", timestamp); -#ifdef PROTEO_USE_TINYJSON +//#ifdef PROTEO_USE_TINYJSON char json[512]; sprintf(json,"{" "\"username\":\"%s\"," "\"scriptId\":\"%s\"," "\"timestamp\":\"%s\"" "}",username,id,timestamp); -#else +/*#else json_object * jobj = json_object_new_object(); #ifndef PROTEO2 json_object *jstring1 = json_object_new_string(id); @@ -1490,7 +1540,7 @@ void proteo_login_md5(const char* username,const char* md5_hex, const char* id) const char *json = json_object_to_json_string(jobj); //json_object_put(jobj); -#endif +#endif*/ if(debug) printf("login json: %s\n",json); @@ -1584,7 +1634,7 @@ void proteo_login_md5(const char* username,const char* md5_hex, const char* id) curl_easy_cleanup (hnd); #ifndef PROTEO_USE_TINYJSON - free( (void*)json ); + //free( (void*)json ); #endif free(chunk.memory); diff --git a/client/proteo_opencv.cpp b/client/proteo_opencv.cpp index 1caa95f..5101058 100644 --- a/client/proteo_opencv.cpp +++ b/client/proteo_opencv.cpp @@ -97,6 +97,9 @@ static UMat *checkMat (lua_State *L, int index) return mat; } +#ifdef __EMSCRIPTEN__ + +#else static VideoCapture *checkCap (lua_State *L, int index) { VideoCapture *cap; @@ -105,6 +108,7 @@ static VideoCapture *checkCap (lua_State *L, int index) if (cap == NULL) luaL_typerror(L, index, OPENCVVC); return cap; } +#endif #ifdef OPENCVNET static Net *checkNet (lua_State *L, int index) @@ -117,6 +121,9 @@ static Net *checkNet (lua_State *L, int index) } #endif +#ifdef __EMSCRIPTEN__ + +#else static VideoWriter *checkWriter (lua_State *L, int index) { VideoWriter *vw; @@ -125,6 +132,7 @@ static VideoWriter *checkWriter (lua_State *L, int index) if (vw == NULL) luaL_typerror(L, index, OPENCVVW); return vw; } +#endif //============================================================================== // GC @@ -143,6 +151,9 @@ static int mat_gc(lua_State *l) { return 0; } +#ifdef __EMSCRIPTEN__ + +#else static int vc_gc(lua_State *l) { VideoCapture* cap = checkCap(l, 1); @@ -155,6 +166,7 @@ static int vc_gc(lua_State *l) { return 0; } +#endif #ifdef OPENCVNET static int net_gc(lua_State *l) { @@ -171,6 +183,9 @@ static int net_gc(lua_State *l) { } #endif +#ifdef __EMSCRIPTEN__ + +#else static int vw_gc(lua_State *l) { VideoWriter* vw = checkWriter(l, 1); @@ -183,6 +198,7 @@ static int vw_gc(lua_State *l) { return 0; } +#endif //============================================================================== // PUSH @@ -246,6 +262,9 @@ static Net *pushNet (lua_State *state) } #endif +#ifdef __EMSCRIPTEN__ + +#else static VideoWriter *pushWriter (lua_State *state) { VideoWriter *vw = new (lua_newuserdata(state, sizeof(VideoWriter))) VideoWriter(); @@ -258,7 +277,11 @@ static VideoWriter *pushWriter (lua_State *state) return vw; } +#endif + +#ifdef __EMSCRIPTEN__ +#else static VideoCapture * pushCap (lua_State *state) { #if TARGET_OS_IPHONE @@ -277,6 +300,7 @@ static VideoCapture * pushCap (lua_State *state) #endif return ret; } +#endif //============================================================================== // OPENCV @@ -289,26 +313,39 @@ int opencv_img(lua_State *state) return 1; } + + int opencv_imread(lua_State *state) { const char* file=luaL_checkstring(state,1); +#ifdef __EMSCRIPTEN__ + +#else Mat tmp = imread( file, 1 ); UMat *ret=pushMat(state); tmp.copyTo(*ret); +#endif return 1; } + + int opencv_imwrite(lua_State* state) { const char* file=luaL_checkstring(state,1); +#ifdef __EMSCRIPTEN__ + +#else UMat* frame=checkMat(state, 2); if (!frame->empty()) imwrite(file, *frame); - +#endif return 0; } + + int opencv_imencode(lua_State* state) { UMat *img=checkMat(state,1); @@ -320,7 +357,9 @@ int opencv_imencode(lua_State* state) lua_pushnil(state); return 1; } +#ifdef __EMSCRIPTEN__ +#else vector buf; imencode(".jpg",*img,buf); @@ -332,15 +371,20 @@ int opencv_imencode(lua_State* state) lua_pushstring(state, b64); free(b64); - +#endif return 1; } + + int opencv_imdecode(lua_State* state) { const char* img=luaL_checkstring(state, 1); UMat *out=checkMat(state,2); +#ifdef __EMSCRIPTEN__ + +#else char *tmp=(char *)malloc(Base64decode_len(img)); int len = Base64decode(tmp, img); @@ -351,12 +395,17 @@ int opencv_imdecode(lua_State* state) imdecode(buf, 1).copyTo(*out); free(tmp); - +#endif + return 0; } + int opencv_videowriter(lua_State* state) { +#ifdef __EMSCRIPTEN__ + +#else VideoWriter *vw=pushWriter(state); const char *filename = lua_tostring(state, 1); @@ -368,12 +417,48 @@ int opencv_videowriter(lua_State* state) if(fourcc==0) fourcc=VideoWriter::fourcc('M','J','P','G'); vw->open(filename, fourcc, fps, Size(w,h)); - +#endif return 1; } + + int opencv_videocapture(lua_State* state) { +#ifdef __EMSCRIPTEN__ + const char *value = lua_tostring(state, 1); + + //Se il valore di input è 0 potremmo non settare l'attributo src e invece richiamare il codice di avvio della camera + char *cap=(char*)EM_ASM_INT({ + let video_element_id='VideoCapture'; + let video = document.createElement('video'); + video.id=video_element_id; + video.style.display = "none"; + //video.autoplay=true; + video.width=576; + video.height=720; + video.setAttribute('src',UTF8ToString($0)); + + document.body.insertBefore(video, null); + + var canvas=document.createElement('canvas'); + canvas.width=video.width; + canvas.height=video.height; + var ctx=canvas.getContext('2d'); + + //document.body.insertBefore(canvas, null); + + video.ctx=ctx; + + var lengthBytes = lengthBytesUTF8(video_element_id)+1; + var stringOnWasmHeap = _malloc(lengthBytes); + stringToUTF8(video_element_id, stringOnWasmHeap, lengthBytes); + return stringOnWasmHeap; + },value); + lua_pushstring(state, cap); + free(cap); + return 1; +#else VideoCapture *cap=pushCap(state); if (lua_isnumber(state, 1)==1) @@ -404,42 +489,55 @@ cap->set(CAP_PROP_BUFFERSIZE, 3); */ printf("VideoCapture open error\n"); } } - +#endif return 1; } int opencv_getFrameSize(lua_State* state) { - VideoCapture *cap=checkCap(state,1); +#ifdef __EMSCRIPTEN__ +#else + VideoCapture *cap=checkCap(state,1); +#endif return 1; } int opencv_setFrameSize(lua_State* state) { +#ifdef __EMSCRIPTEN__ + //x.setAttribute("width", "320"); + //x.setAttribute("height", "240"); +#else VideoCapture *cap=checkCap(state,1); int w=luaL_checkinteger(state, 2); int h=luaL_checkinteger(state, 3); cap->set(CAP_PROP_FRAME_WIDTH, w); cap->set(CAP_PROP_FRAME_HEIGHT, h); - +#endif return 0; } int opencv_setBufferSize(lua_State* state) { +#ifdef __EMSCRIPTEN__ + +#else VideoCapture *cap=checkCap(state,1); int s=luaL_checkinteger(state, 2); cap->set(CAP_PROP_BUFFERSIZE, s); - +#endif return 0; } int opencv_write(lua_State* state) { +#ifdef __EMSCRIPTEN__ + +#else //UMat *ret=pushMat(state); VideoWriter *vw=checkWriter(state,1); UMat *ret=checkMat(state,2); @@ -457,11 +555,63 @@ int opencv_write(lua_State* state) success=0; } lua_pushinteger(state, success); +#endif return 1; } +lua_State* tmp_state; +int image_to_mat(int width, int height,uint8_t* data) +{ + UMat *ret=checkMat(tmp_state,2); + cv::Mat mat =cv::Mat(height,width, CV_8UC4, data); + + + mat.copyTo(*ret); + + int success=1; + if (ret->empty()) { + success=0; + } + + return success; +} + int opencv_frame(lua_State* state) { +#ifdef __EMSCRIPTEN__ + tmp_state=state; + const char *cap=luaL_checkstring(state, 1); + + //printf("VideoCapture id:%s\n",cap); + + int success=EM_ASM_INT({ + var video=document.getElementById(UTF8ToString($0)); + video.ctx.drawImage(video,0,0,video.width,video.height); + + //video.ctx.fillStyle = "#FF0000"; + //video.ctx.fillRect(0, 0, 150, 75); + + var data = video.ctx.getImageData(0,0,video.width,video.height).data; + //const uint8ArrData=new Uint8Array(data); + //console.log(data.length); + + var result = Module.ccall('image_to_mat', + 'number', + ['number','number','array'], + [video.width,video.height,data]); + + return result; + //uint8ArrData=new Uint8Array(imgData.data); + },cap); + + //ret->create() + //printf("Data : %d %d %d\n",data[0],data[1],data[2]); + + lua_pushinteger(state, success); +/*ctx.drawImage(video,0,0,video.width,video.height); + frame.data.set(ctx.getImageData(0,0,video.width,video.height).data)*/ + +#else //UMat *ret=pushMat(state); VideoCapture *cap=checkCap(state,1); UMat *ret=checkMat(state,2); @@ -472,6 +622,7 @@ int opencv_frame(lua_State* state) success=0; } lua_pushinteger(state, success); +#endif return 1; } @@ -512,7 +663,11 @@ int opencv_resize(lua_State* state) int rows=luaL_optinteger(state, 4, -1); // - if(in->empty()) return 0; + if(in->empty()) + { + printf("OpenCV Resize: Input image is empty\n"); + return 0; + } /*if(rows==-1 || cols==-1) resize(*in, *out,out->size()); @@ -533,14 +688,17 @@ int opencv_resize(lua_State* state) } else { cv::resize( *in, *out, cv::Size(w2, rows)); } - +#ifdef __EMSCRIPTEN__ + +#else int top = (rows - out->rows) / 2; int down = (rows - out->rows+1) / 2; int left = (cols - out->cols) / 2; int right = (cols - out->cols+1) / 2; + cv::copyMakeBorder(*out, *out, top, down, left, right, cv::BORDER_CONSTANT, 0 ); - +#endif return 0; } diff --git a/client/proteo_sdl.c b/client/proteo_sdl.c index 91b74c8..7f9bb0b 100644 --- a/client/proteo_sdl.c +++ b/client/proteo_sdl.c @@ -6,6 +6,9 @@ SDL_Window* gWindow = NULL; //SDL_Surface* gScreenSurface = NULL; SDL_Renderer* gRenderer = NULL; +SDL_GLContext gContext =NULL; +SDL_Texture *gTarget=NULL; + float gScale=1.0f; ProteoColor backgroundColor={255,0,0,0}; @@ -163,11 +166,15 @@ int initSDL() #if TARGET_OS_IPHONE gWindow = SDL_CreateWindow( NULL, 0, 0, 0, 0, SDL_WINDOW_SHOWN| SDL_WINDOW_BORDERLESS ); #else - gWindow = SDL_CreateWindow( "Proteo", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN/*|SDL_WINDOW_RESIZABLE*/ ); + gWindow = SDL_CreateWindow( "Proteo", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN|SDL_WINDOW_OPENGL/*|SDL_WINDOW_RESIZABLE*/ ); SDL_SetWindowResizable(gWindow,TRUE); #endif - - + +#ifdef USEOPENGL + SDL_SetHint(SDL_HINT_RENDER_DRIVER,"opengles2"); +#endif + printf("Hint render driver: %s\n",SDL_GetHint(SDL_HINT_RENDER_DRIVER)); + if( gWindow == NULL ) { printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError() ); @@ -178,11 +185,25 @@ int initSDL() //Get window surface //gScreenSurface = SDL_GetWindowSurface( gWindow ); - gRenderer = SDL_CreateRenderer( gWindow, -1, SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC); + gRenderer = SDL_CreateRenderer( gWindow, -1, SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC|SDL_RENDERER_TARGETTEXTURE); SDL_SetRenderDrawBlendMode(gRenderer,SDL_BLENDMODE_BLEND); } +#ifdef USEOPENGL + gContext = SDL_GL_CreateContext( gWindow ); + //SDL_GL_MakeCurrent(gWindow,gContext); + + gTarget = SDL_CreateTexture(gRenderer, SDL_PIXELFORMAT_RGBA8888, + SDL_TEXTUREACCESS_TARGET, SCREEN_WIDTH, SCREEN_HEIGHT); + //Initialize GLEW + glewExperimental = GL_TRUE; + GLenum glewError = glewInit(); + if( glewError != GLEW_OK ) + { + printf( "Error initializing GLEW! %s\n", glewGetErrorString( glewError ) ); + } +#endif if(opt_fullscreen) { SDL_SetWindowFullscreen(gWindow,SDL_WINDOW_FULLSCREEN_DESKTOP); @@ -231,7 +252,12 @@ void closeSDL() freesounds(); freeskeletons(); - SDL_DestroyRenderer(gRenderer); + SDL_GL_DeleteContext(gContext); + + SDL_DestroyTexture(gTarget); + gTarget=NULL; + + SDL_DestroyRenderer(gRenderer); gRenderer = NULL; SDL_DestroyWindow( gWindow ); diff --git a/client/proteo_shell_minimal.html b/client/proteo_shell_minimal.html index b643e8e..fa58479 100644 --- a/client/proteo_shell_minimal.html +++ b/client/proteo_shell_minimal.html @@ -145,7 +145,6 @@ - {{{ SCRIPT }}} diff --git a/client/proteo_system.c b/client/proteo_system.c index 958e4ee..a11aae9 100644 --- a/client/proteo_system.c +++ b/client/proteo_system.c @@ -74,7 +74,14 @@ static int system_fileexist(lua_State *state) { static int system_document(lua_State *state) { if(debug) printf("system.document\n"); //lua_pushliteral(state,"./"); +#if TARGET_OS_MAC + char path_doc[PATH_MAX]; + strcpy(path_doc,app_path); + strcat(path_doc,"/../../../"); + lua_pushlstring(state,path_doc,strlen(path_doc)); +#else lua_pushlstring(state,config.basedir,strlen(config.basedir)); +#endif return 1; } diff --git a/client/proteo_tensorflow.c b/client/proteo_tensorflow.c new file mode 100644 index 0000000..051e4bc --- /dev/null +++ b/client/proteo_tensorflow.c @@ -0,0 +1,378 @@ +//============================================================================== +// TENSORFLOW +//============================================================================== + +#define TFLITE_MODEL "TfLiteModel" +#define TFLITE_INTERPRETEROPTIONS "TfLiteInterpreterOptions" +#define TFLITE_INTERPRETER "TfLiteInterpreter" +#define TFLITE_TENSOR "TfLiteTensor" + +//============================================================================== +// CHECK +//============================================================================== + +static void *checkTFLModel (lua_State *state, int index) +{ + void *model; + luaL_checktype(state, index, LUA_TUSERDATA); + model = *(void**)luaL_checkudata(state, index, TFLITE_MODEL); + if (model == NULL) luaL_typerror(state, index, TFLITE_MODEL); + return model; +} + +static void *checkTFLInterpreterOptions (lua_State *state, int index) +{ + void *options; + luaL_checktype(state, index, LUA_TUSERDATA); + options = *(void**)luaL_checkudata(state, index, TFLITE_INTERPRETEROPTIONS); + if (options == NULL) luaL_typerror(state, index, TFLITE_INTERPRETEROPTIONS); + return options; +} + +static void *checkTFLInterpreter (lua_State *state, int index) +{ + void *interpreter; + luaL_checktype(state, index, LUA_TUSERDATA); + interpreter = *(void**)luaL_checkudata(state, index, TFLITE_INTERPRETER); + if (interpreter == NULL) luaL_typerror(state, index, TFLITE_INTERPRETER); + return interpreter; +} + +static TfLiteTensor *toTFLTensor (lua_State *state, int index) +{ + TfLiteTensor *tensor = (TfLiteTensor *)lua_touserdata(state, index); + if (tensor == NULL) luaL_typerror(state, index, TFLITE_TENSOR); + return tensor; +} + +static void *checkTFLTensor (lua_State *state, int index) +{ + TfLiteTensor *tensor=NULL; + + if(lua_islightuserdata(state, index)) + tensor=toTFLTensor(state,index); + else luaL_typerror(state, index, TFLITE_TENSOR); + + return tensor; +} + +//============================================================================== +// GC +//============================================================================== + +static int tflmodel_gc(lua_State *state) { + + void* model = checkTFLModel(state, 1); + + if(model!=NULL) + { + printf("TFLite Model release\n"); + TfLiteModelDelete(model); + } + + return 0; +} + +static int tflinterpreteroptions_gc(lua_State *state) { + + void* options = checkTFLInterpreterOptions(state, 1); + + if(options!=NULL) + { + printf("TFLite InterpreterOptions release\n"); + TfLiteInterpreterOptionsDelete(options); + } + + return 0; +} + +static int tflinterpreter_gc(lua_State *state) { + + void* interpreter = checkTFLInterpreter(state, 1); + + if(interpreter!=NULL) + { + printf("TFLite Interpreter release\n"); + TfLiteInterpreterDelete(interpreter); + } + + return 0; +} + +//============================================================================== +// PUSH +//============================================================================== + +static void * pushTFLModelFromFile (lua_State *state,const char *modelpath) +{ + TfLiteModel* model = TfLiteModelCreateFromFile(modelpath); + if(model==NULL) printf("TfLiteModelCreateFromFile error\n"); + + *(void**)lua_newuserdata(state, sizeof(void*)) = model; + + if(luaL_newmetatable(state, TFLITE_MODEL)){ + lua_pushcfunction(state, tflmodel_gc); + lua_setfield(state, -2, "__gc"); + } + lua_setmetatable(state, -2); + + return model; +} + +static void * pushTFLInterpreterOptions (lua_State *state) +{ + TfLiteInterpreterOptions* options = TfLiteInterpreterOptionsCreate(); + if(options==NULL) printf("TfLiteInterpreterOptionsCreate error\n"); + + *(void**)lua_newuserdata(state, sizeof(void*)) = options; + + if(luaL_newmetatable(state, TFLITE_INTERPRETEROPTIONS)){ + lua_pushcfunction(state, tflinterpreteroptions_gc); + lua_setfield(state, -2, "__gc"); + } + lua_setmetatable(state, -2); + + return options; +} + +static void * pushTFLInterpreter (lua_State *state,const TfLiteModel* model, const TfLiteInterpreterOptions* optional_options) +{ + TfLiteInterpreter* interpreter = TfLiteInterpreterCreate(model,optional_options); + if(interpreter==NULL) printf("TfLiteInterpreterCreate error\n"); + + *(void**)lua_newuserdata(state, sizeof(void*)) = interpreter; + + if(luaL_newmetatable(state, TFLITE_INTERPRETER)){ + lua_pushcfunction(state, tflinterpreter_gc); + lua_setfield(state, -2, "__gc"); + } + lua_setmetatable(state, -2); + + return interpreter; +} + +static void * pushTFLInterpreterInputTensor (lua_State *state,TfLiteInterpreter* interpreter,int index) +{ + TfLiteTensor* input_tensor = + TfLiteInterpreterGetInputTensor(interpreter, index); + + if(input_tensor==NULL) printf("TfLiteInterpreterGetInputTensor error \n"); + + lua_pushlightuserdata(state, input_tensor); + + return input_tensor; +} + +static void * pushTFLInterpreterOutputTensor (lua_State *state,TfLiteInterpreter* interpreter,int index) +{ + TfLiteTensor* output_tensor = + TfLiteInterpreterGetOutputTensor(interpreter, index); + + if(output_tensor==NULL) printf("TfLiteInterpreterGetOutputTensor error \n"); + + lua_pushlightuserdata(state, output_tensor); + + return output_tensor; +} + +//============================================================================== +// TFLITE +//============================================================================== + +static int tflite_modelfromfile(lua_State *state) { + + const char* modelfile=luaL_checkstring(state,1); + + TfLiteModel* model = pushTFLModelFromFile(state,modelfile); + return 1; +} + +static int tflite_createinterpreteroptions(lua_State *state) { + + TfLiteInterpreterOptions* options = pushTFLInterpreterOptions(state); + return 1; +} + +static int tflite_createinterpreter(lua_State *state) { + + TfLiteModel* model=checkTFLModel(state, 1); + TfLiteInterpreterOptions* options =checkTFLInterpreterOptions(state, 2); + + TfLiteInterpreter* interpreter = pushTFLInterpreter(state,model,options); + + return 1; +} + +static int tflite_interpreterallocatetensors(lua_State *state) { + + TfLiteInterpreter* interpreter = checkTFLInterpreter(state,1); + TfLiteStatus ret=TfLiteInterpreterAllocateTensors(interpreter); + if(ret!=kTfLiteOk) + { + if(debug) printf("TFLite AllocateTensor error \n"); + } + return 0; +} + +static int tflite_interpretergetinputtensor(lua_State *state) { + + TfLiteInterpreter* interpreter = checkTFLInterpreter(state,1); + int index=luaL_checkinteger(state, 2); + TfLiteTensor* input_tensor = pushTFLInterpreterInputTensor(state,interpreter,index); + + return 1; +} + +static int tflite_interpretergetoutputtensor(lua_State *state) { + + TfLiteInterpreter* interpreter = checkTFLInterpreter(state,1); + int index=luaL_checkinteger(state, 2); + TfLiteTensor* output_tensor = pushTFLInterpreterOutputTensor(state,interpreter,index); + + return 1; +} + +static int tflite_gettensorsize(lua_State *state) +{ + /*int ndim=TfLiteTensorNumDims(tensor); + printf("Tensor size(%d",TfLiteTensorDim(tensor,0)); + for(int i=1;i> 24) & 0xff; + col.r = (value >> 16) & 0xff; + col.g = (value >> 8) & 0xff; + col.b = (value >> 0) & 0xff; + //return color; + + return col; +} + +void mkpath(const char* dir) { + char tmp[256]; + char *p = NULL; + size_t len; + + snprintf(tmp, sizeof(tmp),"%s",dir); + dirname(tmp); + len = strlen(tmp); + if(tmp[len - 1] == '/') + tmp[len - 1] = 0; + for(p = tmp + 1; *p; p++) + if(*p == '/') { + *p = 0; + #if TARGET_OS_WINDOWS //defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined(__MINGW64__) + _mkdir(tmp); + #else + int ret=mkdir(tmp, S_IRWXU); + #endif + *p = '/'; + } + #if TARGET_OS_WINDOWS //defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined(__MINGW64__) + _mkdir(tmp); + #else + int ret=mkdir(tmp, S_IRWXU); + + #endif +} + +int writefile(char* filename,char* data) +{ + FILE *handler=fopen(filename,"w"); + if (handler) + { + fprintf(handler,"%s",data); + fclose(handler); + return 0; + } + else printf("Write file %s error: %s\n",filename,strerror(errno)); + + return 1; +} + +int writedatafile(char* filename,char* data,int data_size) +{ + int write_size; + FILE *handler=fopen(filename,"wb"); + if (handler) + { + write_size = fwrite(data, sizeof(char), data_size, handler); + fclose(handler); + if(debug) printf("Write data file: %s,%d,%d\n",filename,data_size,write_size); + return write_size; + } + else printf("Write data %s error: %s\n",filename,strerror(errno)); + + return 0; +} + +char* loadfile(char *filename) +{ + char *buffer = NULL; + int string_size, read_size; + FILE *handler = fopen(filename, "r"); + + if (handler) + { + fseek(handler, 0, SEEK_END); + string_size = ftell(handler); + rewind(handler); + + buffer = (char*) malloc(sizeof(char) * (string_size + 1) ); + if(buffer!=NULL) + { + read_size = fread(buffer, sizeof(char), string_size, handler); + buffer[string_size] = '\0'; + + if (string_size != read_size) + { + free(buffer); + buffer = NULL; + } + } + + fclose(handler); + } + else printf("Load file %s error: %s\n",filename,strerror(errno)); + + return buffer; +} + +int loaddatafile(char *filename,char **buffer) +{ + int data_size, read_size; + FILE *handler = fopen(filename, "r"); + + if (handler) + { + fseek(handler, 0, SEEK_END); + data_size = ftell(handler); + rewind(handler); + + *buffer = (char*) malloc(sizeof(char) * (data_size) ); + if(buffer!=NULL) + { + read_size = fread(*buffer, sizeof(char), data_size, handler); + + if (data_size != read_size) + { + free(*buffer); + *buffer = NULL; + return 0; + } + //if(debug) printf("Load data file: %s,%d,%d\n",filename,data_size,read_size); + if(debug) printf("Load data file: %s\n",filename); + } + fclose(handler); + } + else printf("Load data %s error: %s\n",filename,strerror(errno)); + + return read_size; +} + +void hexDump (const char * desc, const void * addr, const int len) { + int i; + unsigned char buff[17]; + const unsigned char * pc = (const unsigned char *)addr; + + // Output description if given. + + if (desc != NULL) + printf ("%s:\n", desc); + + // Length checks. + + if (len == 0) { + printf(" ZERO LENGTH\n"); + return; + } + else if (len < 0) { + printf(" NEGATIVE LENGTH: %d\n", len); + return; + } + + // Process every byte in the data. + + for (i = 0; i < len; i++) { + // Multiple of 16 means new line (with line offset). + + if ((i % 16) == 0) { + // Don't print ASCII buffer for the "zeroth" line. + + if (i != 0) + printf (" %s\n", buff); + + // Output the offset. + + printf (" %04x ", i); + } + + // Now the hex code for the specific character. + printf (" %02x", pc[i]); + + // And buffer a printable ASCII character for later. + + if ((pc[i] < 0x20) || (pc[i] > 0x7e)) // isprint() may be better. + buff[i % 16] = '.'; + else + buff[i % 16] = pc[i]; + buff[(i % 16) + 1] = '\0'; + } + + // Pad out last line if not exactly 16 characters. + + while ((i % 16) != 0) { + printf (" "); + i++; + } + + // And print the final ASCII buffer. + + printf (" %s\n", buff); +} + +char* concat(const char *s1, const char *s2) +{ + const size_t len1 = strlen(s1); + const size_t len2 = strlen(s2); + char *result = malloc(len1 + len2 + 1); + + if(result!=NULL) + { + memcpy(result, s1, len1); + memcpy(result + len1, s2, len2 + 1); + } + result[len1 + len2]=0; + + return result; +} + +char* concat3(const char *s1, const char *s2, const char *s3) +{ + const size_t len1 = strlen(s1); + const size_t len2 = strlen(s2); + const size_t len3 = strlen(s3); + + char *result = malloc(len1 + len2 + len3 + 1); + + if(result!=NULL) + { + memcpy(result, s1, len1); + memcpy(result + len1, s2, len2); + memcpy(result + len1 + len2, s3, len3 + 1); // +1 to copy the null-terminator + } + result[len1 + len2 + len3]=0; + + return result; +} + +int c_quote(const char* src, char* dest, int maxlen) { + int count = 0; + if(maxlen < 0) { + maxlen = strlen(src)+1; /* add 1 for NULL-terminator */ + } + + while(src && maxlen > 0) { + switch(*src) { + + /* these normal, printable chars just need a slash appended */ + case '\\': + case '\"': + case '\'': + if(dest) { + *dest++ = '\\'; + *dest++ = *src; + } + count += 2; + break; + + /* newlines/tabs and unprintable characters need a special code. + * Use the macro CASE_CHAR defined below. + * The first arg for the macro is the char to compare to, + * the 2nd arg is the char to put in the result string, after the '\' */ +#define CASE_CHAR(c, d) case c:\ + if(dest) {\ + *dest++ = '\\'; *dest++ = (d);\ + }\ +count += 2;\ +break; + /* -------------- */ + CASE_CHAR('\n', 'n'); + CASE_CHAR('\t', 't'); + CASE_CHAR('\b', 'b'); + /* ------------- */ + +#undef CASE_CHAR + + + /* by default, just copy the char over */ + default: + if(dest) { + *dest++ = *src; + } + count++; + } + + ++src; + --maxlen; + } + return count; +} + +//simple encrypt-decrypt function +void encryptDecrypt(char inpString[]) +{ + char xorKey[] = "Key"; + int len = strlen(inpString); + + for (int i = 0; i < len; i++) + { + inpString[i] = inpString[i] ^ xorKey[i%strlen(xorKey)]; + printf("%c",inpString[i]); + } +} + +#ifdef AFFINE +SDL_Point affineTrasformation(SDL_Point point,float affine[3][3]) +{ + SDL_Point ret; + + ret.x=point.x*affine[0][0]+point.y*affine[1][0]+affine[2][0]; + ret.y=point.x*affine[0][1]+point.y*affine[1][1]+affine[2][1]; + + return ret; +} +#endif + +void mult_matrices(float a[3][3], float b[3][3], float result[3][3]) +{ + int i, j, k; + for(i = 0; i < 3; i++) + { + for(j = 0; j < 3; j++) + { + for(k = 0; k < 3; k++) + { + result[i][j] += a[i][k] * b[k][j]; + } + } + } +} + + +void laderman_mul(const float a[3][3],const float b[3][3],float c[3][3]) { + + float m[24]; // not off by one, just wanted to match the index from the paper + + m[1 ]= (a[0][0]+a[0][1]+a[0][2]-a[1][0]-a[1][1]-a[2][1]-a[2][2])*b[1][1]; + m[2 ]= (a[0][0]-a[1][0])*(-b[0][1]+b[1][1]); + m[3 ]= a[1][1]*(-b[0][0]+b[0][1]+b[1][0]-b[1][1]-b[1][2]-b[2][0]+b[2][2]); + m[4 ]= (-a[0][0]+a[1][0]+a[1][1])*(b[0][0]-b[0][1]+b[1][1]); + m[5 ]= (a[1][0]+a[1][1])*(-b[0][0]+b[0][1]); + m[6 ]= a[0][0]*b[0][0]; + m[7 ]= (-a[0][0]+a[2][0]+a[2][1])*(b[0][0]-b[0][2]+b[1][2]); + m[8 ]= (-a[0][0]+a[2][0])*(b[0][2]-b[1][2]); + m[9 ]= (a[2][0]+a[2][1])*(-b[0][0]+b[0][2]); + m[10]= (a[0][0]+a[0][1]+a[0][2]-a[1][1]-a[1][2]-a[2][0]-a[2][1])*b[1][2]; + m[11]= a[2][1]*(-b[0][0]+b[0][2]+b[1][0]-b[1][1]-b[1][2]-b[2][0]+b[2][1]); + m[12]= (-a[0][2]+a[2][1]+a[2][2])*(b[1][1]+b[2][0]-b[2][1]); + m[13]= (a[0][2]-a[2][2])*(b[1][1]-b[2][1]); + m[14]= a[0][2]*b[2][0]; + m[15]= (a[2][1]+a[2][2])*(-b[2][0]+b[2][1]); + m[16]= (-a[0][2]+a[1][1]+a[1][2])*(b[1][2]+b[2][0]-b[2][2]); + m[17]= (a[0][2]-a[1][2])*(b[1][2]-b[2][2]); + m[18]= (a[1][1]+a[1][2])*(-b[2][0]+b[2][2]); + m[19]= a[0][1]*b[1][0]; + m[20]= a[1][2]*b[2][1]; + m[21]= a[1][0]*b[0][2]; + m[22]= a[2][0]*b[0][1]; + m[23]= a[2][2]*b[2][2]; + + c[0][0] = m[6]+m[14]+m[19]; + c[0][1] = m[1]+m[4]+m[5]+m[6]+m[12]+m[14]+m[15]; + c[0][2] = m[6]+m[7]+m[9]+m[10]+m[14]+m[16]+m[18]; + c[1][0] = m[2]+m[3]+m[4]+m[6]+m[14]+m[16]+m[17]; + c[1][1] = m[2]+m[4]+m[5]+m[6]+m[20]; + c[1][2] = m[14]+m[16]+m[17]+m[18]+m[21]; + c[2][0] = m[6]+m[7]+m[8]+m[11]+m[12]+m[13]+m[14]; + c[2][1] = m[12]+m[13]+m[14]+m[15]+m[22]; + c[2][2] = m[6]+m[7]+m[8]+m[9]+m[23]; +} + +SDL_FPoint I2FPoint(SDL_Point p) +{ + SDL_FPoint ret={p.x,p.y}; + return ret; +} +SDL_Point F2IPoint(SDL_FPoint p) +{ + SDL_Point ret={p.x,p.y}; + return ret; +} +SDL_FPoint subtract(SDL_FPoint p0, SDL_FPoint p1) +{ + SDL_FPoint ret={p0.x-p1.x,p0.y-p1.y}; + + return ret; +} + +SDL_FPoint sum(SDL_FPoint p0, SDL_FPoint p1) +{ + SDL_FPoint ret={p0.x+p1.x,p0.y+p1.y}; + + return ret; +} + +SDL_FPoint multiply(SDL_FPoint p, float f) +{ + SDL_FPoint ret={p.x*f,p.y*f}; + + return ret; +} + +float dot(SDL_FPoint p0, SDL_FPoint p1) +{ + float ret=(p0.x*p1.x)+(p0.y*p1.y); + + return ret; +} + +float distance(SDL_FPoint p0,SDL_FPoint p1) +{ + return hypotf(p0.x-p1.x,p0.y-p1.y); +} + +SDL_FPoint normalize(SDL_FPoint p) +{ + float mag=hypotf(p.x,p.y); + SDL_FPoint ret={p.x/mag,p.y/mag}; + + //problema di normalizzazione? vettore spesso 0 + return ret; +} + +float magnitude(SDL_FPoint p) +{ + float len=hypotf(p.x,p.y); + + return len; +} + +SDL_FPoint getClosestPointOnSegment(SDL_FPoint p0, SDL_FPoint p1, SDL_FPoint p) +{ + SDL_FPoint d=subtract(p1,p0); + float c=dot(subtract(p,p0),d)/dot(d,d); + if(c>=1) return p1; + else if(c<=0) return p0; + else return sum(p0,multiply(d,c)); +} + +/*static getClosestPointOnSegment(p0, p1, p) { + let d = p1.subtract(p0); + let c = p.subtract(p0).dot(d) / (d.dot(d)); + if (c >= 1) { + return p1.clone(); + } else if (c <= 0) { + return p0.clone(); + } else { + return p0.add(d.multiply(c)); + } +} +*/ diff --git a/client/update.sh b/client/update.sh deleted file mode 100755 index 3f561cd..0000000 --- a/client/update.sh +++ /dev/null @@ -1,6 +0,0 @@ -git pull -cd build -cmake -DCMAKE_BUILD_TYPE=Debug -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl .. -make -cp ./proteo ../ -cd .. diff --git a/client/upload.sh b/client/upload.sh deleted file mode 100755 index ba9e24d..0000000 --- a/client/upload.sh +++ /dev/null @@ -1,3 +0,0 @@ -git stage * -git commit -git push diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 451d291..43e9e76 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -13,8 +13,7 @@ find_package(CURL REQUIRED) find_package(JSONC REQUIRED) find_package(libmicrohttpd REQUIRED) find_package(SQLite3 REQUIRED) -#find_package(ENet REQUIRED) -find_package(EJDB REQUIRED) +find_package(EJDB) find_package (Threads) find_package(OpenCV REQUIRED) find_package(ZeroMQ REQUIRED) @@ -42,19 +41,71 @@ tensorflowlite HINTS ${CMAKE_SOURCE_DIR}/tflite/lib /usr/lib -/usr/local/lib REQUIRED) +/usr/local/lib) +find_path(DeepSpeech_INCLUDE_DIR +NAMES +deepspeech +HINTS +${CMAKE_SOURCE_DIR}/deepspeech/include +/usr/local/include) + +find_library(DeepSpeech_LIBRARY +NAMES +deepspeech +HINTS +${CMAKE_SOURCE_DIR}/deepspeech/lib +/usr/lib +/usr/local/lib) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(DEEPSPEECH DEFAULT_MSG DeepSpeech_INCLUDE_DIR) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(TFLITE DEFAULT_MSG TensorFlowLite_INCLUDE_DIR) + +if (OpenCV_VERSION_MAJOR GREATER 4) + add_definitions(-DOPENCV_DNN) +endif() -include_directories(${TensorFlowLite_INCLUDE_DIR} ${AVUTIL_INCLUDE_DIR} ${SWSCALE_INCLUDE_DIR} ${AVCODEC_INCLUDE_DIR} ${LUAJIT_INCLUDE_DIR} ${OPENSSL_INCLUDE_DIR} ${CURL_INCLUDE_DIRS} ${JSONC_INCLUDE_DIRS} ${LIBMICROHTTPD_INCLUDE_DIRS} ${SQLite3_INCLUDE_DIRS} ${EJDB_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS} ${ZMQ_INCLUDE_DIRS}) #${ENET_INCLUDE_DIRS} +if(ejdb2_FOUND) + include_directories(${EJDB_INCLUDE_DIRS}) + add_definitions(-DEJDB2) +endif() + +if(DEEPSPEECH_FOUND) + include_directories(${DeepSpeech_INCLUDE_DIR}) + add_definitions(-DDEEPSPEECH) +endif() + +if(TFLITE_FOUND) + include_directories(${TensorFlowLite_INCLUDE_DIR}) + add_definitions(-DTFLITE) +endif() + +include_directories(${AVUTIL_INCLUDE_DIR} ${SWSCALE_INCLUDE_DIR} ${AVCODEC_INCLUDE_DIR} ${LUAJIT_INCLUDE_DIR} ${OPENSSL_INCLUDE_DIR} ${CURL_INCLUDE_DIRS} ${JSONC_INCLUDE_DIRS} ${LIBMICROHTTPD_INCLUDE_DIRS} ${SQLite3_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS} ${ZMQ_INCLUDE_DIRS}) #include_directories(${CMAKE_SOURCE_DIR}/darknet) #link_directories(${CMAKE_SOURCE_DIR}/darknet) -#include_directories(${CMAKE_SOURCE_DIR}/tflite/include) -#link_directories(${CMAKE_SOURCE_DIR}/tflite/lib) - #link_directories(${CMAKE_SOURCE_DIR}/usr/local/opt/curl/lib) add_executable(proteo_server proteo_server.c proteo_opencv.cpp) -target_link_libraries(proteo_server ${TensorFlowLite_LIBRARY} ${AVUTIL_LIBRARY} ${SWSCALE_LIBRARY} ${AVCODEC_LIBRARY} ${OPENSSL_LIBRARIES} ${LUAJIT_LIBRARIES} ${CURL_LIBRARIES} ${JSONC_LIBRARIES} ${LIBMICROHTTPD_LIBRARIES} ${SQLite3_LIBRARIES} ${EJDB_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${OpenCV_LIBS} ${ZMQ_LIBRARIES})# dark ${ENET_LIBRARIES} +if(ejdb2_FOUND) + target_link_libraries(proteo_server ${EJDB_LIBRARIES}) +endif() + +if(DEEPSPEECH_FOUND) + target_link_libraries(proteo_server ${DeepSpeech_LIBRARY}) +endif() + +if(TFLITE_FOUND) + target_link_libraries(proteo_server ${TensorFlowLite_LIBRARY}) +endif() + +target_link_libraries(proteo_server ${AVUTIL_LIBRARY} ${SWSCALE_LIBRARY} ${AVCODEC_LIBRARY} ${OPENSSL_LIBRARIES} ${LUAJIT_LIBRARIES} ${CURL_LIBRARIES} ${JSONC_LIBRARIES} ${LIBMICROHTTPD_LIBRARIES} ${SQLite3_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${OpenCV_LIBS} ${ZMQ_LIBRARIES}) + +#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -latomic") + +SET(CPACK_DEBIAN_PACKAGE_DEPENDS libluajit-5.1-dev ,libssl-dev,libcurl4-openssl-dev,libjson-c-dev,libmicrohttpd-dev,libsqlite3-dev,ejdb2,libopencv-dev,libzmq3-dev,libavcodec-dev,libavformat-dev,libavutil-dev,libswresample-dev,libswscale-dev) +SET(CPACK_GENERATOR "DEB") +SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "M") +INCLUDE(CPack) diff --git a/server/install.sh b/server/install.sh index 3ec5aa2..ada26df 100755 --- a/server/install.sh +++ b/server/install.sh @@ -1,13 +1,21 @@ systemctl stop proteo cp ./build/proteo_server /usr/local/bin/ -rm -r /usr/local/etc/proteo -mkdir /usr/local/etc/proteo -cp -r ./lib /usr/local/etc/proteo/ -cp -r ./plugin /usr/local/etc/proteo/ -cp -r ./script /usr/local/etc/proteo/ -cp -r ./web /usr/local/etc/proteo/ -cp favicon.ico /usr/local/etc/proteo/ -cp login.lua /usr/local/etc/proteo/ -cp route.lua /usr/local/etc/proteo/ + +cp /usr/local/etc/Proteo/config.json ./config.bkp || : + +rm -rf /usr/local/etc/Proteo +mkdir /usr/local/etc/Proteo +cp -r ./lib /usr/local/etc/Proteo/ +cp -r ./plugin /usr/local/etc/Proteo/ +cp -r ./script /usr/local/etc/Proteo/ +cp -r ./web /usr/local/etc/Proteo/ +cp -r ./dl /usr/local/etc/Proteo/ +cp favicon.ico /usr/local/etc/Proteo/ +cp login.lua /usr/local/etc/Proteo/ +cp route.lua /usr/local/etc/Proteo/ +cp ticket.lua /usr/local/etc/Proteo/ +cp debugger.lua /usr/local/etc/Proteo/ +cp config.json /usr/local/etc/Proteo/ + cp ./proteo.service /etc/systemd/system/ systemctl start proteo diff --git a/server/lib/FormatMini.lua b/server/lib/FormatMini.lua deleted file mode 100644 index 4d04602..0000000 --- a/server/lib/FormatMini.lua +++ /dev/null @@ -1,365 +0,0 @@ - -local parser = require'ParseLua' -local ParseLua = parser.ParseLua -local util = require'Util' -local lookupify = util.lookupify - --- --- FormatMini.lua --- --- Returns the minified version of an AST. Operations which are performed: --- - All comments and whitespace are ignored --- - All local variables are renamed --- - -local LowerChars = lookupify{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', - 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', - 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'} -local UpperChars = lookupify{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', - 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', - 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'} -local Digits = lookupify{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'} -local Symbols = lookupify{'+', '-', '*', '/', '^', '%', ',', '{', '}', '[', ']', '(', ')', ';', '#'} - -local function Format_Mini(ast) - local formatStatlist, formatExpr; - local count = 0 - -- - local function joinStatementsSafe(a, b, sep) - --print(a, b) - if count > 150 then - count = 0 - return a.."\n"..b - end - sep = sep or ' ' - local aa, bb = a:sub(-1,-1), b:sub(1,1) - if UpperChars[aa] or LowerChars[aa] or aa == '_' then - if not (UpperChars[bb] or LowerChars[bb] or bb == '_' or Digits[bb]) then - --bb is a symbol, can join without sep - return a..b - elseif bb == '(' then - print("==============>>>",aa,bb) - --prevent ambiguous syntax - return a..sep..b - else - return a..sep..b - end - elseif Digits[aa] then - if bb == '(' then - --can join statements directly - return a..b - elseif Symbols[bb] then - return a .. b - else - return a..sep..b - end - elseif aa == '' then - return a..b - else - if bb == '(' then - --don't want to accidentally call last statement, can't join directly - return a..sep..b - else - --print("asdf", '"'..a..'"', '"'..b..'"') - return a..b - end - end - end - - formatExpr = function(expr, precedence) - local precedence = precedence or 0 - local currentPrecedence = 0 - local skipParens = false - local out = "" - if expr.AstType == 'VarExpr' then - if expr.Variable then - out = out..expr.Variable.Name - else - out = out..expr.Name - end - - elseif expr.AstType == 'NumberExpr' then - out = out..expr.Value.Data - - elseif expr.AstType == 'StringExpr' then - out = out..expr.Value.Data - - elseif expr.AstType == 'BooleanExpr' then - out = out..tostring(expr.Value) - - elseif expr.AstType == 'NilExpr' then - out = joinStatementsSafe(out, "nil") - - elseif expr.AstType == 'BinopExpr' then - currentPrecedence = expr.OperatorPrecedence - out = joinStatementsSafe(out, formatExpr(expr.Lhs, currentPrecedence)) - out = joinStatementsSafe(out, expr.Op) - out = joinStatementsSafe(out, formatExpr(expr.Rhs)) - if expr.Op == '^' or expr.Op == '..' then - currentPrecedence = currentPrecedence - 1 - end - - if currentPrecedence < precedence then - skipParens = false - else - skipParens = true - end - --print(skipParens, precedence, currentPrecedence) - elseif expr.AstType == 'UnopExpr' then - out = joinStatementsSafe(out, expr.Op) - out = joinStatementsSafe(out, formatExpr(expr.Rhs)) - - elseif expr.AstType == 'DotsExpr' then - out = out.."..." - - elseif expr.AstType == 'CallExpr' then - out = out..formatExpr(expr.Base) - out = out.."(" - for i = 1, #expr.Arguments do - out = out..formatExpr(expr.Arguments[i]) - if i ~= #expr.Arguments then - out = out.."," - end - end - out = out..")" - - elseif expr.AstType == 'TableCallExpr' then - out = out..formatExpr(expr.Base) - out = out..formatExpr(expr.Arguments[1]) - - elseif expr.AstType == 'StringCallExpr' then - out = out..formatExpr(expr.Base) - out = out..expr.Arguments[1].Data - - elseif expr.AstType == 'IndexExpr' then - out = out..formatExpr(expr.Base).."["..formatExpr(expr.Index).."]" - - elseif expr.AstType == 'MemberExpr' then - out = out..formatExpr(expr.Base)..expr.Indexer..expr.Ident.Data - - elseif expr.AstType == 'Function' then - expr.Scope:ObfuscateVariables() - out = out.."function(" - if #expr.Arguments > 0 then - for i = 1, #expr.Arguments do - out = out..expr.Arguments[i].Name - if i ~= #expr.Arguments then - out = out.."," - elseif expr.VarArg then - out = out..",..." - end - end - elseif expr.VarArg then - out = out.."..." - end - out = out..")" - out = joinStatementsSafe(out, formatStatlist(expr.Body)) - out = joinStatementsSafe(out, "end") - - elseif expr.AstType == 'ConstructorExpr' then - out = out.."{" - for i = 1, #expr.EntryList do - local entry = expr.EntryList[i] - if entry.Type == 'Key' then - out = out.."["..formatExpr(entry.Key).."]="..formatExpr(entry.Value) - elseif entry.Type == 'Value' then - out = out..formatExpr(entry.Value) - elseif entry.Type == 'KeyString' then - out = out..entry.Key.."="..formatExpr(entry.Value) - end - if i ~= #expr.EntryList then - out = out.."," - end - end - out = out.."}" - - elseif expr.AstType == 'Parentheses' then - out = out.."("..formatExpr(expr.Inner)..")" - - end - --print(">>", skipParens, expr.ParenCount, out) - if not skipParens then - --print("hehe") - out = string.rep('(', expr.ParenCount or 0) .. out - out = out .. string.rep(')', expr.ParenCount or 0) - --print("", out) - end - count = count + #out - return --[[print(out) or]] out - end - - local formatStatement = function(statement) - local out = '' - if statement.AstType == 'AssignmentStatement' then - for i = 1, #statement.Lhs do - out = out..formatExpr(statement.Lhs[i]) - if i ~= #statement.Lhs then - out = out.."," - end - end - if #statement.Rhs > 0 then - out = out.."=" - for i = 1, #statement.Rhs do - out = out..formatExpr(statement.Rhs[i]) - if i ~= #statement.Rhs then - out = out.."," - end - end - end - - elseif statement.AstType == 'CallStatement' then - out = formatExpr(statement.Expression) - - elseif statement.AstType == 'LocalStatement' then - out = out.."local " - for i = 1, #statement.LocalList do - out = out..statement.LocalList[i].Name - if i ~= #statement.LocalList then - out = out.."," - end - end - if #statement.InitList > 0 then - out = out.."=" - for i = 1, #statement.InitList do - out = out..formatExpr(statement.InitList[i]) - if i ~= #statement.InitList then - out = out.."," - end - end - end - - elseif statement.AstType == 'IfStatement' then - out = joinStatementsSafe("if", formatExpr(statement.Clauses[1].Condition)) - out = joinStatementsSafe(out, "then") - out = joinStatementsSafe(out, formatStatlist(statement.Clauses[1].Body)) - for i = 2, #statement.Clauses do - local st = statement.Clauses[i] - if st.Condition then - out = joinStatementsSafe(out, "elseif") - out = joinStatementsSafe(out, formatExpr(st.Condition)) - out = joinStatementsSafe(out, "then") - else - out = joinStatementsSafe(out, "else") - end - out = joinStatementsSafe(out, formatStatlist(st.Body)) - end - out = joinStatementsSafe(out, "end") - - elseif statement.AstType == 'WhileStatement' then - out = joinStatementsSafe("while", formatExpr(statement.Condition)) - out = joinStatementsSafe(out, "do") - out = joinStatementsSafe(out, formatStatlist(statement.Body)) - out = joinStatementsSafe(out, "end") - - elseif statement.AstType == 'DoStatement' then - out = joinStatementsSafe(out, "do") - out = joinStatementsSafe(out, formatStatlist(statement.Body)) - out = joinStatementsSafe(out, "end") - - elseif statement.AstType == 'ReturnStatement' then - out = "return" - for i = 1, #statement.Arguments do - out = joinStatementsSafe(out, formatExpr(statement.Arguments[i])) - if i ~= #statement.Arguments then - out = out.."," - end - end - - elseif statement.AstType == 'BreakStatement' then - out = "break" - - elseif statement.AstType == 'RepeatStatement' then - out = "repeat" - out = joinStatementsSafe(out, formatStatlist(statement.Body)) - out = joinStatementsSafe(out, "until") - out = joinStatementsSafe(out, formatExpr(statement.Condition)) - - elseif statement.AstType == 'Function' then - statement.Scope:ObfuscateVariables() - if statement.IsLocal then - out = "local" - end - out = joinStatementsSafe(out, "function ") - if statement.IsLocal then - out = out..statement.Name.Name - else - out = out..formatExpr(statement.Name) - end - out = out.."(" - if #statement.Arguments > 0 then - for i = 1, #statement.Arguments do - out = out..statement.Arguments[i].Name - if i ~= #statement.Arguments then - out = out.."," - elseif statement.VarArg then - --print("Apply vararg") - out = out..",..." - end - end - elseif statement.VarArg then - out = out.."..." - end - out = out..")" - out = joinStatementsSafe(out, formatStatlist(statement.Body)) - out = joinStatementsSafe(out, "end") - - elseif statement.AstType == 'GenericForStatement' then - statement.Scope:ObfuscateVariables() - out = "for " - for i = 1, #statement.VariableList do - out = out..statement.VariableList[i].Name - if i ~= #statement.VariableList then - out = out.."," - end - end - out = out.." in" - for i = 1, #statement.Generators do - out = joinStatementsSafe(out, formatExpr(statement.Generators[i])) - if i ~= #statement.Generators then - out = joinStatementsSafe(out, ',') - end - end - out = joinStatementsSafe(out, "do") - out = joinStatementsSafe(out, formatStatlist(statement.Body)) - out = joinStatementsSafe(out, "end") - - elseif statement.AstType == 'NumericForStatement' then - statement.Scope:ObfuscateVariables() - out = "for " - out = out..statement.Variable.Name.."=" - out = out..formatExpr(statement.Start)..","..formatExpr(statement.End) - if statement.Step then - out = out..","..formatExpr(statement.Step) - end - out = joinStatementsSafe(out, "do") - out = joinStatementsSafe(out, formatStatlist(statement.Body)) - out = joinStatementsSafe(out, "end") - elseif statement.AstType == 'LabelStatement' then - out = getIndentation() .. "::" .. statement.Label .. "::" - elseif statement.AstType == 'GotoStatement' then - out = getIndentation() .. "goto " .. statement.Label - elseif statement.AstType == 'Comment' then - -- ignore - elseif statement.AstType == 'Eof' then - -- ignore - else - print("Unknown AST Type: " .. statement.AstType) - end - count = count + #out - return out - end - - formatStatlist = function(statList) - local out = '' - statList.Scope:ObfuscateVariables() - for _, stat in pairs(statList.Body) do - out = joinStatementsSafe(out, formatStatement(stat), ';') - end - return out - end - - ast.Scope:ObfuscateVariables() - return formatStatlist(ast) -end - -return Format_Mini diff --git a/server/lib/ParseLua.lua b/server/lib/ParseLua.lua deleted file mode 100644 index 6af7ee4..0000000 --- a/server/lib/ParseLua.lua +++ /dev/null @@ -1,1411 +0,0 @@ - --- --- ParseLua.lua --- --- The main lua parser and lexer. --- LexLua returns a Lua token stream, with tokens that preserve --- all whitespace formatting information. --- ParseLua returns an AST, internally relying on LexLua. --- - -require'strict' - -local util = require'Util' -local lookupify = util.lookupify - -local WhiteChars = lookupify{' ', '\n', '\t', '\r'} -local EscapeLookup = {['\r'] = '\\r', ['\n'] = '\\n', ['\t'] = '\\t', ['"'] = '\\"', ["'"] = "\\'"} -local LowerChars = lookupify{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', - 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', - 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'} -local UpperChars = lookupify{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', - 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', - 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'} -local Digits = lookupify{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'} -local HexDigits = lookupify{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'A', 'a', 'B', 'b', 'C', 'c', 'D', 'd', 'E', 'e', 'F', 'f'} - -local Symbols = lookupify{'+', '-', '*', '/', '^', '%', ',', '{', '}', '[', ']', '(', ')', ';', '#'} -local Scope = require'Scope' - -local Keywords = lookupify{ - 'and', 'break', 'do', 'else', 'elseif', - 'end', 'false', 'for', 'function', 'goto', 'if', - 'in', 'local', 'nil', 'not', 'or', 'repeat', - 'return', 'then', 'true', 'until', 'while', -}; - -local function LexLua(src) - --token dump - local tokens = {} - - local st, err = pcall(function() - --line / char / pointer tracking - local p = 1 - local line = 1 - local char = 1 - - --get / peek functions - local function get() - local c = src:sub(p,p) - if c == '\n' then - char = 1 - line = line + 1 - else - char = char + 1 - end - p = p + 1 - return c - end - local function peek(n) - n = n or 0 - return src:sub(p+n,p+n) - end - local function consume(chars) - local c = peek() - for i = 1, #chars do - if c == chars:sub(i,i) then return get() end - end - end - - --shared stuff - local function generateError(err) - return error(">> :"..line..":"..char..": "..err, 0) - end - - local function tryGetLongString() - local start = p - if peek() == '[' then - local equalsCount = 0 - local depth = 1 - while peek(equalsCount+1) == '=' do - equalsCount = equalsCount + 1 - end - if peek(equalsCount+1) == '[' then - --start parsing the string. Strip the starting bit - for _ = 0, equalsCount+1 do get() end - - --get the contents - local contentStart = p - while true do - --check for eof - if peek() == '' then - generateError("Expected `]"..string.rep('=', equalsCount).."]` near .", 3) - end - - --check for the end - local foundEnd = true - if peek() == ']' then - for i = 1, equalsCount do - if peek(i) ~= '=' then foundEnd = false end - end - if peek(equalsCount+1) ~= ']' then - foundEnd = false - end - else - if peek() == '[' then - -- is there an embedded long string? - local embedded = true - for i = 1, equalsCount do - if peek(i) ~= '=' then - embedded = false - break - end - end - if peek(equalsCount + 1) == '[' and embedded then - -- oh look, there was - depth = depth + 1 - for i = 1, (equalsCount + 2) do - get() - end - end - end - foundEnd = false - end - -- - if foundEnd then - depth = depth - 1 - if depth == 0 then - break - else - for i = 1, equalsCount + 2 do - get() - end - end - else - get() - end - end - - --get the interior string - local contentString = src:sub(contentStart, p-1) - - --found the end. Get rid of the trailing bit - for i = 0, equalsCount+1 do get() end - - --get the exterior string - local longString = src:sub(start, p-1) - - --return the stuff - return contentString, longString - else - return nil - end - else - return nil - end - end - - --main token emitting loop - while true do - --get leading whitespace. The leading whitespace will include any comments - --preceding the token. This prevents the parser needing to deal with comments - --separately. - local leading = { } - local leadingWhite = '' - local longStr = false - while true do - local c = peek() - if c == '#' and peek(1) == '!' and line == 1 then - -- #! shebang for linux scripts - get() - get() - leadingWhite = "#!" - while peek() ~= '\n' and peek() ~= '' do - leadingWhite = leadingWhite .. get() - end - local token = { - Type = 'Comment', - CommentType = 'Shebang', - Data = leadingWhite, - Line = line, - Char = char - } - token.Print = function() - return "<"..(token.Type .. string.rep(' ', 7-#token.Type)).." "..(token.Data or '').." >" - end - leadingWhite = "" - table.insert(leading, token) - end - if c == ' ' or c == '\t' then - --whitespace - --leadingWhite = leadingWhite..get() - local c2 = get() -- ignore whitespace - table.insert(leading, { Type = 'Whitespace', Line = line, Char = char, Data = c2 }) - elseif c == '\n' or c == '\r' then - local nl = get() - if leadingWhite ~= "" then - local token = { - Type = 'Comment', - CommentType = longStr and 'LongComment' or 'Comment', - Data = leadingWhite, - Line = line, - Char = char, - } - token.Print = function() - return "<"..(token.Type .. string.rep(' ', 7-#token.Type)).." "..(token.Data or '').." >" - end - table.insert(leading, token) - leadingWhite = "" - end - table.insert(leading, { Type = 'Whitespace', Line = line, Char = char, Data = nl }) - elseif c == '-' and peek(1) == '-' then - --comment - get() - get() - leadingWhite = leadingWhite .. '--' - local _, wholeText = tryGetLongString() - if wholeText then - leadingWhite = leadingWhite..wholeText - longStr = true - else - while peek() ~= '\n' and peek() ~= '' do - leadingWhite = leadingWhite..get() - end - end - else - break - end - end - if leadingWhite ~= "" then - local token = { - Type = 'Comment', - CommentType = longStr and 'LongComment' or 'Comment', - Data = leadingWhite, - Line = line, - Char = char, - } - token.Print = function() - return "<"..(token.Type .. string.rep(' ', 7-#token.Type)).." "..(token.Data or '').." >" - end - table.insert(leading, token) - end - - --get the initial char - local thisLine = line - local thisChar = char - local errorAt = ":"..line..":"..char..":> " - local c = peek() - - --symbol to emit - local toEmit = nil - - --branch on type - if c == '' then - --eof - toEmit = { Type = 'Eof' } - - elseif UpperChars[c] or LowerChars[c] or c == '_' then - --ident or keyword - local start = p - repeat - get() - c = peek() - until not (UpperChars[c] or LowerChars[c] or Digits[c] or c == '_') - local dat = src:sub(start, p-1) - if Keywords[dat] then - toEmit = {Type = 'Keyword', Data = dat} - else - toEmit = {Type = 'Ident', Data = dat} - end - - elseif Digits[c] or (peek() == '.' and Digits[peek(1)]) then - --number const - local start = p - if c == '0' and peek(1) == 'x' then - get();get() - while HexDigits[peek()] do get() end - if consume('Pp') then - consume('+-') - while Digits[peek()] do get() end - end - else - while Digits[peek()] do get() end - if consume('.') then - while Digits[peek()] do get() end - end - if consume('Ee') then - consume('+-') - while Digits[peek()] do get() end - end - end - toEmit = {Type = 'Number', Data = src:sub(start, p-1)} - - elseif c == '\'' or c == '\"' then - local start = p - --string const - local delim = get() - local contentStart = p - while true do - local c = get() - if c == '\\' then - get() --get the escape char - elseif c == delim then - break - elseif c == '' then - generateError("Unfinished string near ") - end - end - local content = src:sub(contentStart, p-2) - local constant = src:sub(start, p-1) - toEmit = {Type = 'String', Data = constant, Constant = content} - - elseif c == '[' then - local content, wholetext = tryGetLongString() - if wholetext then - toEmit = {Type = 'String', Data = wholetext, Constant = content} - else - get() - toEmit = {Type = 'Symbol', Data = '['} - end - - elseif consume('>=<') then - if consume('=') then - toEmit = {Type = 'Symbol', Data = c..'='} - else - toEmit = {Type = 'Symbol', Data = c} - end - - elseif consume('~') then - if consume('=') then - toEmit = {Type = 'Symbol', Data = '~='} - else - generateError("Unexpected symbol `~` in source.", 2) - end - - elseif consume('.') then - if consume('.') then - if consume('.') then - toEmit = {Type = 'Symbol', Data = '...'} - else - toEmit = {Type = 'Symbol', Data = '..'} - end - else - toEmit = {Type = 'Symbol', Data = '.'} - end - - elseif consume(':') then - if consume(':') then - toEmit = {Type = 'Symbol', Data = '::'} - else - toEmit = {Type = 'Symbol', Data = ':'} - end - - elseif Symbols[c] then - get() - toEmit = {Type = 'Symbol', Data = c} - - else - local contents, all = tryGetLongString() - if contents then - toEmit = {Type = 'String', Data = all, Constant = contents} - else - generateError("Unexpected Symbol `"..c.."` in source.", 2) - end - end - - --add the emitted symbol, after adding some common data - toEmit.LeadingWhite = leading -- table of leading whitespace/comments - --for k, tok in pairs(leading) do - -- tokens[#tokens + 1] = tok - --end - - toEmit.Line = thisLine - toEmit.Char = thisChar - toEmit.Print = function() - return "<"..(toEmit.Type..string.rep(' ', 7-#toEmit.Type)).." "..(toEmit.Data or '').." >" - end - tokens[#tokens+1] = toEmit - - --halt after eof has been emitted - if toEmit.Type == 'Eof' then break end - end - end) - if not st then - return false, err - end - - --public interface: - local tok = {} - local savedP = {} - local p = 1 - - function tok:getp() - return p - end - - function tok:setp(n) - p = n - end - - function tok:getTokenList() - return tokens - end - - --getters - function tok:Peek(n) - n = n or 0 - return tokens[math.min(#tokens, p+n)] - end - function tok:Get(tokenList) - local t = tokens[p] - p = math.min(p + 1, #tokens) - if tokenList then - table.insert(tokenList, t) - end - return t - end - function tok:Is(t) - return tok:Peek().Type == t - end - - --save / restore points in the stream - function tok:Save() - savedP[#savedP+1] = p - end - function tok:Commit() - savedP[#savedP] = nil - end - function tok:Restore() - p = savedP[#savedP] - savedP[#savedP] = nil - end - - --either return a symbol if there is one, or return true if the requested - --symbol was gotten. - function tok:ConsumeSymbol(symb, tokenList) - local t = self:Peek() - if t.Type == 'Symbol' then - if symb then - if t.Data == symb then - self:Get(tokenList) - return true - else - return nil - end - else - self:Get(tokenList) - return t - end - else - return nil - end - end - - function tok:ConsumeKeyword(kw, tokenList) - local t = self:Peek() - if t.Type == 'Keyword' and t.Data == kw then - self:Get(tokenList) - return true - else - return nil - end - end - - function tok:IsKeyword(kw) - local t = tok:Peek() - return t.Type == 'Keyword' and t.Data == kw - end - - function tok:IsSymbol(s) - local t = tok:Peek() - return t.Type == 'Symbol' and t.Data == s - end - - function tok:IsEof() - return tok:Peek().Type == 'Eof' - end - - return true, tok -end - - -local function ParseLua(src) - local st, tok - if type(src) ~= 'table' then - st, tok = LexLua(src) - else - st, tok = true, src - end - if not st then - return false, tok - end - -- - local function GenerateError(msg) - local err = ">> :"..tok:Peek().Line..":"..tok:Peek().Char..": "..msg.."\n" - --find the line - local lineNum = 0 - if type(src) == 'string' then - for line in src:gmatch("[^\n]*\n?") do - if line:sub(-1,-1) == '\n' then line = line:sub(1,-2) end - lineNum = lineNum+1 - if lineNum == tok:Peek().Line then - err = err..">> `"..line:gsub('\t',' ').."`\n" - for i = 1, tok:Peek().Char do - local c = line:sub(i,i) - if c == '\t' then - err = err..' ' - else - err = err..' ' - end - end - err = err.." ^^^^" - break - end - end - end - return err - end - -- - local VarUid = 0 - -- No longer needed: handled in Scopes now local GlobalVarGetMap = {} - local VarDigits = {'_', 'a', 'b', 'c', 'd'} - local function CreateScope(parent) - --[[ - local scope = {} - scope.Parent = parent - scope.LocalList = {} - scope.LocalMap = {} - - function scope:ObfuscateVariables() - for _, var in pairs(scope.LocalList) do - local id = "" - repeat - local chars = "QWERTYUIOPASDFGHJKLZXCVBNMqwertyuioplkjhgfdsazxcvbnm_" - local chars2 = "QWERTYUIOPASDFGHJKLZXCVBNMqwertyuioplkjhgfdsazxcvbnm_1234567890" - local n = math.random(1, #chars) - id = id .. chars:sub(n, n) - for i = 1, math.random(0,20) do - local n = math.random(1, #chars2) - id = id .. chars2:sub(n, n) - end - until not GlobalVarGetMap[id] and not parent:GetLocal(id) and not scope.LocalMap[id] - var.Name = id - scope.LocalMap[id] = var - end - end - - scope.RenameVars = scope.ObfuscateVariables - - -- Renames a variable from this scope and down. - -- Does not rename global variables. - function scope:RenameVariable(old, newName) - if type(old) == "table" then -- its (theoretically) an AstNode variable - old = old.Name - end - for _, var in pairs(scope.LocalList) do - if var.Name == old then - var.Name = newName - scope.LocalMap[newName] = var - end - end - end - - function scope:GetLocal(name) - --first, try to get my variable - local my = scope.LocalMap[name] - if my then return my end - - --next, try parent - if scope.Parent then - local par = scope.Parent:GetLocal(name) - if par then return par end - end - - return nil - end - - function scope:CreateLocal(name) - --create my own var - local my = {} - my.Scope = scope - my.Name = name - my.CanRename = true - -- - scope.LocalList[#scope.LocalList+1] = my - scope.LocalMap[name] = my - -- - return my - end]] - local scope = Scope:new(parent) - scope.RenameVars = scope.ObfuscateLocals - scope.ObfuscateVariables = scope.ObfuscateLocals - scope.Print = function() return "" end - return scope - end - - local ParseExpr - local ParseStatementList - local ParseSimpleExpr, - ParseSubExpr, - ParsePrimaryExpr, - ParseSuffixedExpr - - local function ParseFunctionArgsAndBody(scope, tokenList) - local funcScope = CreateScope(scope) - if not tok:ConsumeSymbol('(', tokenList) then - return false, GenerateError("`(` expected.") - end - - --arg list - local argList = {} - local isVarArg = false - while not tok:ConsumeSymbol(')', tokenList) do - if tok:Is('Ident') then - local arg = funcScope:CreateLocal(tok:Get(tokenList).Data) - argList[#argList+1] = arg - if not tok:ConsumeSymbol(',', tokenList) then - if tok:ConsumeSymbol(')', tokenList) then - break - else - return false, GenerateError("`)` expected.") - end - end - elseif tok:ConsumeSymbol('...', tokenList) then - isVarArg = true - if not tok:ConsumeSymbol(')', tokenList) then - return false, GenerateError("`...` must be the last argument of a function.") - end - break - else - return false, GenerateError("Argument name or `...` expected") - end - end - - --body - local st, body = ParseStatementList(funcScope) - if not st then return false, body end - - --end - if not tok:ConsumeKeyword('end', tokenList) then - return false, GenerateError("`end` expected after function body") - end - local nodeFunc = {} - nodeFunc.AstType = 'Function' - nodeFunc.Scope = funcScope - nodeFunc.Arguments = argList - nodeFunc.Body = body - nodeFunc.VarArg = isVarArg - nodeFunc.Tokens = tokenList - -- - return true, nodeFunc - end - - - function ParsePrimaryExpr(scope) - local tokenList = {} - - if tok:ConsumeSymbol('(', tokenList) then - local st, ex = ParseExpr(scope) - if not st then return false, ex end - if not tok:ConsumeSymbol(')', tokenList) then - return false, GenerateError("`)` Expected.") - end - if false then - --save the information about parenthesized expressions somewhere - ex.ParenCount = (ex.ParenCount or 0) + 1 - return true, ex - else - local parensExp = {} - parensExp.AstType = 'Parentheses' - parensExp.Inner = ex - parensExp.Tokens = tokenList - return true, parensExp - end - - elseif tok:Is('Ident') then - local id = tok:Get(tokenList) - local var = scope:GetLocal(id.Data) - if not var then - var = scope:GetGlobal(id.Data) - if not var then - var = scope:CreateGlobal(id.Data) - else - var.References = var.References + 1 - end - else - var.References = var.References + 1 - end - -- - local nodePrimExp = {} - nodePrimExp.AstType = 'VarExpr' - nodePrimExp.Name = id.Data - nodePrimExp.Variable = var - nodePrimExp.Tokens = tokenList - -- - return true, nodePrimExp - else - return false, GenerateError("primary expression expected") - end - end - - function ParseSuffixedExpr(scope, onlyDotColon) - --base primary expression - local st, prim = ParsePrimaryExpr(scope) - if not st then return false, prim end - -- - while true do - local tokenList = {} - - if tok:IsSymbol('.') or tok:IsSymbol(':') then - local symb = tok:Get(tokenList).Data - if not tok:Is('Ident') then - return false, GenerateError(" expected.") - end - local id = tok:Get(tokenList) - local nodeIndex = {} - nodeIndex.AstType = 'MemberExpr' - nodeIndex.Base = prim - nodeIndex.Indexer = symb - nodeIndex.Ident = id - nodeIndex.Tokens = tokenList - -- - prim = nodeIndex - - elseif not onlyDotColon and tok:ConsumeSymbol('[', tokenList) then - local st, ex = ParseExpr(scope) - if not st then return false, ex end - if not tok:ConsumeSymbol(']', tokenList) then - return false, GenerateError("`]` expected.") - end - local nodeIndex = {} - nodeIndex.AstType = 'IndexExpr' - nodeIndex.Base = prim - nodeIndex.Index = ex - nodeIndex.Tokens = tokenList - -- - prim = nodeIndex - - elseif not onlyDotColon and tok:ConsumeSymbol('(', tokenList) then - local args = {} - while not tok:ConsumeSymbol(')', tokenList) do - local st, ex = ParseExpr(scope) - if not st then return false, ex end - args[#args+1] = ex - if not tok:ConsumeSymbol(',', tokenList) then - if tok:ConsumeSymbol(')', tokenList) then - break - else - return false, GenerateError("`)` Expected.") - end - end - end - local nodeCall = {} - nodeCall.AstType = 'CallExpr' - nodeCall.Base = prim - nodeCall.Arguments = args - nodeCall.Tokens = tokenList - -- - prim = nodeCall - - elseif not onlyDotColon and tok:Is('String') then - --string call - local nodeCall = {} - nodeCall.AstType = 'StringCallExpr' - nodeCall.Base = prim - nodeCall.Arguments = { tok:Get(tokenList) } - nodeCall.Tokens = tokenList - -- - prim = nodeCall - - elseif not onlyDotColon and tok:IsSymbol('{') then - --table call - local st, ex = ParseSimpleExpr(scope) - -- FIX: ParseExpr(scope) parses the table AND and any following binary expressions. - -- We just want the table - if not st then return false, ex end - local nodeCall = {} - nodeCall.AstType = 'TableCallExpr' - nodeCall.Base = prim - nodeCall.Arguments = { ex } - nodeCall.Tokens = tokenList - -- - prim = nodeCall - - else - break - end - end - return true, prim - end - - - function ParseSimpleExpr(scope) - local tokenList = {} - - if tok:Is('Number') then - local nodeNum = {} - nodeNum.AstType = 'NumberExpr' - nodeNum.Value = tok:Get(tokenList) - nodeNum.Tokens = tokenList - return true, nodeNum - - elseif tok:Is('String') then - local nodeStr = {} - nodeStr.AstType = 'StringExpr' - nodeStr.Value = tok:Get(tokenList) - nodeStr.Tokens = tokenList - return true, nodeStr - - elseif tok:ConsumeKeyword('nil', tokenList) then - local nodeNil = {} - nodeNil.AstType = 'NilExpr' - nodeNil.Tokens = tokenList - return true, nodeNil - - elseif tok:IsKeyword('false') or tok:IsKeyword('true') then - local nodeBoolean = {} - nodeBoolean.AstType = 'BooleanExpr' - nodeBoolean.Value = (tok:Get(tokenList).Data == 'true') - nodeBoolean.Tokens = tokenList - return true, nodeBoolean - - elseif tok:ConsumeSymbol('...', tokenList) then - local nodeDots = {} - nodeDots.AstType = 'DotsExpr' - nodeDots.Tokens = tokenList - return true, nodeDots - - elseif tok:ConsumeSymbol('{', tokenList) then - local v = {} - v.AstType = 'ConstructorExpr' - v.EntryList = {} - -- - while true do - if tok:IsSymbol('[', tokenList) then - --key - tok:Get(tokenList) - local st, key = ParseExpr(scope) - if not st then - return false, GenerateError("Key Expression Expected") - end - if not tok:ConsumeSymbol(']', tokenList) then - return false, GenerateError("`]` Expected") - end - if not tok:ConsumeSymbol('=', tokenList) then - return false, GenerateError("`=` Expected") - end - local st, value = ParseExpr(scope) - if not st then - return false, GenerateError("Value Expression Expected") - end - v.EntryList[#v.EntryList+1] = { - Type = 'Key'; - Key = key; - Value = value; - } - - elseif tok:Is('Ident') then - --value or key - local lookahead = tok:Peek(1) - if lookahead.Type == 'Symbol' and lookahead.Data == '=' then - --we are a key - local key = tok:Get(tokenList) - if not tok:ConsumeSymbol('=', tokenList) then - return false, GenerateError("`=` Expected") - end - local st, value = ParseExpr(scope) - if not st then - return false, GenerateError("Value Expression Expected") - end - v.EntryList[#v.EntryList+1] = { - Type = 'KeyString'; - Key = key.Data; - Value = value; - } - - else - --we are a value - local st, value = ParseExpr(scope) - if not st then - return false, GenerateError("Value Exected") - end - v.EntryList[#v.EntryList+1] = { - Type = 'Value'; - Value = value; - } - - end - elseif tok:ConsumeSymbol('}', tokenList) then - break - - else - --value - local st, value = ParseExpr(scope) - v.EntryList[#v.EntryList+1] = { - Type = 'Value'; - Value = value; - } - if not st then - return false, GenerateError("Value Expected") - end - end - - if tok:ConsumeSymbol(';', tokenList) or tok:ConsumeSymbol(',', tokenList) then - --all is good - elseif tok:ConsumeSymbol('}', tokenList) then - break - else - return false, GenerateError("`}` or table entry Expected") - end - end - v.Tokens = tokenList - return true, v - - elseif tok:ConsumeKeyword('function', tokenList) then - local st, func = ParseFunctionArgsAndBody(scope, tokenList) - if not st then return false, func end - -- - func.IsLocal = true - return true, func - - else - return ParseSuffixedExpr(scope) - end - end - - - local unops = lookupify{'-', 'not', '#'} - local unopprio = 8 - local priority = { - ['+'] = {6,6}; - ['-'] = {6,6}; - ['%'] = {7,7}; - ['/'] = {7,7}; - ['*'] = {7,7}; - ['^'] = {10,9}; - ['..'] = {5,4}; - ['=='] = {3,3}; - ['<'] = {3,3}; - ['<='] = {3,3}; - ['~='] = {3,3}; - ['>'] = {3,3}; - ['>='] = {3,3}; - ['and'] = {2,2}; - ['or'] = {1,1}; - } - function ParseSubExpr(scope, level) - --base item, possibly with unop prefix - local st, exp - if unops[tok:Peek().Data] then - local tokenList = {} - local op = tok:Get(tokenList).Data - st, exp = ParseSubExpr(scope, unopprio) - if not st then return false, exp end - local nodeEx = {} - nodeEx.AstType = 'UnopExpr' - nodeEx.Rhs = exp - nodeEx.Op = op - nodeEx.OperatorPrecedence = unopprio - nodeEx.Tokens = tokenList - exp = nodeEx - else - st, exp = ParseSimpleExpr(scope) - if not st then return false, exp end - end - - --next items in chain - while true do - local prio = priority[tok:Peek().Data] - if prio and prio[1] > level then - local tokenList = {} - local op = tok:Get(tokenList).Data - local st, rhs = ParseSubExpr(scope, prio[2]) - if not st then return false, rhs end - local nodeEx = {} - nodeEx.AstType = 'BinopExpr' - nodeEx.Lhs = exp - nodeEx.Op = op - nodeEx.OperatorPrecedence = prio[1] - nodeEx.Rhs = rhs - nodeEx.Tokens = tokenList - -- - exp = nodeEx - else - break - end - end - - return true, exp - end - - - ParseExpr = function(scope) - return ParseSubExpr(scope, 0) - end - - - local function ParseStatement(scope) - local stat = nil - local tokenList = {} - if tok:ConsumeKeyword('if', tokenList) then - --setup - local nodeIfStat = {} - nodeIfStat.AstType = 'IfStatement' - nodeIfStat.Clauses = {} - - --clauses - repeat - local st, nodeCond = ParseExpr(scope) - if not st then return false, nodeCond end - if not tok:ConsumeKeyword('then', tokenList) then - return false, GenerateError("`then` expected.") - end - local st, nodeBody = ParseStatementList(scope) - if not st then return false, nodeBody end - nodeIfStat.Clauses[#nodeIfStat.Clauses+1] = { - Condition = nodeCond; - Body = nodeBody; - } - until not tok:ConsumeKeyword('elseif', tokenList) - - --else clause - if tok:ConsumeKeyword('else', tokenList) then - local st, nodeBody = ParseStatementList(scope) - if not st then return false, nodeBody end - nodeIfStat.Clauses[#nodeIfStat.Clauses+1] = { - Body = nodeBody; - } - end - - --end - if not tok:ConsumeKeyword('end', tokenList) then - return false, GenerateError("`end` expected.") - end - - nodeIfStat.Tokens = tokenList - stat = nodeIfStat - - elseif tok:ConsumeKeyword('while', tokenList) then - --setup - local nodeWhileStat = {} - nodeWhileStat.AstType = 'WhileStatement' - - --condition - local st, nodeCond = ParseExpr(scope) - if not st then return false, nodeCond end - - --do - if not tok:ConsumeKeyword('do', tokenList) then - return false, GenerateError("`do` expected.") - end - - --body - local st, nodeBody = ParseStatementList(scope) - if not st then return false, nodeBody end - - --end - if not tok:ConsumeKeyword('end', tokenList) then - return false, GenerateError("`end` expected.") - end - - --return - nodeWhileStat.Condition = nodeCond - nodeWhileStat.Body = nodeBody - nodeWhileStat.Tokens = tokenList - stat = nodeWhileStat - - elseif tok:ConsumeKeyword('do', tokenList) then - --do block - local st, nodeBlock = ParseStatementList(scope) - if not st then return false, nodeBlock end - if not tok:ConsumeKeyword('end', tokenList) then - return false, GenerateError("`end` expected.") - end - - local nodeDoStat = {} - nodeDoStat.AstType = 'DoStatement' - nodeDoStat.Body = nodeBlock - nodeDoStat.Tokens = tokenList - stat = nodeDoStat - - elseif tok:ConsumeKeyword('for', tokenList) then - --for block - if not tok:Is('Ident') then - return false, GenerateError(" expected.") - end - local baseVarName = tok:Get(tokenList) - if tok:ConsumeSymbol('=', tokenList) then - --numeric for - local forScope = CreateScope(scope) - local forVar = forScope:CreateLocal(baseVarName.Data) - -- - local st, startEx = ParseExpr(scope) - if not st then return false, startEx end - if not tok:ConsumeSymbol(',', tokenList) then - return false, GenerateError("`,` Expected") - end - local st, endEx = ParseExpr(scope) - if not st then return false, endEx end - local st, stepEx; - if tok:ConsumeSymbol(',', tokenList) then - st, stepEx = ParseExpr(scope) - if not st then return false, stepEx end - end - if not tok:ConsumeKeyword('do', tokenList) then - return false, GenerateError("`do` expected") - end - -- - local st, body = ParseStatementList(forScope) - if not st then return false, body end - if not tok:ConsumeKeyword('end', tokenList) then - return false, GenerateError("`end` expected") - end - -- - local nodeFor = {} - nodeFor.AstType = 'NumericForStatement' - nodeFor.Scope = forScope - nodeFor.Variable = forVar - nodeFor.Start = startEx - nodeFor.End = endEx - nodeFor.Step = stepEx - nodeFor.Body = body - nodeFor.Tokens = tokenList - stat = nodeFor - else - --generic for - local forScope = CreateScope(scope) - -- - local varList = { forScope:CreateLocal(baseVarName.Data) } - while tok:ConsumeSymbol(',', tokenList) do - if not tok:Is('Ident') then - return false, GenerateError("for variable expected.") - end - varList[#varList+1] = forScope:CreateLocal(tok:Get(tokenList).Data) - end - if not tok:ConsumeKeyword('in', tokenList) then - return false, GenerateError("`in` expected.") - end - local generators = {} - local st, firstGenerator = ParseExpr(scope) - if not st then return false, firstGenerator end - generators[#generators+1] = firstGenerator - while tok:ConsumeSymbol(',', tokenList) do - local st, gen = ParseExpr(scope) - if not st then return false, gen end - generators[#generators+1] = gen - end - if not tok:ConsumeKeyword('do', tokenList) then - return false, GenerateError("`do` expected.") - end - local st, body = ParseStatementList(forScope) - if not st then return false, body end - if not tok:ConsumeKeyword('end', tokenList) then - return false, GenerateError("`end` expected.") - end - -- - local nodeFor = {} - nodeFor.AstType = 'GenericForStatement' - nodeFor.Scope = forScope - nodeFor.VariableList = varList - nodeFor.Generators = generators - nodeFor.Body = body - nodeFor.Tokens = tokenList - stat = nodeFor - end - - elseif tok:ConsumeKeyword('repeat', tokenList) then - local st, body = ParseStatementList(scope) - if not st then return false, body end - -- - if not tok:ConsumeKeyword('until', tokenList) then - return false, GenerateError("`until` expected.") - end - -- FIX: Used to parse in parent scope - -- Now parses in repeat scope - local st, cond = ParseExpr(body.Scope) - if not st then return false, cond end - -- - local nodeRepeat = {} - nodeRepeat.AstType = 'RepeatStatement' - nodeRepeat.Condition = cond - nodeRepeat.Body = body - nodeRepeat.Tokens = tokenList - stat = nodeRepeat - - elseif tok:ConsumeKeyword('function', tokenList) then - if not tok:Is('Ident') then - return false, GenerateError("Function name expected") - end - local st, name = ParseSuffixedExpr(scope, true) --true => only dots and colons - if not st then return false, name end - -- - local st, func = ParseFunctionArgsAndBody(scope, tokenList) - if not st then return false, func end - -- - func.IsLocal = false - func.Name = name - stat = func - - elseif tok:ConsumeKeyword('local', tokenList) then - if tok:Is('Ident') then - local varList = { tok:Get(tokenList).Data } - while tok:ConsumeSymbol(',', tokenList) do - if not tok:Is('Ident') then - return false, GenerateError("local var name expected") - end - varList[#varList+1] = tok:Get(tokenList).Data - end - - local initList = {} - if tok:ConsumeSymbol('=', tokenList) then - repeat - local st, ex = ParseExpr(scope) - if not st then return false, ex end - initList[#initList+1] = ex - until not tok:ConsumeSymbol(',', tokenList) - end - - --now patch var list - --we can't do this before getting the init list, because the init list does not - --have the locals themselves in scope. - for i, v in pairs(varList) do - varList[i] = scope:CreateLocal(v) - end - - local nodeLocal = {} - nodeLocal.AstType = 'LocalStatement' - nodeLocal.LocalList = varList - nodeLocal.InitList = initList - nodeLocal.Tokens = tokenList - -- - stat = nodeLocal - - elseif tok:ConsumeKeyword('function', tokenList) then - if not tok:Is('Ident') then - return false, GenerateError("Function name expected") - end - local name = tok:Get(tokenList).Data - local localVar = scope:CreateLocal(name) - -- - local st, func = ParseFunctionArgsAndBody(scope, tokenList) - if not st then return false, func end - -- - func.Name = localVar - func.IsLocal = true - stat = func - - else - return false, GenerateError("local var or function def expected") - end - - elseif tok:ConsumeSymbol('::', tokenList) then - if not tok:Is('Ident') then - return false, GenerateError('Label name expected') - end - local label = tok:Get(tokenList).Data - if not tok:ConsumeSymbol('::', tokenList) then - return false, GenerateError("`::` expected") - end - local nodeLabel = {} - nodeLabel.AstType = 'LabelStatement' - nodeLabel.Label = label - nodeLabel.Tokens = tokenList - stat = nodeLabel - - elseif tok:ConsumeKeyword('return', tokenList) then - local exList = {} - if not tok:IsKeyword('end') then - local st, firstEx = ParseExpr(scope) - if st then - exList[1] = firstEx - while tok:ConsumeSymbol(',', tokenList) do - local st, ex = ParseExpr(scope) - if not st then return false, ex end - exList[#exList+1] = ex - end - end - end - - local nodeReturn = {} - nodeReturn.AstType = 'ReturnStatement' - nodeReturn.Arguments = exList - nodeReturn.Tokens = tokenList - stat = nodeReturn - - elseif tok:ConsumeKeyword('break', tokenList) then - local nodeBreak = {} - nodeBreak.AstType = 'BreakStatement' - nodeBreak.Tokens = tokenList - stat = nodeBreak - - elseif tok:ConsumeKeyword('goto', tokenList) then - if not tok:Is('Ident') then - return false, GenerateError("Label expected") - end - local label = tok:Get(tokenList).Data - local nodeGoto = {} - nodeGoto.AstType = 'GotoStatement' - nodeGoto.Label = label - nodeGoto.Tokens = tokenList - stat = nodeGoto - - else - --statementParseExpr - local st, suffixed = ParseSuffixedExpr(scope) - if not st then return false, suffixed end - - --assignment or call? - if tok:IsSymbol(',') or tok:IsSymbol('=') then - --check that it was not parenthesized, making it not an lvalue - if (suffixed.ParenCount or 0) > 0 then - return false, GenerateError("Can not assign to parenthesized expression, is not an lvalue") - end - - --more processing needed - local lhs = { suffixed } - while tok:ConsumeSymbol(',', tokenList) do - local st, lhsPart = ParseSuffixedExpr(scope) - if not st then return false, lhsPart end - lhs[#lhs+1] = lhsPart - end - - --equals - if not tok:ConsumeSymbol('=', tokenList) then - return false, GenerateError("`=` Expected.") - end - - --rhs - local rhs = {} - local st, firstRhs = ParseExpr(scope) - if not st then return false, firstRhs end - rhs[1] = firstRhs - while tok:ConsumeSymbol(',', tokenList) do - local st, rhsPart = ParseExpr(scope) - if not st then return false, rhsPart end - rhs[#rhs+1] = rhsPart - end - - --done - local nodeAssign = {} - nodeAssign.AstType = 'AssignmentStatement' - nodeAssign.Lhs = lhs - nodeAssign.Rhs = rhs - nodeAssign.Tokens = tokenList - stat = nodeAssign - - elseif suffixed.AstType == 'CallExpr' or - suffixed.AstType == 'TableCallExpr' or - suffixed.AstType == 'StringCallExpr' - then - --it's a call statement - local nodeCall = {} - nodeCall.AstType = 'CallStatement' - nodeCall.Expression = suffixed - nodeCall.Tokens = tokenList - stat = nodeCall - else - return false, GenerateError("Assignment Statement Expected") - end - end - - if tok:IsSymbol(';') then - stat.Semicolon = tok:Get( stat.Tokens ) - end - return true, stat - end - - - local statListCloseKeywords = lookupify{'end', 'else', 'elseif', 'until'} - - ParseStatementList = function(scope) - local nodeStatlist = {} - nodeStatlist.Scope = CreateScope(scope) - nodeStatlist.AstType = 'Statlist' - nodeStatlist.Body = { } - nodeStatlist.Tokens = { } - -- - --local stats = {} - -- - while not statListCloseKeywords[tok:Peek().Data] and not tok:IsEof() do - local st, nodeStatement = ParseStatement(nodeStatlist.Scope) - if not st then return false, nodeStatement end - --stats[#stats+1] = nodeStatement - nodeStatlist.Body[#nodeStatlist.Body + 1] = nodeStatement - end - - if tok:IsEof() then - local nodeEof = {} - nodeEof.AstType = 'Eof' - nodeEof.Tokens = { tok:Get() } - nodeStatlist.Body[#nodeStatlist.Body + 1] = nodeEof - end - - -- - --nodeStatlist.Body = stats - return true, nodeStatlist - end - - - local function mainfunc() - local topScope = CreateScope() - return ParseStatementList(topScope) - end - - local st, main = mainfunc() - --print("Last Token: "..PrintTable(tok:Peek())) - return st, main -end - -return { LexLua = LexLua, ParseLua = ParseLua } - diff --git a/server/lib/Scope.lua b/server/lib/Scope.lua deleted file mode 100644 index c4b8444..0000000 --- a/server/lib/Scope.lua +++ /dev/null @@ -1,195 +0,0 @@ -local Scope = { - new = function(self, parent) - local s = { - Parent = parent, - Locals = { }, - Globals = { }, - oldLocalNamesMap = { }, - oldGlobalNamesMap = { }, - Children = { }, - } - - if parent then - table.insert(parent.Children, s) - end - - return setmetatable(s, { __index = self }) - end, - - AddLocal = function(self, v) - table.insert(self.Locals, v) - end, - - AddGlobal = function(self, v) - table.insert(self.Globals, v) - end, - - CreateLocal = function(self, name) - local v - v = self:GetLocal(name) - if v then return v end - v = { } - v.Scope = self - v.Name = name - v.IsGlobal = false - v.CanRename = true - v.References = 1 - self:AddLocal(v) - return v - end, - - GetLocal = function(self, name) - for k, var in pairs(self.Locals) do - if var.Name == name then return var end - end - - if self.Parent then - return self.Parent:GetLocal(name) - end - end, - - GetOldLocal = function(self, name) - if self.oldLocalNamesMap[name] then - return self.oldLocalNamesMap[name] - end - return self:GetLocal(name) - end, - - mapLocal = function(self, name, var) - self.oldLocalNamesMap[name] = var - end, - - GetOldGlobal = function(self, name) - if self.oldGlobalNamesMap[name] then - return self.oldGlobalNamesMap[name] - end - return self:GetGlobal(name) - end, - - mapGlobal = function(self, name, var) - self.oldGlobalNamesMap[name] = var - end, - - GetOldVariable = function(self, name) - return self:GetOldLocal(name) or self:GetOldGlobal(name) - end, - - RenameLocal = function(self, oldName, newName) - oldName = type(oldName) == 'string' and oldName or oldName.Name - local found = false - local var = self:GetLocal(oldName) - if var then - var.Name = newName - self:mapLocal(oldName, var) - found = true - end - if not found and self.Parent then - self.Parent:RenameLocal(oldName, newName) - end - end, - - RenameGlobal = function(self, oldName, newName) - oldName = type(oldName) == 'string' and oldName or oldName.Name - local found = false - local var = self:GetGlobal(oldName) - if var then - var.Name = newName - self:mapGlobal(oldName, var) - found = true - end - if not found and self.Parent then - self.Parent:RenameGlobal(oldName, newName) - end - end, - - RenameVariable = function(self, oldName, newName) - oldName = type(oldName) == 'string' and oldName or oldName.Name - if self:GetLocal(oldName) then - self:RenameLocal(oldName, newName) - else - self:RenameGlobal(oldName, newName) - end - end, - - GetAllVariables = function(self) - local ret = self:getVars(true) -- down - for k, v in pairs(self:getVars(false)) do -- up - table.insert(ret, v) - end - return ret - end, - - getVars = function(self, top) - local ret = { } - if top then - for k, v in pairs(self.Children) do - for k2, v2 in pairs(v:getVars(true)) do - table.insert(ret, v2) - end - end - else - for k, v in pairs(self.Locals) do - table.insert(ret, v) - end - for k, v in pairs(self.Globals) do - table.insert(ret, v) - end - if self.Parent then - for k, v in pairs(self.Parent:getVars(false)) do - table.insert(ret, v) - end - end - end - return ret - end, - - CreateGlobal = function(self, name) - local v - v = self:GetGlobal(name) - if v then return v end - v = { } - v.Scope = self - v.Name = name - v.IsGlobal = true - v.CanRename = true - v.References = 1 - self:AddGlobal(v) - return v - end, - - GetGlobal = function(self, name) - for k, v in pairs(self.Globals) do - if v.Name == name then return v end - end - - if self.Parent then - return self.Parent:GetGlobal(name) - end - end, - - GetVariable = function(self, name) - return self:GetLocal(name) or self:GetGlobal(name) - end, - - ObfuscateLocals = function(self, recommendedMaxLength, validNameChars) - recommendedMaxLength = recommendedMaxLength or 7 - local chars = validNameChars or "QWERTYUIOPASDFGHJKLZXCVBNMqwertyuioplkjhgfdsazxcvbnm_" - local chars2 = validNameChars or "QWERTYUIOPASDFGHJKLZXCVBNMqwertyuioplkjhgfdsazxcvbnm_1234567890" - for _, var in pairs(self.Locals) do - local id = "" - local tries = 0 - repeat - local n = math.random(1, #chars) - id = id .. chars:sub(n, n) - for i = 1, math.random(0, tries > 5 and 30 or recommendedMaxLength) do - local n = math.random(1, #chars2) - id = id .. chars2:sub(n, n) - end - tries = tries + 1 - until not self:GetVariable(id) - self:RenameLocal(var.Name, id) - end - end, -} - -return Scope diff --git a/server/lib/WebForm.lua b/server/lib/WebForm.lua deleted file mode 100644 index e8fef17..0000000 --- a/server/lib/WebForm.lua +++ /dev/null @@ -1,181 +0,0 @@ -gForms={} -if Form==nil then - function Form(name) - local self = {}; - self.name = name; - self.controls = {} - self.backgroundColor='Black' - gForms[#gForms+1]=self - function self:addControl(control) - self.controls[#self.controls+1]=control - end - function self:show() - print("SHOW: " .. self.name) - for i=1,#gForms do - gForms[i]:hide(true) - end - self:hide(false) - end - function self:hide(hide) - for i=1,#self.controls do - proteo.gui.setHidden(self.controls[i],hide) - end - if not hide then - proteo.graphics.setBackground(self.backgroundColor) - end - end - function self:is_A(t) - return false - end - return self; - end -end - -if GridForm==nil then - function GridForm(name,width,height) - local self = {}; - self.height=height - self.width=width - self.name=name - self.backgroundColor='Black' - self.margin=5 - self.grid = {} - self.anchor = {} - self.grid_lines = {} - self.grid_rectangles= {} - self.grid_rectangles_y= {} - self.hiddenGrid=true - self.y_scroll=0 - gForms[#gForms+1]=self - - function self:clear() - self.grid = {} - self.anchor = {} - self:removeGrid() - self.grid_rectangles= {} - end - function self:copy() - local grid = GridForm() - for x,y,v in self:iterate() do - grid:set(x,y,v) - end - return grid - end - function self:removeGrid() - for i=1,#self.grid_lines do - proteo.system.remove(self.grid_lines[i]) - end - self.grid_lines={} - end - function self:createGrid() - self:removeGrid() - - local h=(MAX_Y / self.height) - local v=(MAX_X / self.width) - --H - for i=1,self.height-1 do - lineh=proteo.graphics.newLine(self.name .."_hline"..i,"White",1.0,MIN_X,i*h,MAX_X,i*h) - self.grid_lines[#self.grid_lines +1]=lineh - end - --V - for i=1,self.width-1 do - linev=proteo.graphics.newLine(self.name .."_vline"..i,"White",1.0,i*v,MIN_Y,i*v,MAX_Y) - self.grid_lines[#self.grid_lines +1]=linev - end - end - function self:addControl(x, y,anchor, value) - if not self.grid[x] then self.grid[x] = {} end - self.grid[x][y] = value - - if not self.anchor[x] then self.anchor[x] = {} end - self.anchor[x][y] = anchor - - if x>self.width then self.width=x end - if y>self.height then self.height=y end - end - function self:iterate() - local x, row = next(self.grid) - if x == nil then return function() end end - local y, val - return function() - repeat - y,val = next(row,y) - if y == nil then x,row = next(self.grid, x) end - until (val and x and y) or (not val and not x and not y) - return x,y,val - end - end - function self:updatePosition() - for x, y, v in self:iterate() do - local x_anchor=0 - local y_anchor=0 - local x_margin=0 - local y_margin=0 - - if self.anchor[x][y] == proteo.gui.ControlAnchor.Center then x_anchor=0.5 y_anchor=0.5 - elseif self.anchor[x][y] == proteo.gui.ControlAnchor.CenterLeft then x_anchor=1 y_anchor=0.5 x_margin=self.margin end - - local pos_x= x_margin + (MAX_X / self.width) * (x - x_anchor) - local pos_y= y_margin + (MAX_Y / self.height) * (y - y_anchor) - proteo.gui.setPosition(v,pos_x,pos_y+self.y_scroll,self.anchor[x][y]) - end - - for i=1,#self.grid_rectangles do - pos=proteo.graphics.getPosition(self.grid_rectangles[i]) - --print('1:'..pos[0]..' 2: '..pos[1]) - proteo.graphics.setPosition(self.grid_rectangles[i],pos[1],self.grid_rectangles_y[i]+self.y_scroll) - end - end - function self:setColor(color,from_x,from_y,to_x,to_y) - local h=(MAX_Y / self.height) - local v=(MAX_X / self.width) - - crect=proteo.graphics.newRect(self.name .."_crect",color,color,(from_x-1)*v,(from_y-1)*h,(to_x-from_x+1)*v,(to_y-from_y+1)*h) - self.grid_rectangles[#self.grid_rectangles +1]=crect - self.grid_rectangles_y[#self.grid_rectangles]=(from_y-1)*h - end - function self:is_A(t) - return true - end - function self:scroll(y_scroll) - self.y_scroll=y_scroll - - self:updatePosition() - end - function self:show() - print("SHOW: " .. self.name) - for i=1,#gForms do - gForms[i]:hide(true) - end - self:hide(false) - end - function self:hideGrid(hide) - self.hiddenGrid=hide - end - function self:hide(hide) - for x, y, v in self:iterate() do - proteo.gui.setHidden(v,hide) - end - - for i=1,#self.grid_rectangles do - proteo.graphics.setHidden(self.grid_rectangles[i],hide) - end - - local tmp_hide=true - if hide then - tmp_hide=true - else - tmp_hide=self.hiddenGrid - end - - for i=1,#self.grid_lines do - proteo.graphics.setHidden(self.grid_lines[i],tmp_hide) - end - - if not hide then - proteo.graphics.setBackground(self.backgroundColor) - end - end - return self; - end -end diff --git a/server/lib/class.lua b/server/lib/class.lua deleted file mode 100644 index e384af7..0000000 --- a/server/lib/class.lua +++ /dev/null @@ -1,183 +0,0 @@ -------------------------------------------------------------------------------- --- Lua with Classes --- lclass --- Author: Andrew McWatters -------------------------------------------------------------------------------- -local setmetatable = setmetatable -local package = package -local type = type -local error = error -local pcall = pcall -local unpack = unpack -local newproxy = newproxy -local string = string -local rawget = rawget -local ipairs = ipairs -local module = module -local _G = _G - -------------------------------------------------------------------------------- --- new() --- Purpose: Creates an object --- Input: metatable --- Output: object -------------------------------------------------------------------------------- -local function new( metatable ) - local object = {} - setmetatable( object, metatable ) - return object -end - -------------------------------------------------------------------------------- --- getbaseclass() --- Purpose: Get a base class --- Input: class - Class metatable --- Output: class -------------------------------------------------------------------------------- -local function getbaseclass( class ) - local name = class.__base - return package.loaded[ name ] -end - -_G.getbaseclass = getbaseclass - -------------------------------------------------------------------------------- --- eventnames --- Purpose: Provide a list of all inheritable internal event names -------------------------------------------------------------------------------- -local eventnames = { - "__add", "__sub", "__mul", "__div", "__mod", - "__pow", "__unm", "__len", "__lt", "__le", - "__concat", "__call", - "__tostring" -} - -------------------------------------------------------------------------------- --- metamethod() --- Purpose: Creates a filler metamethod for metamethod inheritance --- Input: class - Class metatable --- eventname - Event name --- Output: function -------------------------------------------------------------------------------- -local function metamethod( class, eventname ) - return function( ... ) - local event = nil - local base = getbaseclass( class ) - while ( base ~= nil ) do - if ( base[ eventname ] ) then - event = base[ eventname ] - break - end - base = getbaseclass( base ) - end - local type = type( event ) - if ( type ~= "function" ) then - error( "attempt to call metamethod '" .. eventname .. "' " .. - "(a " .. type .. " value)", 2 ) - end - local returns = { pcall( event, ... ) } - if ( returns[ 1 ] ~= true ) then - error( returns[ 2 ], 2 ) - else - return unpack( returns, 2 ) - end - end -end - -------------------------------------------------------------------------------- --- setproxy() --- Purpose: Set a proxy for __gc --- Input: object -------------------------------------------------------------------------------- -local function setproxy( object ) - local __newproxy = newproxy( true ) - local metatable = getmetatable( __newproxy ) - metatable.__gc = function() - local metatable = getmetatable( object ) - metatable.__gc( object ) - end - object.__newproxy = __newproxy -end - -_G.setproxy = setproxy - -------------------------------------------------------------------------------- --- package.class --- Purpose: Turns a module into a class --- Input: module - Module table -------------------------------------------------------------------------------- -function package.class( module ) - module.__index = module - module.__type = string.gsub( module._NAME, module._PACKAGE, "" ) - -- Create a shortcut to name() - setmetatable( module, { - __call = function( self, ... ) - -- Create an instance of this object - local object = new( self ) - -- Call its constructor (function name:name( ... ) ... end) if it - -- exists - local constructor = rawget( self, self.__type ) - if ( constructor ~= nil ) then - local type = type( constructor ) - if ( type ~= "function" ) then - error( "attempt to call constructor '" .. name .. "' " .. - "(a " .. type .. " value)", 2 ) - end - constructor( object, ... ) - end - -- Return the instance - return object - end - } ) -end - -------------------------------------------------------------------------------- --- package.inherit --- Purpose: Sets a base class --- Input: base - Class name -------------------------------------------------------------------------------- -function package.inherit( base ) - return function( module ) - -- Set our base class - module.__base = base - -- Overwrite our existing __index value with a metamethod which checks - -- our members, metatable, and base class, in that order, a la behavior - -- via the Lua 5.1 manual's illustrative code for indexing access - module.__index = function( table, key ) - local v = rawget( module, key ) - if ( v ~= nil ) then return v end - local baseclass = getbaseclass( module ) - if ( baseclass == nil ) then - error( "attempt to index base class '" .. base .. "' " .. - "(a nil value)", 2 ) - end - local h = rawget( baseclass, "__index" ) - if ( h == nil ) then return nil end - if ( type( h ) == "function" ) then - return h( table, key ) - else - return h[ key ] - end - end - -- Create inheritable metamethods - for _, event in ipairs( eventnames ) do - module[ event ] = metamethod( module, event ) - end - end -end - -------------------------------------------------------------------------------- --- class() --- Purpose: Creates a class --- Input: name - Name of class -------------------------------------------------------------------------------- -function class( name ) - local function setmodule( name ) - module( name, package.class ) - end setmodule( name ) - -- For syntactic sugar, return a function to set inheritance - return function( base ) - local _M = package.loaded[ name ] - package.inherit( base )( _M ) - end -end diff --git a/server/lib/classy.lua b/server/lib/classy.lua deleted file mode 100644 index 98b906f..0000000 --- a/server/lib/classy.lua +++ /dev/null @@ -1,527 +0,0 @@ --- class-based OO module for Lua - --- cache globals -local assert = assert -local V = assert( _VERSION ) -local setmetatable = assert( setmetatable ) -local select = assert( select ) -local pairs = assert( pairs ) -local ipairs = assert( ipairs ) -local type = assert( type ) -local error = assert( error ) -local load = assert( load ) -local s_rep = assert( string.rep ) -local t_unpack = assert( V == "Lua 5.1" and unpack or table.unpack ) - - --- list of all metamethods that a user of this library is allowed to --- add to a class -local allowed_metamethods = { - __add = true, __sub = true, __mul = true, __div = true, - __mod = true, __pow = true, __unm = true, __concat = true, - __len = true, __eq = true, __lt = true, __le = true, __call = true, - __tostring = true, __pairs = true, __ipairs = true, __gc = true, - __newindex = true, __metatable = true, __idiv = true, __band = true, - __bor = true, __bxor = true, __bnot = true, __shl = true, - __shr = true, -} - --- this metatable is (re-)used often: -local mode_k_meta = { __mode = "k" } - --- store information for every registered class (still in use) --- [ cls ] = { --- -- the name of the class --- name = "clsname", --- -- an array of superclasses in an order suitable for method --- -- lookup, the first n are direct superclasses (parents) --- super = { n = 2, super1, super2, super1_1, super1_2 }, --- -- a set of subclasses (value is "inheritance difference") --- sub = { [ subcls1 ] = 1, [ subcls2 ] = 2 }, -- mode="k" --- -- direct member functions/variables for this class --- members = {}, --- -- the metatable for objects of this class --- o_meta = { __index = {} }, --- -- the metatable for the class itself --- c_meta = { __index = ..., __call = ..., __newindex = ... }, --- } -local classinfo = setmetatable( {}, mode_k_meta ) - - --- object constructor for the class if no custom __init function is --- defined -local function default_constructor( meta ) - return function() - return setmetatable( {}, meta ) - end -end - --- object constructor for the class if a custom __init function is --- available -local function init_constructor( meta, init ) - return function( _, ... ) - local o = setmetatable( {}, meta ) - init( o, ... ) - return o - end -end - - --- propagate a changed method to a sub class -local function propagate_update( cls, key ) - local info = classinfo[ cls ] - if info.members[ key ] ~= nil then - info.o_meta.__index[ key ] = info.members[ key ] - else - for i = 1, #info.super do - local val = classinfo[ info.super[ i ] ].members[ key ] - if val ~= nil then - info.o_meta.__index[ key ] = val - return - end - end - info.o_meta.__index[ key ] = nil - end -end - - --- __newindex handler for class proxy tables, allowing to set certain --- metamethods, initializers, and normal members. updates sub classes! -local function class_newindex( cls, key, val ) - local info = classinfo[ cls ] - if allowed_metamethods[ key ] then - assert( info.o_meta[ key ] == nil, - "overwriting metamethods not allowed" ) - info.o_meta[ key ] = val - elseif key == "__init" then - info.members.__init = val - info.o_meta.__index.__init = val - if type( val ) == "function" then - info.c_meta.__call = init_constructor( info.o_meta, val ) - else - info.c_meta.__call = default_constructor( info.o_meta ) - end - else - assert( key ~= "__class", "key '__class' is reserved" ) - info.members[ key ] = val - propagate_update( cls, key ) - for sub in pairs( info.sub ) do - propagate_update( sub, key ) - end - end -end - - --- __pairs/__ipairs metamethods for iterating members of classes -local function class_pairs( cls ) - return pairs( classinfo[ cls ].o_meta.__index ) -end - -local function class_ipairs( cls ) - return ipairs( classinfo[ cls ].o_meta.__index ) -end - - --- put the inheritance tree into a flat array using a width-first --- iteration (similar to a binary heap); also set the "inheritance --- difference" in superclasses -local function linearize_ancestors( cls, super, ... ) - local n = select( '#', ... ) - for i = 1, n do - local pcls = select( i, ... ) - assert( classinfo[ pcls ], "invalid class" ) - super[ i ] = pcls - end - super.n = n - local diff, newn = 1, n - for i,p in ipairs( super ) do - local pinfo = classinfo[ p ] - local psuper, psub = pinfo.super, pinfo.sub - if not psub[ cls ] then psub[ cls ] = diff end - for i = 1, psuper.n do - super[ #super+1 ] = psuper[ i ] - end - newn = newn + psuper.n - if i == n then - n, diff = newn, diff+1 - end - end -end - - --- create the necessary metadata for the class, setup the inheritance --- hierarchy, set a suitable metatable, and return the class -local function create_class( _, name, ... ) - assert( type( name ) == "string", "class name must be a string" ) - local cls, index = {}, {} - local o_meta = { - __index = index, - __name = name, - } - local info = { - name = name, - super = { n = 0 }, - sub = setmetatable( {}, mode_k_meta ), - members = {}, - o_meta = o_meta, - c_meta = { - __index = index, - __newindex = class_newindex, - __call = default_constructor( o_meta ), - __pairs = class_pairs, - __ipairs = class_ipairs, - __name = "class", - __metatable = false, - }, - } - linearize_ancestors( cls, info.super, ... ) - for i = #info.super, 1, -1 do - for k,v in pairs( classinfo[ info.super[ i ] ].members ) do - if k ~= "__init" then index[ k ] = v end - end - end - index.__class = cls - classinfo[ cls ] = info - return setmetatable( cls, info.c_meta ) -end - - --- the exported class module -local M = {} -setmetatable( M, { __call = create_class } ) - - --- returns the class of an object -function M.of( o ) - return type( o ) == "table" and o.__class or nil -end - - --- returns the class name of an object or class -function M.name( oc ) - if oc == nil then return nil end - oc = type( oc ) == "table" and oc.__class or oc - local info = classinfo[ oc ] - return info and info.name -end - - --- checks if an object or class is in an inheritance --- relationship with a given class -function M.is_a( oc, cls ) - if oc == nil then return nil end - local info = assert( classinfo[ cls ], "invalid class" ) - oc = type( oc ) == "table" and oc.__class or oc - if oc == cls then return 0 end - return info.sub[ oc ] -end - - --- change the type of an object to the new class -function M.cast( o, newcls ) - local info = classinfo[ newcls ] - if not info then - error( "invalid class" ) - end - setmetatable( o, info.o_meta ) - return o -end - - -local function make_delegate( cls, field, method ) - cls[ method ] = function( self, ... ) - local obj = self[ field ] - return obj[ method ]( obj, ... ) - end -end - --- create delegation methods -function M.delegate( cls, fieldname, ... ) - if type( (...) ) == "table" then - for k,v in pairs( (...) ) do - if cls[ k ] == nil and k ~= "__init" and - type( v ) == "function" then - make_delegate( cls, fieldname, k ) - end - end - else - for i = 1, select( '#', ... ) do - local k = select( i, ... ) - if cls[ k ] == nil and k ~= "__init" then - make_delegate( cls, fieldname, k ) - end - end - end - return cls -end - - --- multimethod stuff -do - -- store multimethods and map them to the meta-data - local mminfo = setmetatable( {}, mode_k_meta ) - - local erroffset = 0 - if V == "Lua 5.1" then erroffset = 1 end - - local function no_match2() - error( "no matching multimethod overload", 2+erroffset ) - end - - local function no_match3() - error( "no matching multimethod overload", 3+erroffset ) - end - - local function amb_call() - error( "ambiguous multimethod call", 3+erroffset ) - end - - local empty = {} -- just an empty table used as dummy - local FIRST_OL = 4 -- index of first overload specification - - - -- create a multimethod using the parameter indices given - -- as arguments for dynamic dispatch - function M.multimethod( ... ) - local t, n = { ... }, select( '#', ... ) - assert( n >= 1, "no polymorphic parameter for multimethod" ) - local max = 0 - for i = 1, n do - local x = t[ i ] - max = assert( x > max and x % 1 == 0 and x, - "invalid parameter overload specification" ) - end - local mm_impl = { no_match2, t, max } - local function mm( ... ) - return mm_impl[ 1 ]( mm_impl, ... ) - end - mminfo[ mm ] = mm_impl - return mm - end - - - local function make_weak() - return setmetatable( {}, mode_k_meta ) - end - - - local function calculate_cost( ol, ... ) - local c = 0 - for i = 1, select( '#', ... ) do - local a, pt = ol[ i ], select( i, ... ) - if type( a ) == "table" then -- class table - local info = classinfo[ a ] - local diff = (pt == a) and 0 or info and info.sub[ pt ] - if not diff then return nil end - c = c + diff - else -- type name - if pt ~= a then return nil end - end - end - return c - end - - - local function select_impl( cost, f, amb, ol, ... ) - local c = calculate_cost( ol, ... ) - if c then - if cost then - if c < cost then - cost, f, amb = c, ol.func, false - elseif c == cost then - amb = true - end - else - cost, f, amb = c, ol.func, false - end - end - return cost, f, amb - end - - - local function collect_type_checkers( mm, a ) - local funcs = {}, {} - for i = FIRST_OL, #mm do - local ol = mm[ i ] - for k,v in pairs( ol ) do - if type( k ) == "function" and - (a == nil or v[ a ]) and - not funcs[ k ] then - local j = #funcs+1 - funcs[ j ] = k - funcs[ k ] = j - end - end - end - return funcs - end - - - local function c_varlist( t, m, prefix ) - local n = #t - if m >= 1 then - t[ n+1 ] = prefix - t[ n+2 ] = 1 - end - for i = 2, m do - local j = i*3+n - t[ j-3 ] = "," - t[ j-2 ] = prefix - t[ j-1 ] = i - end - end - - local function c_typecheck( t, mm, funcs, j ) - local n, ai = #t, mm[ 2 ][ j ] - t[ n+1 ] = " t=type(_" - t[ n+2 ] = ai - t[ n+3 ] = ")\n local t" - t[ n+4 ] = j - t[ n+5 ] = "=(t=='table' and _" - t[ n+6 ] = ai - t[ n+7 ] = ".__class) or " - local ltcs = collect_type_checkers( mm, j ) - local m = #ltcs - for i = 1, m do - local k = i*5+n+3 - t[ k ] = "tc" - t[ k+1 ] = funcs[ ltcs[ i ] ] - t[ k+2 ] = "(_" - t[ k+3 ] = ai - t[ k+4 ] = ") or " - end - t[ m*5+n+8 ] = "t\n" - end - - local function c_cache( t, mm ) - local c = #mm[ 2 ] - local n = #t - t[ n+1 ] = s_rep( "(", c-1 ) - t[ n+2 ] = "cache" - for i = 1, c-1 do - local j = i*3+n - t[ j ] = "[t" - t[ j+1 ] = i - t[ j+2 ] = "] or empty)" - end - local j = c*3+n - t[ j ] = "[t" - t[ j+1 ] = c - t[ j+2 ] = "]\n" - end - - local function c_costcheck( t, i, j ) - local n = #t - t[ n+1 ] = " cost,f,is_amb=sel_impl(cost,f,is_amb,mm[" - t[ n+2 ] = j+FIRST_OL-1 - t[ n+3 ] = "]," - c_varlist( t, i, "t" ) - t[ #t+1 ] = ")\n" - end - - local function c_updatecache( t, i ) - local n = #t - t[ n+1 ] = " if not t[t" - t[ n+2 ] = i - t[ n+3 ] = "] then t[t" - t[ n+4 ] = i - t[ n+5 ] = "]=mk_weak() end\n t=t[t" - t[ n+6 ] = i - t[ n+7 ] = "]\n" - end - - - local function recompile_and_call( mm, ... ) - local n = #mm[ 2 ] -- number of polymorphic parameters - local tcs = collect_type_checkers( mm ) - local code = { - "local type,cache,empty,mk_weak,sel_impl,no_match,amb_call" - } - if #tcs >= 1 then - code[ #code+1 ] = "," - end - c_varlist( code, #tcs, "tc" ) - code[ #code+1 ] = "=...\nreturn function(mm," - c_varlist( code, mm[ 3 ], "_" ) - code[ #code+1 ] = ",...)\n local t\n" - for i = 1, n do - c_typecheck( code, mm, tcs, i ) - end - code[ #code+1 ] = " local f=" - c_cache( code, mm ) - code[ #code+1 ] = [=[ - if f==nil then - local is_amb,cost -]=] - for i = 1, #mm-FIRST_OL+1 do - c_costcheck( code, n, i ) - end - code[ #code+1 ] = [=[ - if f==nil then - no_match() - elseif is_amb then - amb_call() - end - t=cache -]=] - for i = 1, n-1 do - c_updatecache( code, i ) - end - code[ #code+1 ] = " t[t" - code[ #code+1 ] = n - code[ #code+1 ] = "]=f\n end\n return f(" - c_varlist( code, mm[ 3 ], "_" ) - code[ #code+1 ] = ",...)\nend\n" - local i = 0 - local function ld() - i = i + 1 - return code[ i ] - end - --print( table.concat( code ) ) -- XXX - local f = assert( load( ld, "=[multimethod]" ) )( - type, make_weak(), empty, make_weak, select_impl, no_match3, - amb_call, t_unpack( tcs ) - ) - mm[ 1 ] = f - return f( mm, ... ) - end - - - -- register a new overload for this multimethod - function M.overload( f, ... ) - local mm = assert( type( f ) == "function" and mminfo[ f ], - "argument is not a multimethod" ) - local i, n = 1, select( '#', ... ) - local ol = {} - local func = assert( n >= 1 and select( n, ... ), - "missing function in overload specification" ) - while i < n do - local a = select( i, ... ) - local t = type( a ) - if t == "string" then - ol[ #ol+1 ] = a - elseif t == "table" then - assert( classinfo[ a ], "invalid class" ) - ol[ #ol+1 ] = a - else - assert( t == "function", "invalid overload specification" ) - i = i + 1 - assert( i < n, "missing function in overload specification" ) - ol[ a ] = ol[ a ] or {} - ol[ #ol+1 ] = select( i, ... ) - ol[ a ][ #ol ] = true - end - i = i + 1 - end - assert( #mm[ 2 ] == #ol, "wrong number of overloaded parameters" ) - ol.func = func - mm[ #mm+1 ] = ol - mm[ 1 ] = recompile_and_call - end - -end - - --- return module table -return M - diff --git a/server/lib/demo_lib.lua b/server/lib/demo_lib.lua index 33c33a1..49447b3 100644 --- a/server/lib/demo_lib.lua +++ b/server/lib/demo_lib.lua @@ -368,7 +368,7 @@ demo.start_callback = function(res,data) demo.zmq_context = proteo.zmq.ctx_new() demo.zmq_socket = proteo.zmq.socket_new(demo.zmq_context,proteo.zmq.sockType.ZMQ_REQ) - proteo.zmq.connect(demo.zmq_socket,'tcp://localhost:5555') + proteo.zmq.connect(demo.zmq_socket,'tcp://poseidone.irib.cloud:5555') demo.frame = proteo.opencv.img() demo.cap = proteo.opencv.videocapture(0) diff --git a/server/lib/middleclass.lua b/server/lib/middleclass.lua deleted file mode 100644 index 0d9a834..0000000 --- a/server/lib/middleclass.lua +++ /dev/null @@ -1,170 +0,0 @@ -local middleclass = { - _VERSION = 'middleclass v4.1.0', - _DESCRIPTION = 'Object Orientation for Lua', - _URL = 'https://github.com/kikito/middleclass', - _LICENSE = [[ - MIT LICENSE - - Copyright (c) 2011 Enrique García Cota - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ]] -} - -local function _createIndexWrapper(aClass, f) - if f == nil then - return aClass.__instanceDict - else - return function(self, name) - local value = aClass.__instanceDict[name] - - if value ~= nil then - return value - elseif type(f) == "function" then - return (f(self, name)) - else - return f[name] - end - end - end -end - -local function _propagateInstanceMethod(aClass, name, f) - f = name == "__index" and _createIndexWrapper(aClass, f) or f - aClass.__instanceDict[name] = f - - for subclass in pairs(aClass.subclasses) do - if rawget(subclass.__declaredMethods, name) == nil then - _propagateInstanceMethod(subclass, name, f) - end - end -end - -local function _declareInstanceMethod(aClass, name, f) - aClass.__declaredMethods[name] = f - - if f == nil and aClass.super then - f = aClass.super.__instanceDict[name] - end - - _propagateInstanceMethod(aClass, name, f) -end - -local function _tostring(self) return "class " .. self.name end -local function _call(self, ...) return self:new(...) end - -local function _createClass(name, super) - local dict = {} - dict.__index = dict - - local aClass = { name = name, super = super, static = {}, - __instanceDict = dict, __declaredMethods = {}, - subclasses = setmetatable({}, {__mode='k'}) } - - if super then - setmetatable(aClass.static, { __index = function(_,k) return rawget(dict,k) or super.static[k] end }) - else - setmetatable(aClass.static, { __index = function(_,k) return rawget(dict,k) end }) - end - - setmetatable(aClass, { __index = aClass.static, __tostring = _tostring, - __call = _call, __newindex = _declareInstanceMethod }) - - return aClass -end - -local function _includeMixin(aClass, mixin) - assert(type(mixin) == 'table', "mixin must be a table") - - for name,method in pairs(mixin) do - if name ~= "included" and name ~= "static" then aClass[name] = method end - end - - for name,method in pairs(mixin.static or {}) do - aClass.static[name] = method - end - - if type(mixin.included)=="function" then mixin:included(aClass) end - return aClass -end - -local DefaultMixin = { - __tostring = function(self) return "instance of " .. tostring(self.class) end, - - initialize = function(self, ...) end, - - isInstanceOf = function(self, aClass) - return type(aClass) == 'table' and (aClass == self.class or self.class:isSubclassOf(aClass)) - end, - - static = { - allocate = function(self) - assert(type(self) == 'table', "Make sure that you are using 'Class:allocate' instead of 'Class.allocate'") - return setmetatable({ class = self }, self.__instanceDict) - end, - - new = function(self, ...) - assert(type(self) == 'table', "Make sure that you are using 'Class:new' instead of 'Class.new'") - local instance = self:allocate() - instance:initialize(...) - return instance - end, - - subclass = function(self, name) - assert(type(self) == 'table', "Make sure that you are using 'Class:subclass' instead of 'Class.subclass'") - assert(type(name) == "string", "You must provide a name(string) for your class") - - local subclass = _createClass(name, self) - - for methodName, f in pairs(self.__instanceDict) do - _propagateInstanceMethod(subclass, methodName, f) - end - subclass.initialize = function(instance, ...) return self.initialize(instance, ...) end - - self.subclasses[subclass] = true - self:subclassed(subclass) - - return subclass - end, - - subclassed = function(self, other) end, - - isSubclassOf = function(self, other) - return type(other) == 'table' and - type(self.super) == 'table' and - ( self.super == other or self.super:isSubclassOf(other) ) - end, - - include = function(self, ...) - assert(type(self) == 'table', "Make sure you that you are using 'Class:include' instead of 'Class.include'") - for _,mixin in ipairs({...}) do _includeMixin(self, mixin) end - return self - end - } -} - -function middleclass.class(name, super) - assert(type(name) == 'string', "A name (string) is needed for the new class") - return super and super:subclass(name) or _includeMixin(_createClass(name), DefaultMixin) -end - -setmetatable(middleclass, { __call = function(_, ...) return middleclass.class(...) end }) - -return middleclass diff --git a/server/lib/room.lua b/server/lib/room.lua deleted file mode 100644 index ca88577..0000000 --- a/server/lib/room.lua +++ /dev/null @@ -1,75 +0,0 @@ ---[[ - - ---]] - -local host = proteo.enet.host_create() -local server = nil - -local rooms={} -local peer_server=nil -local init_callback=nil - -local function split(s, sep) - local fields = {} - - local sep = sep or " " - local pattern = string.format("([^%s]+)", sep) - string.gsub(s, pattern, function(c) fields[#fields + 1] = c end) - - return fields -end - -proteo.network.roomInit = function(server,callback) - print("roomInit: "..server) - server = host:connect(server) - init_callback=callback -end - -proteo.network.roomConnect = function(room,callback) - print("roomConnect: "..room.."->"..callback) - rooms[room]={} - rooms[room].callback=callback - rooms[room].state="wait" - peer_server:send(room.."#connect") -end - -proteo.network.roomDisconnect = function(room) - -end - -proteo.network.roomSend = function(room,data) - peer_server:send(room.."#"..data) -end - ---Deve essere invocata dentro l'update dello script che lo usa -proteo.network.roomCheck = function() - --print("roomCheck") - local event = host:service(0) - while event do - if event.type == "receive" then - --print("Got message: ", event.data, event.peer) - --event.peer:send( "ping" ) - local split_room=split(event.data, "#") - if #split_room==2 then - if rooms[split_room[1]] ~= nil then - if split_room[2]=="connected" then rooms[split_room[1]].state="connected" end - _G[rooms[split_room[1]].callback](split_room[1],split_room[2]) - end - end - elseif event.type == "connect" then - print(event.peer, "connected.") - --event.peer:send( "ping" ) - peer_server=event.peer - - --local f=loadstring('return '..init_callback) - --if f==nil then print("Callback error: " .. init_callback) - --else f() print("Call : " .. init_callback) end - _G[init_callback]() - - elseif event.type == "disconnect" then - print(event.peer, "disconnected.") - end - event = host:service() - end -end diff --git a/server/lib/skl_utility.lua b/server/lib/skl_utility.lua index a4bd98c..98ffaa9 100644 --- a/server/lib/skl_utility.lua +++ b/server/lib/skl_utility.lua @@ -4,13 +4,13 @@ local inspect = require "inspect" function svg2shape (svgfile, shape) for i=1,#svgfile do - print("Shape "..i..") "..svgfile[i].id.." color: "..svgfile[i].fill_color) + if VERBOSE then print("Shape "..i..") "..svgfile[i].id.." color: "..svgfile[i].fill_color) end for j=1,#svgfile[i] do - print(" Path "..j) + if VERBOSE then print(" Path "..j) end local p=proteo.graphics.newPolygon(svgfile[i].id.."_"..j,"clear",svgfile[i].fill_color,0,0) proteo.graphics.addItem(shape,p) for k=1,#svgfile[i][j] do - print(" Bezier "..k..") x0:"..svgfile[i][j][k].x0.." y0:"..svgfile[i][j][k].y0.." x3:"..svgfile[i][j][k].x3.." y3:"..svgfile[i][j][k].y3) + if VERBOSE then rint(" Bezier "..k..") x0:"..svgfile[i][j][k].x0.." y0:"..svgfile[i][j][k].y0.." x3:"..svgfile[i][j][k].x3.." y3:"..svgfile[i][j][k].y3) end proteo.graphics.addBezier(p,svgfile[i][j][k].x0,svgfile[i][j][k].y0, svgfile[i][j][k].x1,svgfile[i][j][k].y1, svgfile[i][j][k].x2,svgfile[i][j][k].y2, @@ -23,11 +23,11 @@ end function json2skl(jsonfile,skeleton) for k, j in pairs(jsonfile.joints) do - print("Joint ("..k..") x: "..j.x.." y: "..j.y) + if VERBOSE then print("Joint ("..k..") x: "..j.x.." y: "..j.y) end proteo.graphics.addJoint(k,skeleton,j.x,j.y) end for k, b in pairs(jsonfile.bones) do - print("Bone ("..k..") a: "..b.a.." yb: "..b.b.." group: "..b.group) + if VERBOSE then print("Bone ("..k..") a: "..b.a.." yb: "..b.b.." group: "..b.group) end proteo.graphics.addBone(k,skeleton,b.a,b.b,b.group) end end diff --git a/server/lib/strict.lua b/server/lib/strict.lua deleted file mode 100644 index c67243f..0000000 --- a/server/lib/strict.lua +++ /dev/null @@ -1,39 +0,0 @@ --- From http://metalua.luaforge.net/src/lib/strict.lua.html --- --- strict.lua --- checks uses of undeclared global variables --- All global variables must be 'declared' through a regular assignment --- (even assigning nil will do) in a main chunk before being used --- anywhere or assigned to inside a function. --- - -local mt = getmetatable(_G) -if mt == nil then - mt = {} - setmetatable(_G, mt) -end - -__STRICT = true -mt.__declared = {} - -mt.__newindex = function (t, n, v) - if __STRICT and not mt.__declared[n] then - local w = debug.getinfo(2, "S").what - if w ~= "main" and w ~= "C" then - error("assign to undeclared variable '"..n.."'", 2) - end - mt.__declared[n] = true - end - rawset(t, n, v) -end - -mt.__index = function (t, n) - if not mt.__declared[n] and debug.getinfo(2, "S").what ~= "C" then - error("variable '"..n.."' is not declared", 2) - end - return rawget(t, n) -end - -function global(...) - for _, v in ipairs{...} do mt.__declared[v] = true end -end diff --git a/server/lib/tetris_lib.lua b/server/lib/tetris_lib.lua index a59d003..6ab5a6d 100644 --- a/server/lib/tetris_lib.lua +++ b/server/lib/tetris_lib.lua @@ -1,5 +1,6 @@ local inspect = require("inspect") local json=require "json" +require "tfl_blazepose" require "tfl_utility" @@ -26,6 +27,8 @@ tetris.left_move_rotate = function() end end +--REMOTE TFL +--[[ tetris.pose = function(data) for _, b in ipairs(data['data']) do landmarks = show_landmark(b,tetris.template.left_frame,b['landmarks']) @@ -37,6 +40,7 @@ tetris.pose = function(data) end end + tetris.pipe = function(json_data) data = json.decode(json_data) proteo.opencv.frame(tetris.left_cap,tetris.template.left_frame) @@ -53,14 +57,41 @@ tetris.pipe = function(json_data) return json.encode(data) end + tetris.update_event = function(dt) + if tetris.zmq_socket_tetris ~= nil then buffer = proteo.zmq.recv(tetris.zmq_socket_tetris,proteo.zmq.flag.ZMQ_DONTWAIT) if buffer ~= nil then proteo.zmq.send (tetris.zmq_socket_tetris,(tetris.pipe(buffer)),proteo.zmq.flag.ZMQ_DONTWAIT) end end + + end + ]]-- +--============= + +--LOCAL TFL +tetris.update_local_event = function(dt) + + proteo.opencv.frame(tetris.left_cap,tetris.template.left_frame) + + bbox = invoke_pose_detect(tetris.template.left_frame) + size = proteo.opencv.size(tetris.template.left_frame) + + for i=1,#bbox do + feed_image = generate_pose_landmark_input_image(tetris.template.left_frame,bbox[i]) + bbox[i].landmarks=invoke_pose_landmark(feed_image) + landmarks = get_landmark(bbox[i],tetris.template.left_frame,bbox[i].landmarks) + show_pose(landmarks,tetris.template.left_frame) + tetris.pose_control(landmarks) + end + + proteo.opencv.flip(tetris.template.left_frame,tetris.template.left_frame,1) + proteo.graphics.changeImage(tetris.template.left_image,tetris.template.left_frame) +end +--============= tetris.update_t_event = function(dt) if tetris.check_t_left(tetris.DOWN) ~= 1 then @@ -310,16 +341,22 @@ tetris.check_t_left = function(d) return 0 end +--REMOTE TFL +--[[ tetris.start_callback = function(res,data) tetris.current_session = data['session'] proteo.system.stopTimer(tetris.webcam_timer) proteo.system.startTimer(tetris.t_timer) + + tetris.zmq_context_tetris = proteo.zmq.ctx_new() tetris.zmq_socket_tetris = proteo.zmq.socket_new(tetris.zmq_context_tetris,proteo.zmq.sockType.ZMQ_REQ) - proteo.zmq.connect(tetris.zmq_socket_tetris,'tcp://localhost:5555') + proteo.zmq.connect(tetris.zmq_socket_tetris,'tcp://poseidone.irib.cloud:5555') + proteo.opencv.frame(tetris.left_cap,tetris.template.left_frame) proteo.opencv.flip(tetris.template.left_frame,tetris.template.left_frame,1) proteo.graphics.changeImage(tetris.template.left_image,tetris.template.left_frame) + tmp = proteo.opencv.imencode(tetris.template.left_frame) data = {} data['type']='FRAME' @@ -328,12 +365,23 @@ tetris.start_callback = function(res,data) data['encoding']='JPEG' data['request']='TFLPOSE' proteo.zmq.send (tetris.zmq_socket_tetris,json.encode(data),proteo.zmq.flag.ZMQ_DONTWAIT) + tetris.event_timer = proteo.system.createTimer(50,tetris.update_event) proteo.system.startTimer(tetris.event_timer) end + ]]-- + --=========== tetris.start = function(sender) - proteo.network.proteo_post("/deepcrimson/start",'{}',tetris.start_callback) + +--REMOTE TFL +--proteo.network.proteo_post("/deepcrimson/start",'{}',tetris.start_callback) +--LOCAL TFL + proteo.system.stopTimer(tetris.webcam_timer) + proteo.system.startTimer(tetris.t_timer) + tetris.event_timer = proteo.system.createTimer(50,tetris.update_local_event) + proteo.system.startTimer(tetris.event_timer) +--========== end tetris.update_left_square = function() @@ -407,7 +455,7 @@ tetris.create_template = function(pose_control_function) proteo.opencv.setBufferSize(tetris.left_cap,3) proteo.opencv.frame(tetris.left_cap,tetris.template.left_frame) tetris.template.sagoma = proteo.opencv.imread(proteo.system.document()..'sagoma.jpg') - proteo.opencv.resize(tetris.template.sagoma,tetris.template.sagoma,480,640) + proteo.opencv.resize(tetris.template.sagoma,tetris.template.sagoma,480,640) tetris.webcam_timer = proteo.system.createTimer(300,tetris.webcam_event) proteo.system.startTimer(tetris.webcam_timer) for y = 1, 20, 1 do @@ -421,4 +469,4 @@ tetris.create_template = function(pose_control_function) tetris.update_t_left() end -return tetris \ No newline at end of file +return tetris diff --git a/server/lib/tfl_blazeface.lua b/server/lib/tfl_blazeface.lua index b98212f..6d1ab0a 100644 --- a/server/lib/tfl_blazeface.lua +++ b/server/lib/tfl_blazeface.lua @@ -8,10 +8,10 @@ local function decode_face_bounds (scores, bbox, score_thresh, input_img_w, inpu local region_list={} - for i=1,#anchors do + for i=1,#face_anchors do region = {} - anchor = anchors[i] + anchor = face_anchors[i] score0 = scores[i] score = 1.0 / (1.0 + math.exp(-score0)) @@ -207,8 +207,8 @@ kRightEyeTragion=6 FACE_LM_NUM=468 -local tfl_detect_model=proteo.tflite.modelFromFile("pose/face_detection_front.tflite") -local tfl_landmark_model=proteo.tflite.modelFromFile("pose/face_landmark.tflite") +local tfl_detect_model=proteo.tflite.modelFromFile(proteo.system.document().."dl/face_detection_front.tflite") +local tfl_landmark_model=proteo.tflite.modelFromFile(proteo.system.document().."dl/face_landmark.tflite") local tfl_interpreter_options=proteo.tflite.createInterpreterOptions() @@ -235,7 +235,7 @@ local tfl_landmark_score_outputTensorSize=proteo.tflite.getTensorSize(tfl_landma local tfl_frame=proteo.opencv.img() proteo.opencv.setSize(tfl_frame,tfl_detect_inputTensorSize[2],tfl_detect_inputTensorSize[3]) -local anchors=create_face_ssd_anchors(tfl_detect_inputTensorSize[3],tfl_detect_inputTensorSize[2]) +face_anchors=create_face_ssd_anchors(tfl_detect_inputTensorSize[3],tfl_detect_inputTensorSize[2]) --ocv_detect_model=proteo.opencv.readnet("pose/pose_detection_model_float32.pb","") --proteo.opencv.infoNet(ocv_detect_model) diff --git a/server/lib/tfl_blazepose.lua b/server/lib/tfl_blazepose.lua index 87aeddf..700d1ec 100644 --- a/server/lib/tfl_blazepose.lua +++ b/server/lib/tfl_blazepose.lua @@ -13,10 +13,10 @@ function decode_pose_bounds (scores, bbox, score_thresh, input_img_w, input_img_ --print("#anchors: "..#anchors) --print("#bbox: "..#bbox) - for i=1,#anchors do + for i=1,#pose_anchors do region = {} - anchor = anchors[i] + anchor = pose_anchors[i] score0 = scores[i] score = 1.0 / (1.0 + math.exp(-score0)) @@ -169,7 +169,7 @@ function pack_detect_pose_result (region_list) end -function create_pose_ssd_anchors(input_w,intput_h) +function create_pose_ssd_anchors_old(input_w,intput_h) local anchor_options = {} anchor_options.num_layers = 4 @@ -191,6 +191,27 @@ function create_pose_ssd_anchors(input_w,intput_h) return GenerateAnchors(anchor_options) end +function create_pose_ssd_anchors(input_w,intput_h) + + local anchor_options = {} + anchor_options.num_layers = 5 + anchor_options.strides = {8,16,32,32,32} + anchor_options.aspect_ratios = {1.0} + anchor_options.feature_map_height ={} + + anchor_options.min_scale = 0.1484375 + anchor_options.max_scale = 0.75 + anchor_options.input_size_height = 224 + anchor_options.input_size_width = 224 + anchor_options.anchor_offset_x = 0.5 + anchor_options.anchor_offset_y = 0.5 + + anchor_options.reduce_boxes_in_lowest_layer = false + anchor_options.interpolated_scale_aspect_ratio = 1.0 + anchor_options.fixed_anchor_size = true + + return GenerateAnchors(anchor_options) +end --========= INIT kPoseDetectKeyNum=4 -- FullBody:4, UpperBody:2 @@ -200,8 +221,9 @@ kMidShoulderCenter=3 POSE_JOINT_NUM=33 -tfl_detect_model=proteo.tflite.modelFromFile("pose/pose_detection.tflite") -tfl_landmark_model=proteo.tflite.modelFromFile("pose/pose_landmark_full_body.tflite") +--tfl_detect_model=proteo.tflite.modelFromFile(proteo.system.document().."dl/pose_detection_old.tflite") +tfl_detect_model=proteo.tflite.modelFromFile(proteo.system.document().."dl/pose_detection.tflite") +tfl_landmark_model=proteo.tflite.modelFromFile(proteo.system.document().."dl/pose_landmark_heavy.tflite")--"dl/pose_landmark_full_body.tflite")-- tfl_interpreter_options=proteo.tflite.createInterpreterOptions() @@ -229,7 +251,7 @@ tfl_landmark_score_outputTensorSize=proteo.tflite.getTensorSize(tfl_landmark_sco tfl_frame=proteo.opencv.img() proteo.opencv.setSize(tfl_frame,tfl_detect_inputTensorSize[2],tfl_detect_inputTensorSize[3]) -anchors=create_pose_ssd_anchors(tfl_detect_inputTensorSize[3],tfl_detect_inputTensorSize[2]) +pose_anchors=create_pose_ssd_anchors(tfl_detect_inputTensorSize[3],tfl_detect_inputTensorSize[2]) --ocv_detect_model=proteo.opencv.readnet("pose/pose_detection_model_float32.pb","") --proteo.opencv.infoNet(ocv_detect_model) @@ -257,7 +279,8 @@ function invoke_pose_detect (img) scores = proteo.tflite.tensorToTable(tfl_detect_scores_tensor) bbox = proteo.tflite.tensorToTable(tfl_detect_bbox_tensor) - score_thresh = 0.4 + --score_thresh = 0.4 + score_thresh = 0.5 region_list = decode_pose_bounds (scores, bbox, score_thresh, tfl_detect_inputTensorSize[3], tfl_detect_inputTensorSize[2]) diff --git a/server/lib/tfl_emotion.lua b/server/lib/tfl_emotion.lua index 1c20b7f..93ba95a 100644 --- a/server/lib/tfl_emotion.lua +++ b/server/lib/tfl_emotion.lua @@ -5,7 +5,7 @@ local inspect = require "inspect" --========= INIT -local tfl_emotion_model=proteo.tflite.modelFromFile("pose/emotion_model_optimized.tflite") +local tfl_emotion_model=proteo.tflite.modelFromFile(proteo.system.document().."dl/emotion_model_optimized.tflite") local tfl_interpreter_options=proteo.tflite.createInterpreterOptions() diff --git a/server/lib/tfl_hand.lua b/server/lib/tfl_hand.lua new file mode 100644 index 0000000..22595d4 --- /dev/null +++ b/server/lib/tfl_hand.lua @@ -0,0 +1,322 @@ + +local inspect = require "inspect" + +require "tfl_utility" + +local function decode_hand_bounds (scores, bbox, score_thresh, input_img_w, input_img_h) + + local region_list={} + + + for i=1,#hand_anchors do + + region = {} + anchor = hand_anchors[i] + score0 = scores[i] + score = 1.0 / (1.0 + math.exp(-score0)) + + if score > score_thresh then + + local numkey = kHandDetectKeyNum + local bbx_idx = (4 + 2 * numkey) * (i-1) + + -- boundary box + local sx = bbox[bbx_idx + 1] + local sy = bbox[bbx_idx + 2] + local w = bbox[bbx_idx + 3] + local h = bbox[bbx_idx + 4] + + local cx = sx + anchor.x_center * input_img_w + local cy = sy + anchor.y_center * input_img_h + + cx = cx / input_img_w + cy = cy / input_img_h + w = w / input_img_w + h = h / input_img_h + + topleft = {} + btmright = {} + topleft.x = cx - w * 0.5 + topleft.y = cy - h * 0.5 + btmright.x = cx + w * 0.5 + btmright.y = cy + h * 0.5 + + region.score = score + region.topleft = topleft + region.btmright = btmright + + -- landmark positions (6 keys) + local keys={} + for j=1,kHandDetectKeyNum do + + local lx = bbox[bbx_idx + 4 + (2 * (j-1)) + 1] + local ly = bbox[bbx_idx + 4 + (2 * (j-1)) + 2] + lx = lx + anchor.x_center * input_img_w + ly = ly + anchor.y_center * input_img_h + lx = lx / input_img_w + ly = ly / input_img_h + + keys[j] = {} + keys[j].x=lx + keys[j].y=ly + + end + + region.keys = keys + table.insert(region_list,region) + end + end + + return region_list +end + + +function compute_detect_hand_to_roi (region) + + local input_img_w = tfl_detect_inputTensorSize[2] + local input_img_h = tfl_detect_inputTensorSize[3] + --local x_center = (region.topleft.x + region.btmright.x) * input_img_w / 2 + --local y_center = (region.topleft.y + region.btmright.y) * input_img_h / 2 + + local x_center = region.keys[kMiddle].x * input_img_w + local y_center = region.keys[kMiddle].y * input_img_h + + + --local box_size = math.sqrt((x_left - x_right) * (x_left - x_right) + + -- (y_left - y_right) * (y_left - y_right)) * 2.5 + --local box_size = math.sqrt((region.topleft.x - region.btmright.x) * (region.topleft.x - region.btmright.x) + + -- (region.topleft.y - region.btmright.y) * (region.topleft.y - region.btmright.y))*2.0 + local box_size = math.max(math.abs(region.topleft.x - region.btmright.x) * input_img_w,math.abs(region.topleft.y - region.btmright.y) * input_img_h) + + ---se il volto è troppo lontano questo valore diventa troppo piccolo (ad occhio sotto il 40) + + -- RectTransformationCalculator::TransformNormalizedRect() + local width = math.max(math.abs(region.topleft.x - region.btmright.x) * input_img_w, math.abs(region.keys[kThumb_MCP].x - region.keys[kPinky].x) * input_img_w) --box_size + local height = math.max(math.abs(region.topleft.y - region.btmright.y) * input_img_h, math.abs(region.keys[kWrist].y - region.keys[kMiddle].y) * input_img_h) --box_size + local rotation = region.rotation + local shift_x = 0.0 + local shift_y = 0.0 + local roi_cx + local roi_cy + + if rotation == 0.0 then + + roi_cx = x_center + (width * shift_x) + roi_cy = y_center + (height * shift_y) + + else + + local dx = (width * shift_x) * math.cos(rotation) - + (height * shift_y) * math.sin(rotation) + local dy = (width * shift_x) * math.sin(rotation) + + (height * shift_y) * math.cos(rotation) + roi_cx = x_center + dx + roi_cy = y_center + dy + end + + local scale_x = 2.6 --1.5 + local scale_y = 2.6 --1.5 + local long_side = math.max (width, height) + local roi_w = long_side * scale_x + local roi_h = long_side * scale_y + + region.roi_center = {x = roi_cx / input_img_w, y= roi_cy / input_img_h} + region.roi_size = {x= roi_w / input_img_w, y= roi_h / input_img_h} + + -- calculate ROI coordinates + local dx = roi_w * 0.5 + local dy = roi_h * 0.5 + region.roi_coord = {} + region.roi_coord[1] = {x= - dx, y= - dy} + region.roi_coord[2] = {x= dx, y= - dy} + region.roi_coord[3] = {x= dx, y= dy} + region.roi_coord[4] = {x= - dx, y= dy} + + for i = 1,4 do + rot_vec (region.roi_coord[i], rotation) + region.roi_coord[i].x = region.roi_coord[i].x + roi_cx + region.roi_coord[i].y = region.roi_coord[i].y + roi_cy + + region.roi_coord[i].x = region.roi_coord[i].x / input_img_h + region.roi_coord[i].y = region.roi_coord[i].y / input_img_h + end +end + +function pack_detect_hand_result (region_list) + + local detect_result={} + + for i = 1,#region_list do + + region = region_list[i] + + compute_rotation (region,kWrist,kMiddle) + compute_detect_hand_to_roi (region) + + table.insert(detect_result,region) + end + + return detect_result + +end + +function create_hand_ssd_anchors(input_w,intput_h) + + local anchor_options = {} + anchor_options.num_layers = 4 + anchor_options.strides = {8,16,16,16} + anchor_options.aspect_ratios = {1.0} + anchor_options.feature_map_height ={} + + anchor_options.min_scale = 0.1484375 + anchor_options.max_scale = 0.75 + anchor_options.input_size_height = 128 + anchor_options.input_size_width = 128 + anchor_options.anchor_offset_x = 0.5 + anchor_options.anchor_offset_y = 0.5 + + anchor_options.reduce_boxes_in_lowest_layer = false + anchor_options.interpolated_scale_aspect_ratio = 1.0 + anchor_options.fixed_anchor_size = true + +--[[ +# Options to generate anchors for SSD object detection models. + ssd_anchors_calculator_options = SsdAnchorsCalculatorOptions(input_size_width=256, input_size_height=256, min_scale=0.15625, max_scale=0.75 + , anchor_offset_x=0.5, anchor_offset_y=0.5, num_layers=4 + , feature_map_width=[], feature_map_height=[] + , strides=[16, 32, 32, 32], aspect_ratios=[1.0] + , reduce_boxes_in_lowest_layer=False, interpolated_scale_aspect_ratio=1.0 + , fixed_anchor_size=True) + ]] + return GenerateAnchors(anchor_options) +end + + +--========= INIT + +kHandDetectKeyNum=7 + +kWrist=1 +kIndex=2 +kMiddle=3 +kRing=4 +kPinky=5 +kThumb_CMC=6 +kThumb_MCP=7 + +HAND_LM_NUM=21 + +local tfl_detect_model=proteo.tflite.modelFromFile(proteo.system.document().."dl/palm_detection.tflite") +local tfl_landmark_model=proteo.tflite.modelFromFile(proteo.system.document().."dl/hand_landmark.tflite") + +local tfl_interpreter_options=proteo.tflite.createInterpreterOptions() + +local tfl_detect_interpreter=proteo.tflite.createInterpreter(tfl_detect_model,tfl_interpreter_options) +proteo.tflite.InterpreterAllocateTensors(tfl_detect_interpreter) + +local tfl_landmark_interpreter=proteo.tflite.createInterpreter(tfl_landmark_model,tfl_interpreter_options) +proteo.tflite.InterpreterAllocateTensors(tfl_landmark_interpreter) + +local tfl_detect_input_tensor =proteo.tflite.InterpreterGetInputTensor(tfl_detect_interpreter, 0) +local tfl_detect_inputTensorSize=proteo.tflite.getTensorSize(tfl_detect_input_tensor) + +local tfl_landmark_input_tensor =proteo.tflite.InterpreterGetInputTensor(tfl_landmark_interpreter, 0) +local tfl_landmark_inputTensorSize=proteo.tflite.getTensorSize(tfl_landmark_input_tensor) + +local tfl_detect_scores_tensor =proteo.tflite.InterpreterGetOutputTensor(tfl_detect_interpreter, 1) +local tfl_detect_scores_outputTensorSize=proteo.tflite.getTensorSize(tfl_detect_scores_tensor) +local tfl_detect_bbox_tensor =proteo.tflite.InterpreterGetOutputTensor(tfl_detect_interpreter, 0) +local tfl_detect_bbox_outputTensorSize=proteo.tflite.getTensorSize(tfl_detect_bbox_tensor) + +local tfl_landmark_score_tensor =proteo.tflite.InterpreterGetOutputTensor(tfl_landmark_interpreter, 0) +local tfl_landmark_score_outputTensorSize=proteo.tflite.getTensorSize(tfl_landmark_score_tensor) + +local tfl_frame=proteo.opencv.img() +proteo.opencv.setSize(tfl_frame,tfl_detect_inputTensorSize[2],tfl_detect_inputTensorSize[3]) + +hand_anchors=create_hand_ssd_anchors(tfl_detect_inputTensorSize[3],tfl_detect_inputTensorSize[2]) + +--ocv_detect_model=proteo.opencv.readnet("pose/pose_detection_model_float32.pb","") +--proteo.opencv.infoNet(ocv_detect_model) + +function invoke_hand_detect (img) + + proteo.opencv.resize(img,tfl_frame) + proteo.opencv.convert(tfl_frame,tfl_frame,proteo.opencv.matType.CV_32F,tfl_detect_inputTensorSize[4]) + + + proteo.opencv.mul(tfl_frame,1.0/255.0,tfl_frame) + proteo.opencv.add(tfl_frame,-0.5,tfl_frame) + proteo.opencv.mul(tfl_frame,2.0,tfl_frame) + + proteo.tflite.copyImage(tfl_detect_input_tensor,tfl_frame) + + --[[proteo.tflite.copyTensor(tfl_frame,tfl_detect_input_tensor) + proteo.opencv.mul(tfl_frame,0.5,tfl_frame) + proteo.opencv.add(tfl_frame,0.5,tfl_frame) + proteo.opencv.mul(tfl_frame,255.0,tfl_frame) + proteo.opencv.imwrite(proteo.system.document().."prova.jpg",tfl_frame)]] + + proteo.tflite.interpreterInvoke(tfl_detect_interpreter) + + scores = proteo.tflite.tensorToTable(tfl_detect_scores_tensor) + bbox = proteo.tflite.tensorToTable(tfl_detect_bbox_tensor) + score_thresh = 0.5 + + region_list = decode_hand_bounds (scores, bbox, score_thresh, tfl_detect_inputTensorSize[3], tfl_detect_inputTensorSize[2]) + + iou_thresh = 0.3 + + region_nms_list = non_max_suppression (region_list, iou_thresh) + + detect_result=pack_detect_hand_result (region_nms_list) + + --print(inspect(detect_result)) + + return detect_result +end + +function invoke_hand_landmark(img) + landmark_result={} + + proteo.tflite.copyImage(tfl_landmark_input_tensor,img) + proteo.tflite.interpreterInvoke(tfl_landmark_interpreter) + + landmarks = proteo.tflite.tensorToTable(tfl_landmark_score_tensor) + + landmark_result.score = 0 --TODO + landmark_result.joint={} + for i = 1,HAND_LM_NUM do + landmark_result.joint[i]={} + landmark_result.joint[i].x = landmarks[3 * (i-1) + 1] / tfl_landmark_inputTensorSize[3] + landmark_result.joint[i].y = landmarks[3 * (i-1) + 2] / tfl_landmark_inputTensorSize[2] + landmark_result.joint[i].z = landmarks[3 * (i-1) + 3] + end + + + return landmark_result +end + +function generate_hand_landmark_input_image (image, pose) + + local size=proteo.opencv.size(image) + local H=size[1] + local W=size[2] + + local mat=proteo.opencv.getAffineTransform(pose.roi_coord[1].x * W, pose.roi_coord[1].y * H + ,pose.roi_coord[2].x * W, pose.roi_coord[2].y * H + ,pose.roi_coord[3].x * W, pose.roi_coord[3].y * H + ,0,0 + ,tfl_landmark_inputTensorSize[3],0 + ,tfl_landmark_inputTensorSize[3],tfl_landmark_inputTensorSize[2] ) + img_affine=proteo.opencv.img() + proteo.opencv.setImg(img_affine,tfl_landmark_inputTensorSize[3],tfl_landmark_inputTensorSize[2],"#000000") + proteo.opencv.warpAffine(image,img_affine,mat) + + --proteo.opencv.imwrite(proteo.system.document().."prova.jpg",img_affine) + + proteo.opencv.convert(img_affine,img_affine,proteo.opencv.matType.CV_32F,tfl_landmark_inputTensorSize[4]) + proteo.opencv.mul(img_affine,1.0/255.0,img_affine) + + return img_affine +end diff --git a/server/lib/tfl_utility.lua b/server/lib/tfl_utility.lua index 1eac2a1..e9032ba 100644 --- a/server/lib/tfl_utility.lua +++ b/server/lib/tfl_utility.lua @@ -194,24 +194,97 @@ function GenerateAnchors(options) end function show_pose(landmarks,image) - proteo.opencv.line(image,(landmarks[12].x),(landmarks[12].y),(landmarks[13].x),(landmarks[13].y),16,'#cc33cc') - proteo.opencv.line(image,(landmarks[12].x),(landmarks[12].y),(landmarks[14].x),(landmarks[14].y),16,'#993399') - proteo.opencv.line(image,(landmarks[13].x),(landmarks[13].y),(landmarks[15].x),(landmarks[15].y),16,'#993399') - proteo.opencv.line(image,(landmarks[14].x),(landmarks[14].y),(landmarks[16].x),(landmarks[16].y),16,'#cc33cc') - proteo.opencv.line(image,(landmarks[15].x),(landmarks[15].y),(landmarks[17].x),(landmarks[17].y),16,'#cc33cc') - proteo.opencv.line(image,(landmarks[13].x),(landmarks[13].y),(landmarks[25].x),(landmarks[25].y),16,'#cc66cc') - proteo.opencv.line(image,(landmarks[12].x),(landmarks[12].y),(landmarks[24].x),(landmarks[24].y),16,'#cc66cc') - proteo.opencv.line(image,(landmarks[25].x),(landmarks[25].y),(landmarks[24].x),(landmarks[24].y),16,'#ff99ff') + + proteo.opencv.line(image,(landmarks[4].x),(landmarks[4].y),(landmarks[8].x),(landmarks[8].y),3,'#cc66cc') + proteo.opencv.line(image,(landmarks[3].x),(landmarks[3].y),(landmarks[4].x),(landmarks[4].y),3,'#cc66cc') + proteo.opencv.line(image,(landmarks[2].x),(landmarks[2].y),(landmarks[3].x),(landmarks[3].y),3,'#993399') + proteo.opencv.line(image,(landmarks[1].x),(landmarks[1].y),(landmarks[2].x),(landmarks[2].y),3,'#cc33cc') + proteo.opencv.line(image,(landmarks[1].x),(landmarks[1].y),(landmarks[5].x),(landmarks[5].y),3,'#cc33cc') + proteo.opencv.line(image,(landmarks[5].x),(landmarks[5].y),(landmarks[6].x),(landmarks[6].y),3,'#993399') + proteo.opencv.line(image,(landmarks[6].x),(landmarks[6].y),(landmarks[7].x),(landmarks[7].y),3,'#cc66cc') + proteo.opencv.line(image,(landmarks[7].x),(landmarks[7].y),(landmarks[9].x),(landmarks[9].y),3,'#cc66cc') + + + proteo.opencv.line(image,(landmarks[10].x),(landmarks[10].y),(landmarks[11].x),(landmarks[11].y),3,'#cc33cc') + + proteo.opencv.line(image,(landmarks[12].x),(landmarks[12].y),(landmarks[13].x),(landmarks[13].y),3,'#cc33cc') + proteo.opencv.line(image,(landmarks[12].x),(landmarks[12].y),(landmarks[14].x),(landmarks[14].y),3,'#993399') + proteo.opencv.line(image,(landmarks[13].x),(landmarks[13].y),(landmarks[15].x),(landmarks[15].y),3,'#993399') + proteo.opencv.line(image,(landmarks[14].x),(landmarks[14].y),(landmarks[16].x),(landmarks[16].y),3,'#cc33cc') + proteo.opencv.line(image,(landmarks[15].x),(landmarks[15].y),(landmarks[17].x),(landmarks[17].y),3,'#cc33cc') + proteo.opencv.line(image,(landmarks[16].x),(landmarks[16].y),(landmarks[18].x),(landmarks[18].y),3,'#cc66cc') + proteo.opencv.line(image,(landmarks[17].x),(landmarks[17].y),(landmarks[19].x),(landmarks[19].y),3,'#cc66cc') + proteo.opencv.line(image,(landmarks[20].x),(landmarks[20].y),(landmarks[18].x),(landmarks[18].y),3,'#cc66cc') + proteo.opencv.line(image,(landmarks[21].x),(landmarks[21].y),(landmarks[19].x),(landmarks[19].y),3,'#cc66cc') + proteo.opencv.line(image,(landmarks[20].x),(landmarks[20].y),(landmarks[16].x),(landmarks[16].y),3,'#cc66cc') + proteo.opencv.line(image,(landmarks[21].x),(landmarks[21].y),(landmarks[17].x),(landmarks[17].y),3,'#cc66cc') + proteo.opencv.line(image,(landmarks[22].x),(landmarks[22].y),(landmarks[16].x),(landmarks[16].y),3,'#cc66cc') + proteo.opencv.line(image,(landmarks[23].x),(landmarks[23].y),(landmarks[17].x),(landmarks[17].y),3,'#cc66cc') + + proteo.opencv.line(image,(landmarks[13].x),(landmarks[13].y),(landmarks[25].x),(landmarks[25].y),3,'#cc66cc') + proteo.opencv.line(image,(landmarks[12].x),(landmarks[12].y),(landmarks[24].x),(landmarks[24].y),3,'#cc66cc') + proteo.opencv.line(image,(landmarks[25].x),(landmarks[25].y),(landmarks[24].x),(landmarks[24].y),3,'#ff99ff') + + proteo.opencv.line(image,(landmarks[25].x),(landmarks[25].y),(landmarks[27].x),(landmarks[27].y),3,'#ff99ff') + proteo.opencv.line(image,(landmarks[26].x),(landmarks[26].y),(landmarks[24].x),(landmarks[24].y),3,'#ff99ff') + proteo.opencv.line(image,(landmarks[29].x),(landmarks[29].y),(landmarks[27].x),(landmarks[27].y),3,'#ff99ff') + proteo.opencv.line(image,(landmarks[26].x),(landmarks[26].y),(landmarks[28].x),(landmarks[28].y),3,'#ff99ff') + proteo.opencv.line(image,(landmarks[29].x),(landmarks[29].y),(landmarks[31].x),(landmarks[31].y),3,'#ff99ff') + proteo.opencv.line(image,(landmarks[32].x),(landmarks[32].y),(landmarks[28].x),(landmarks[28].y),3,'#ff99ff') + proteo.opencv.line(image,(landmarks[33].x),(landmarks[33].y),(landmarks[31].x),(landmarks[31].y),3,'#ff99ff') + proteo.opencv.line(image,(landmarks[32].x),(landmarks[32].y),(landmarks[30].x),(landmarks[30].y),3,'#ff99ff') + proteo.opencv.line(image,(landmarks[33].x),(landmarks[33].y),(landmarks[29].x),(landmarks[29].y),3,'#ff99ff') + proteo.opencv.line(image,(landmarks[28].x),(landmarks[28].y),(landmarks[30].x),(landmarks[30].y),3,'#ff99ff') end function show_facemesh(landmarks,image) + for i=1,#landmarks do + proteo.opencv.circle(image, landmarks[i].x, landmarks[i].y,1,"#00FF00") + end +end + +function show_hand(landmark,image) + + proteo.opencv.line(image,(landmarks[1].x),(landmarks[1].y),(landmarks[6].x),(landmarks[6].y),3,'#00AA00') + proteo.opencv.line(image,(landmarks[10].x),(landmarks[10].y),(landmarks[6].x),(landmarks[6].y),3,'#00AA00') + proteo.opencv.line(image,(landmarks[10].x),(landmarks[10].y),(landmarks[14].x),(landmarks[14].y),3,'#00AA00') + proteo.opencv.line(image,(landmarks[14].x),(landmarks[14].y),(landmarks[18].x),(landmarks[18].y),3,'#00AA00') + proteo.opencv.line(image,(landmarks[1].x),(landmarks[1].y),(landmarks[18].x),(landmarks[18].y),3,'#00AA00') + + proteo.opencv.line(image,(landmarks[6].x),(landmarks[6].y),(landmarks[7].x),(landmarks[7].y),3,'#00BB00') + proteo.opencv.line(image,(landmarks[7].x),(landmarks[7].y),(landmarks[8].x),(landmarks[8].y),3,'#00DD00') + proteo.opencv.line(image,(landmarks[8].x),(landmarks[8].y),(landmarks[9].x),(landmarks[9].y),3,'#00FF00') + + proteo.opencv.line(image,(landmarks[10].x),(landmarks[10].y),(landmarks[11].x),(landmarks[11].y),3,'#00BB00') + proteo.opencv.line(image,(landmarks[11].x),(landmarks[11].y),(landmarks[12].x),(landmarks[12].y),3,'#00DD00') + proteo.opencv.line(image,(landmarks[12].x),(landmarks[12].y),(landmarks[13].x),(landmarks[13].y),3,'#00FF00') + + proteo.opencv.line(image,(landmarks[14].x),(landmarks[14].y),(landmarks[15].x),(landmarks[15].y),3,'#00BB00') + proteo.opencv.line(image,(landmarks[15].x),(landmarks[15].y),(landmarks[16].x),(landmarks[16].y),3,'#00DD00') + proteo.opencv.line(image,(landmarks[16].x),(landmarks[16].y),(landmarks[17].x),(landmarks[17].y),3,'#00FF00') + + proteo.opencv.line(image,(landmarks[18].x),(landmarks[18].y),(landmarks[19].x),(landmarks[19].y),3,'#00BB00') + proteo.opencv.line(image,(landmarks[19].x),(landmarks[19].y),(landmarks[20].x),(landmarks[20].y),3,'#00DD00') + proteo.opencv.line(image,(landmarks[20].x),(landmarks[20].y),(landmarks[21].x),(landmarks[21].y),3,'#00FF00') + + proteo.opencv.line(image,(landmarks[1].x),(landmarks[1].y),(landmarks[2].x),(landmarks[2].y),3,'#00BB00') + proteo.opencv.line(image,(landmarks[2].x),(landmarks[2].y),(landmarks[3].x),(landmarks[3].y),3,'#00CC00') + proteo.opencv.line(image,(landmarks[3].x),(landmarks[3].y),(landmarks[4].x),(landmarks[4].y),3,'#00DD00') + proteo.opencv.line(image,(landmarks[4].x),(landmarks[4].y),(landmarks[5].x),(landmarks[5].y),3,'#00FF00') end function show_landmark(bbox,image,landmarks) local size=proteo.opencv.size(image) - + --print("Size W:"..size[2].." H:"..size[1]) + + --print("Roi1 X:"..bbox.roi_coord[1].x.." Y:"..bbox.roi_coord[1].y) + --print("Roi2 X:"..bbox.roi_coord[2].x.." Y:"..bbox.roi_coord[2].y) + --print("Roi3 X:"..bbox.roi_coord[3].x.." Y:"..bbox.roi_coord[3].y) + + --print("Landmark1 X:"..landmarks.joint[1].x.." Y:"..landmarks.joint[1].y) + proteo.opencv.rectangle(image,bbox.topleft.x*size[2],bbox.topleft.y*size[1], bbox.btmright.x*size[2],bbox.btmright.y*size[1], 3,"#FF0000") @@ -225,7 +298,9 @@ function show_landmark(bbox,image,landmarks) proteo.opencv.line(image,bbox.roi_coord[4].x*size[2],bbox.roi_coord[4].y*size[1],bbox.roi_coord[1].x*size[2],bbox.roi_coord[1].y*size[1],1,"#FFFF00") proteo.opencv.rectangle(image,bbox.topleft.x*size[2],bbox.topleft.y*size[1],bbox.btmright.x*size[2],bbox.btmright.y*size[1],1,"#FF0000") - + + + for j=1,#bbox.keys do proteo.opencv.circle(image, bbox.keys[j].x*size[2], bbox.keys[j].y*size[1], 2,"#0000FF") end @@ -240,26 +315,23 @@ function show_landmark(bbox,image,landmarks) ) if landmarks~=nil then --proteo.opencv.print(mat) - mat_table=proteo.opencv.toTable(mat) + local mat_table=proteo.opencv.toTable(mat) --tprint(mat_table) - ret={} + local ret={} for j=1,#landmarks.joint do ret[j]={} ret[j].x=landmarks.joint[j].x*mat_table[1][1]+landmarks.joint[j].y*mat_table[1][2]+mat_table[1][3] ret[j].y=landmarks.joint[j].x*mat_table[2][1]+landmarks.joint[j].y*mat_table[2][2]+mat_table[2][3] ret[j].z=landmarks.joint[j].z - if j==8 or j==9 or j==250 then + --if j==8 or j==9 or j==250 then --proteo.opencv.circle(image, ret[j].x, ret[j].y,8,"#0000FF") - id=string.format("%d",j) - proteo.opencv.putText(image,id,ret[j].x, ret[j].y,0.5,"#FF0000") - --elseif j>=249 and j<=255 then - -- id=string.format("%d",j) - -- proteo.opencv.putText(image,id,ret[j].x, ret[j].y,0.5,"#0000FF") - else - proteo.opencv.circle(image, ret[j].x, ret[j].y,2,"#00FF00") - end + -- id=string.format("%d",j) + -- proteo.opencv.putText(image,id,ret[j].x, ret[j].y,0.5,"#FF0000") + --else + proteo.opencv.circle(image, ret[j].x, ret[j].y,1,"#00FF00") + --end end return ret @@ -271,6 +343,13 @@ end function get_landmark(bbox,image,landmarks) local size=proteo.opencv.size(image) + --print("Size W:"..size[2].." H:"..size[1]) + + --print("Roi1 X:"..bbox.roi_coord[1].x.." Y:"..bbox.roi_coord[1].y) + --print("Roi2 X:"..bbox.roi_coord[2].x.." Y:"..bbox.roi_coord[2].y) + --print("Roi3 X:"..bbox.roi_coord[3].x.." Y:"..bbox.roi_coord[3].y) + + --print("Landmark1 X:"..landmarks.joint[1].x.." Y:"..landmarks.joint[1].y) --LANDMARK local mat=proteo.opencv.getAffineTransform(0,0 @@ -282,10 +361,10 @@ function get_landmark(bbox,image,landmarks) ) if landmarks~=nil then --proteo.opencv.print(mat) - mat_table=proteo.opencv.toTable(mat) + local mat_table=proteo.opencv.toTable(mat) --tprint(mat_table) - ret={} + local ret={} for j=1,#landmarks.joint do ret[j]={} ret[j].x=landmarks.joint[j].x*mat_table[1][1]+landmarks.joint[j].y*mat_table[1][2]+mat_table[1][3] @@ -297,4 +376,19 @@ function get_landmark(bbox,image,landmarks) end return nil -end \ No newline at end of file +end + +--[[function tprint (tbl, indent) + if not indent then indent = 0 end + for k, v in pairs(tbl) do + formatting = string.rep(" ", indent) .. k .. ": " + if type(v) == "table" then + print(formatting) + tprint(v, indent+1) + elseif type(v) == 'boolean' then + print(formatting .. tostring(v)) + else + print(formatting .. v) + end + end +end]]-- diff --git a/server/plugin/admin.lua b/server/plugin/admin.lua index d82a136..91669de 100644 --- a/server/plugin/admin.lua +++ b/server/plugin/admin.lua @@ -67,8 +67,11 @@ proteo.route.get("admin/config", --local conf=proteo.system.readFile(BASEDIR.."config.json") --TODO attenzione, se dentro il config "originale" il basedir punta altrove questo readfile non lo trova - --TODO forse si popssono aggiungere anche i file nella cartella plugin in modo da poter vedere quali sono attivi e quali no - local conf=proteo.system.readFile("./config.json") + --TODO forse si possono aggiungere anche i file nella cartella plugin in modo da poter vedere quali sono attivi e quali no + + local conf=proteo.system.readFile(CONFIG_PATH) + + --TODO non è possibile inviare il file di configurazione integrale, si devono togliere almeno le key return conf end diff --git a/server/plugin/deepcrimson.lua b/server/plugin/deepcrimson.lua index 23fe813..7caa53b 100644 --- a/server/plugin/deepcrimson.lua +++ b/server/plugin/deepcrimson.lua @@ -3,6 +3,7 @@ local json=require "json" require "tfl_blazepose" require "tfl_blazeface" +require "tfl_hand" require "tfl_emotion" local deepcrimson_data={} @@ -12,6 +13,9 @@ deepcrimson_data.zmq_context=nil deepcrimson_data.sessions={} +--t_profile=0 +--last_profile=0 + deepcrimson_data.pipe = function (json_data) data = json.decode(json_data) @@ -56,6 +60,7 @@ deepcrimson_data.pipe = function (json_data) ret["size"]=size elseif data["request"]=="TFLPOSE" then + bbox = invoke_pose_detect(deepcrimson_data.sessions[session].frame) size = proteo.opencv.size(deepcrimson_data.sessions[session].frame) for i=1,#bbox do @@ -69,17 +74,120 @@ deepcrimson_data.pipe = function (json_data) ret['request']='TFLPOSE' ret['data']=bbox ret['size']=size - + elseif data["request"]=="TFLHAND" then + + bbox = invoke_hand_detect(deepcrimson_data.sessions[session].frame) + size = proteo.opencv.size(deepcrimson_data.sessions[session].frame) + for i=1,#bbox do + feed_image = generate_hand_landmark_input_image(deepcrimson_data.sessions[session].frame,bbox[i]) + bbox[i].landmarks=invoke_hand_landmark(feed_image) + end + + deepcrimson_data.sessions[session].bbox=bbox + + ret['type']='BBOX' + ret['request']='TFLHAND' + ret['data']=bbox + ret['size']=size + elseif data["request"]=="TFLHOLI" then + bbox = invoke_pose_detect(deepcrimson_data.sessions[session].frame) + face_bbox={} + for i=1,#bbox do + feed_image = generate_pose_landmark_input_image(deepcrimson_data.sessions[session].frame,bbox[i]) + bbox[i].landmarks=invoke_pose_landmark(feed_image) + + --Due possibilità: + + --Estraiamo un Roi per la faccia e lo facciamo analizzare al face_detect per ottimizzarlo prima di passarlo al face_landmark + --face_frame=face_roi(deepcrimson_data.sessions[session].frame,bbox[i].landmarks) + --bbox = invoke_face_detect (face_frame) + + --Generiamo direttamente un roi ottimizzato da passare al face_landmark + pose_landmarks = get_landmark(bbox[i],deepcrimson_data.sessions[session].frame,bbox[i].landmarks) + --print("Center X:"..pose_landmarks[1].x.." Y:"..pose_landmarks[1].y) + face_bbox[i]=generate_face_bbox_from_pose(pose_landmarks,proteo.opencv.size(deepcrimson_data.sessions[session].frame)) + feed_image=generate_face_landmark_input_image (deepcrimson_data.sessions[session].frame, face_bbox[i]) + face_bbox[i].landmarks=invoke_face_landmark (feed_image) + end + + deepcrimson_data.sessions[session].bbox=bbox + + ret['type']='BBOX' + ret['request']='TFLHOLI' + ret['data']=bbox + ret['face']=face_bbox + ret['size']=size end + + --ret['nframe']=data['nframe'] return json.encode(ret) end +function face_roi(frame,pose_landmarks) + +end + +function generate_face_bbox_from_pose(pose_landmarks,size) + + local x_center = pose_landmarks[1].x/size[2] + local y_center = pose_landmarks[1].y/size[1] + + local x_lefteye = pose_landmarks[3].x/size[2] + local y_lefteye = pose_landmarks[3].y/size[1] + local x_righteye = pose_landmarks[6].x/size[2] + local y_righteye = pose_landmarks[6].y/size[1] + + local roi_size = math.sqrt((x_lefteye - x_righteye) * (x_lefteye - x_righteye) + (y_lefteye - y_righteye) * (y_lefteye - y_righteye)) + local ret={} + + ret.score=0 + + ret.topleft={x=x_center-roi_size/2,y=y_center-roi_size/2} + ret.btmright={x=x_center+roi_size/2,y=y_center+roi_size/2} + + ret.keys={} + ret.keys[1]={x=x_center,y=y_center} + ret.keys[2]={x=x_lefteye,y=y_lefteye} + ret.keys[3]={x=x_righteye,y=y_righteye} + + compute_rotation(ret,3,2) + ret.rotation=ret.rotation - math.pi * 0.5 + + local roi_scale = 4.0 + + local dx = roi_size * roi_scale * 0.5 + local dy = roi_size * roi_scale * 0.5 + ret.roi_coord = {} + ret.roi_coord[1] = {x= - dx, y= - dy} + ret.roi_coord[2] = {x= dx, y= - dy} + ret.roi_coord[3] = {x= dx, y= dy} + ret.roi_coord[4] = {x= - dx, y= dy} + + for i = 1,4 do + rot_vec (ret.roi_coord[i], ret.rotation) + ret.roi_coord[i].x = ret.roi_coord[i].x + x_center + ret.roi_coord[i].y = ret.roi_coord[i].y + y_center + + ret.roi_coord[i].x = ret.roi_coord[i].x + ret.roi_coord[i].y = ret.roi_coord[i].y + end + + return ret +end + deepcrimson_data.update= function(dt) if deepcrimson_data.zmq_socket ~= nil then buffer = proteo.zmq.recv(deepcrimson_data.zmq_socket,proteo.zmq.flag.ZMQ_DONTWAIT) if buffer ~= nil then - proteo.zmq.send (deepcrimson_data.zmq_socket,deepcrimson_data.pipe(buffer),proteo.zmq.flag.ZMQ_DONTWAIT) + + -- last_profile=proteo.system.clock() + + proteo.zmq.send (deepcrimson_data.zmq_socket,deepcrimson_data.pipe(buffer),proteo.zmq.flag.ZMQ_DONTWAIT) + + -- t_profile=proteo.system.clock()-last_profile + -- print(t_profile) + end end end @@ -128,6 +236,9 @@ proteo.route.get("deepcrimson/permissions", proteo.route.post("deepcrimson/stop", function(username,permission,data,param) + + --TODO chiude la sessione, se non ce ne sono più attive interrompe il timer + proteo.system.stopTimer(deepcrimson_data.timer) if deepcrimson_data.zmq_socket~=nil then proteo.zmq.socket_close(deepcrimson_data.zmq_socket) diff --git a/server/plugin/proteo.lua b/server/plugin/proteo.lua index 4ff8aeb..7308d65 100644 --- a/server/plugin/proteo.lua +++ b/server/plugin/proteo.lua @@ -16,11 +16,15 @@ libs["json"]="lib/json.lua" libs["room"]="lib/room.lua" libs["md5"]="lib/md5.lua" libs["bit"]="lib/numberlua.lua" +--libs["bit32"]="lib/numberlua.lua" libs["matrix"]="lib/matrix.lua" libs["base64"]="lib/base64.lua" libs["aeslua"]="lib/aeslua.lua" libs["inspect"]="lib/inspect.lua" libs["tfl_utility"]="lib/tfl_utility.lua" +libs["tfl_blazepose"]="lib/tfl_blazepose.lua" +libs["tfl_blazeface"]="lib/tfl_blazeface.lua" +libs["tfl_hand"]="lib/tfl_hand.lua" libs["skl_utility"]="lib/skl_utility.lua" libs["demo_lib"]="lib/demo_lib.lua" @@ -90,6 +94,27 @@ proteo.route.get("proteo/scriptandlibs/:script", --print("GET SCRIPT PERMISSION: "..permission) + if username=="demo" then --TODO può diventare l'opzione di default cercare lo script ANCHE nella cartella del proprio utente + --potrebbe essere un modo per testare gli script prima di rilasciarli nella cartella comune + script={} + script["type"]="SCRIPT" + script["result"]="OK" + data=proteo.system.readFile(BASEDIR.."script/"..username.."/"..param["script"]..".lua") + script["script"]=data + script["libs"]={} + + local script_info=json.decode(proteo.system.readFile(BASEDIR.."script/"..username.."/"..param["script"]..".json")) + + if script_info["libs"]~=nil then + for i=1,#script_info["libs"] do + local lib_name=script_info["libs"][i] + script["libs"][lib_name]=proteo.system.readFile(BASEDIR..libs[lib_name]) + end + end + + return json.encode(script) + end + local permitted=false for i=1,#permission do print("PERMISSION: "..permission[i]) @@ -147,7 +172,7 @@ proteo.route.get("proteo/script/:script", script={} script["type"]="SCRIPT" script["result"]="OK" - data=proteo.system.readFile(BASEDIR.."script/demo/"..param["script"]..".lua") + data=proteo.system.readFile(BASEDIR.."script/"..username.."/"..param["script"]..".lua") script["script"]=data return json.encode(script) diff --git a/server/proteo.service b/server/proteo.service index e7048fd..4d7153b 100644 --- a/server/proteo.service +++ b/server/proteo.service @@ -7,7 +7,7 @@ StartLimitIntervalSec=0 Type=simple Restart=always RestartSec=1 -ExecStart=/usr/local/bin/proteo_server -d -c /usr/local/etc/proteo/config.json +ExecStart=/usr/local/bin/proteo_server -d -c /usr/local/etc/Proteo/config.json [Install] WantedBy=multi-user.target diff --git a/server/proteo_auth.c b/server/proteo_auth.c index 1fa95f5..ceb45f6 100644 --- a/server/proteo_auth.c +++ b/server/proteo_auth.c @@ -1,7 +1,4 @@ -unsigned char *serverkey = (unsigned char *)"01234567890123456789012345678901"; //TODO va nel config -unsigned char *clientkey = (unsigned char *)"1234567890123456789012"; //TODO va nel config - struct connection_info_struct { int type; @@ -36,7 +33,7 @@ int aes_encrypt(const unsigned char *plaintext, int plaintext_len, unsigned char if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors(); - if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, serverkey, iv)) + if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, config.server_key, iv)) handleErrors(); @@ -73,7 +70,7 @@ int aes_decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *ke if(!(ctx = EVP_CIPHER_CTX_new())) handleErrors(); - if(1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, serverkey, iv)) + if(1 != EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, config.server_key, iv)) handleErrors(); if(1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len)) @@ -212,7 +209,7 @@ int createTokenAndTicket(const char* username,const char* scriptId, char* token, if(debug) printf("Create Token: %s\n",json_token); unsigned char ciphertext[512]; - int ciphertext_len = aes_encrypt ((const unsigned char *)json_token, strlen (json_token), serverkey, iv, ciphertext); + int ciphertext_len = aes_encrypt ((const unsigned char *)json_token, strlen (json_token), config.server_key, iv, ciphertext); strcpy(ciphertext+ciphertext_len, "::"); strcpy(ciphertext+ciphertext_len+2,iv); ciphertext_len+=18; @@ -265,7 +262,7 @@ int verifyToken(char* username,char* permissions,const char* app,const char* tok //printf("OUT %d-%d: %s\n",len,strlen(json),json); //printf("IV: %s\n",iv); - int decryptedtext_len = aes_decrypt(tmp,len-18, serverkey, iv,(unsigned char*)decryptedtext); + int decryptedtext_len = aes_decrypt(tmp,len-18, config.server_key, iv,(unsigned char*)decryptedtext); free(tmp); //unsigned char *iv=tmp+len-16; diff --git a/server/proteo_config.c b/server/proteo_config.c index 3ad5bb9..eb61fe0 100644 --- a/server/proteo_config.c +++ b/server/proteo_config.c @@ -16,7 +16,7 @@ struct server struct conf { char version[10]; - char local[64]; + //char local[64]; char basedir[256]; char baseurl[64]; int port; @@ -29,6 +29,8 @@ struct conf int ssl; char ssl_key[64]; char ssl_cert[64]; + char server_key[33]; + char client_key[33]; } conf; @@ -47,15 +49,17 @@ int load_config(char *path_config) } fprintf(f, "{" "\"version\":\"0.1\"," - "\"local\":\"http://localhost:8888\"," + //"\"local\":\"http://localhost:8888\"," "\"master\":1," "\"basedir\":\"%s/\"," "\"baseurl\":\"localhost\"," "\"port\":8888," "\"ssl\":0," + "\"server_key\":\"01234567890123456789012345678901\"," + "\"client_key\":\"01234567890123456789012345678901\"," "\"admin_enabled\":1," "\"plugins\":[\"proteo\",\"admin\"]," - "\"servers\":[\"http://remote.server.com:8888\"]" + "\"servers\":[\"http://remote.server:8888\"]" "}",dirname(path_config)); fclose(f); } @@ -75,9 +79,9 @@ int load_config(char *path_config) const char* ver=json_object_get_string(obj); strcpy(config.version,ver); - json_object_object_get_ex(jobj, "local", &obj); - const char* lcl=json_object_get_string(obj); - strcpy(config.local,lcl); + //json_object_object_get_ex(jobj, "local", &obj); + //const char* lcl=json_object_get_string(obj); + //strcpy(config.local,lcl); json_object_object_get_ex(jobj, "basedir", &obj); const char* basedir=json_object_get_string(obj); @@ -87,6 +91,14 @@ int load_config(char *path_config) const char* baseurl=json_object_get_string(obj); if(baseurl!=NULL) strcpy(config.baseurl,baseurl); + json_object_object_get_ex(jobj, "server_key", &obj); + const char* server_key=json_object_get_string(obj); + if(server_key!=NULL) strcpy(config.server_key,server_key); + + json_object_object_get_ex(jobj, "client_key", &obj); + const char* client_key=json_object_get_string(obj); + if(client_key!=NULL) strcpy(config.client_key,client_key); + json_object_object_get_ex(jobj, "port", &obj); config.port=json_object_get_int(obj); diff --git a/server/proteo_info.c b/server/proteo_info.c index addc546..59a28ad 100644 --- a/server/proteo_info.c +++ b/server/proteo_info.c @@ -5,20 +5,66 @@ struct MemoryStruct { int addTicket(const char* app,const char* url,int value) { - //TODO - //Lua script + lua_getglobal(L,"ticket_add"); + lua_pushlstring(L,app,strlen(app)); + lua_pushlstring(L,url,strlen(url)); + lua_pushinteger(L, value); +#ifdef DEBUGGER + int error = dbg_pcall(L,3,1,0); +#else + int error = lua_trace_pcall(L,3,1);//lua_pcall(L, 1, 0, 0); +#endif + + if (error) { + printf("ERROR pcall(ticket_add): %s\n", lua_tostring(L, -1)); + //lua_pop(L, 1); + if(verbose) printf("Add ticket GetTop %d\n",lua_gettop(L)); + return 1; + + } + + return 0; //IF SQLITE - return sqlite_addTicket(app,url,value); + //return sqlite_addTicket(app,url,value); } int getTicket(const char* app,char** url) { - //TODO - //Lua script + lua_getglobal(L,"ticket_get"); + lua_pushlstring(L,app,strlen(app)); + //int error = lua_trace_pcall(L, 6, 1); +#ifdef DEBUGGER + int error = dbg_pcall(L,1,1,0); +#else + int error = lua_trace_pcall(L,1,1);//lua_pcall(L, 1, 0, 0); +#endif + + if (error) { + printf("ERROR pcall(ticket_get): %s\n", lua_tostring(L, -1)); + //lua_pop(L, 1); + if(verbose) printf("Get ticket GetTop %d\n",lua_gettop(L)); + return 1; + + } + + const char* ret=NULL; + int iType = lua_type(L, -1); + switch (iType) + { + case LUA_TSTRING: + ret = lua_tostring(L, -1);//Oppure 1? + lua_pop(L, 1); + *url=malloc(strlen(ret)+1); + strcpy(*url,ret); + break; + default: + printf("WHAT?!?!?!\n"); + } + return 0; //IF SQLITE - return sqlite_getTicket(app,url); + //return sqlite_getTicket(app,url); } struct MHD_Response * proteo_info() @@ -135,8 +181,20 @@ void get_info(char* url) void get_server_info() { char path[100]; - strcpy(path,config.local); - strcat(path,"/info"); + /*if(config.ssl) + strcpy(path,"https://"); + else + strcpy(path,"http://"); + strcat(path,config.baseurl); + strcat(path,":"); + strcat(path,config.port); + strcat(path,"/info");*/ + + //snprintf(path,sizeof(path)-1,"%s%s:%d/info",config.ssl?"https://":"http://",config.baseurl,config.port); + + //With some urls it may not work, so it's better to set always localhost + snprintf(path,sizeof(path)-1,"%slocalhost:%d/info",config.ssl?"https://":"http://",config.port); + if(verbose) printf("get_info: %s\n",path); get_info(path); @@ -149,3 +207,22 @@ void get_server_info() get_info(path); } } + +static int info_updateTickets(lua_State *state) { + + const char* url = luaL_checkstring(state,1); + if(strcmp(url, config.baseurl)!=0) + { + //TODO + //Non può invocare se stesso perchè si blocca, bisogna procedere in altro modo + + return 0; + } + char path[100]; + strcpy(path,url); + strcat(path,"/info"); + + get_info(path); + + return 0; +} diff --git a/server/proteo_lua.c b/server/proteo_lua.c index 04ce020..34462e8 100644 --- a/server/proteo_lua.c +++ b/server/proteo_lua.c @@ -35,6 +35,7 @@ static int traceback(lua_State *state) { } sem_t* lua_sem; + int lua_trace_pcall( lua_State* state, int nargs, int nret ) { //sem_wait(lua_sem); @@ -47,6 +48,7 @@ int lua_trace_pcall( lua_State* state, int nargs, int nret ) { ret = lua_pcall( state, nargs, nret, hpos ); + lua_remove( state, hpos ); //sem_post(lua_sem); @@ -81,5 +83,5 @@ void init(lua_State *state,const char* app) //chiamato da initLUA void closeLUA() { lua_close(L); - sem_close(lua_sem); + if(lua_sem!=SEM_FAILED) sem_close(lua_sem); } diff --git a/server/proteo_network.c b/server/proteo_network.c index ba96bd4..6c0235e 100644 --- a/server/proteo_network.c +++ b/server/proteo_network.c @@ -317,7 +317,7 @@ static int network_get(lua_State *state) { const char* token = luaL_checkstring(state,2); const char* callback = luaL_checkstring(state,3); - server_get(url,(const char*)clientkey,token,callback); + server_get(url,(const char*)config.client_key,token,callback); return 0; } @@ -333,7 +333,7 @@ static int network_post(lua_State *state) { const char* token = luaL_checkstring(state,3); const char* callback = luaL_checkstring(state,4); - server_post(url,(const char*)clientkey,token,json,callback); + server_post(url,(const char*)config.client_key,token,json,callback); free((void*)json); diff --git a/server/proteo_opencv.cpp b/server/proteo_opencv.cpp index 66f7946..2bb8027 100644 --- a/server/proteo_opencv.cpp +++ b/server/proteo_opencv.cpp @@ -2,21 +2,36 @@ //#ifdef PROTEO_OPENCV //#ifdef __cplusplus + +#include #include -#include +/*#include #include +#include #include +#include +#include */ #include #define OPENCVMAT "OpenCVMat" #define OPENCVVC "OpenCVVideoCapture" -#define OPENCVNET "OpenCVNet" #define OPENCVVW "OpenCVVideoWriter" +#if OPENCV_DNN +//CV_VERSION_MAJOR >= 4 +#define OPENCVNET "OpenCVNet" +#endif + +#ifndef CV_16F +#define CV_16F 7 +#endif + using namespace std; using namespace cv; +#ifdef OPENCVNET using namespace cv::dnn; -//using namespace cv::cuda; +using namespace cv::cuda; +#endif extern "C" { //#endif @@ -87,6 +102,7 @@ static VideoCapture *checkCap (lua_State *L, int index) return cap; } +#ifdef OPENCVNET static Net *checkNet (lua_State *L, int index) { Net *net; @@ -95,6 +111,7 @@ static Net *checkNet (lua_State *L, int index) if (net == NULL) luaL_typerror(L, index, OPENCVNET); return net; } +#endif static VideoWriter *checkWriter (lua_State *L, int index) { @@ -135,6 +152,7 @@ static int vc_gc(lua_State *l) { return 0; } +#ifdef OPENCVNET static int net_gc(lua_State *l) { Net* net = checkNet(l, 1); @@ -147,6 +165,7 @@ static int net_gc(lua_State *l) { return 0; } +#endif static int vw_gc(lua_State *l) { @@ -208,7 +227,7 @@ static UMat * pushMat (lua_State *state) }*/ - +#ifdef OPENCVNET static Net *pushNet (lua_State *state) { Net *net = new (lua_newuserdata(state, sizeof(Net))) Net(); @@ -229,6 +248,7 @@ static Net *pushNet (lua_State *state) return net; } +#endif static VideoWriter *pushWriter (lua_State *state) { @@ -425,7 +445,12 @@ int opencv_write(lua_State* state) //UMat *ret=pushMat(state); VideoWriter *vw=checkWriter(state,1); UMat *ret=checkMat(state,2); - if(vw!=NULL) vw->write(*ret); + if(vw!=NULL) + #ifdef OPENCVNET + vw->write(*ret); + #else + vw->write(ret->getMat(ACCESS_READ)); + #endif // check if we succeeded int success=1; if (ret->empty()) { @@ -704,6 +729,7 @@ int opencv_print(lua_State* state) } +#ifdef OPENCVNET int opencv_readnet(lua_State* state) { const char* model=luaL_checkstring(state,1); @@ -715,7 +741,9 @@ int opencv_readnet(lua_State* state) return 1; } +#endif +#ifdef OPENCVNET int opencv_forward(lua_State* state) { Net* net=checkNet(state,1); @@ -755,7 +783,9 @@ int opencv_forward(lua_State* state) return 0; } +#endif +#ifdef OPENCVNET int opencv_forwardTable(lua_State* state) { Net* net=checkNet(state,1); @@ -832,6 +862,7 @@ int opencv_forwardTable(lua_State* state) return 0; } +#endif int opencv_sliceImg(lua_State* state) { @@ -1077,6 +1108,8 @@ int opencv_infoImg(lua_State* state) return 0; } + +#ifdef OPENCVNET int opencv_infoNet(lua_State* state) { Net * net = (Net *)luaL_checkudata(state, 1, OPENCVNET); @@ -1098,6 +1131,7 @@ int opencv_infoNet(lua_State* state) return 0; } +#endif int opencv_size(lua_State* state) { @@ -1169,7 +1203,19 @@ int opencv_totable(lua_State* state) lua_newtable(state); for (int c = 0; c < mat.cols; c++) { lua_pushinteger(state, c+1); - lua_pushnumber(state,mat.at(r, c)); + float value; + + switch (mat.depth()) + { + case CV_8U: value = mat.at(r, c); break; + case CV_8S: value = mat.at(r, c); break; + case CV_16U: value = mat.at(r, c); break; + case CV_16S: value = mat.at(r, c); break; + case CV_32S: value = mat.at(r, c); break; + case CV_32F: value = mat.at(r, c); break; + case CV_64F: value = mat.at(r, c); break; + } + lua_pushnumber(state,value); lua_settable(state,-3); } lua_settable(state,-3); diff --git a/server/proteo_server.c b/server/proteo_server.c index 31636e5..2f247d9 100644 --- a/server/proteo_server.c +++ b/server/proteo_server.c @@ -1,15 +1,19 @@ //============================================================================== -//=> Proteo Server v0.0.1 +//=> Proteo Server v0.2 //=> //=> CC BY-NC-SA 3.0 //=> //=> Massimo Bernava //=> massimo.bernava@gmail.com -//=> 2021-05-13 +//=> 2021-06-15 //============================================================================== +//#define EJDB2 //CMAKE +//#define DEEPSPEECH //CMAKE +//#define TFLITE //CMAKE + #define PROTEO_OPENCV -#define DEBUGGER +//#define DEBUGGER #include "proteo_server.h" #include "proteo_b64.c" @@ -22,7 +26,9 @@ #include "proteo_auth.c" #include "proteo_sqlite.c" +#ifdef EJDB2 #include "proteo_ejdb.c" +#endif #include "proteo_system.c" #include "proteo_info.c" #include "proteo_network.c" @@ -30,7 +36,9 @@ #include "proteo_admin.c" #include "proteo_zmq.c" #include "proteo_ffmpeg.c" +#ifdef TFLITE #include "proteo_tensorflow.c" +#endif //============================================================================== @@ -382,10 +390,10 @@ LUALIB_API int luaopen_proteo (lua_State *state) { lua_newtable(state); lua_setfield(state, -2, "opencv"); - +#ifdef EJDB2 lua_newtable(state); lua_setfield(state, -2, "ejdb"); - +#endif lua_newtable(state); lua_setfield(state, -2, "ffmpeg"); @@ -397,7 +405,9 @@ LUALIB_API int luaopen_proteo (lua_State *state) { add_system_proteo(state); add_zmq_proteo(state); add_ffmpeg_proteo(state); +#ifdef TFLITE add_tensorflow_proteo(state); +#endif return 1; } @@ -436,8 +446,14 @@ void addEnum_proteo(lua_State *state,const char *lib,const char *enumname,const int initLUA() { //sem_init(&lua_mutex,0,1); - sem_unlink("/lua_call_sem"); - lua_sem = sem_open ("/lua_call_sem", O_CREAT , 0644, 1);//| O_EXCL + char sem_name[10]; + + rand_string(sem_name, 10); + sem_name[0]="/"; + //printf("sem name: %s",sem_name); + //if the proteo crash it could remain a suspended semaphore and deny permission to open it. In this way a different semaphore is created each time. + sem_unlink(sem_name); + lua_sem = sem_open (sem_name, O_CREAT , 0666,1);//0666, 1);//| O_EXCL if(lua_sem==SEM_FAILED) { printf("Sem_open: Failed: %s!\n",strerror(errno)); @@ -467,9 +483,12 @@ int initLUA() addFunction_proteo(L,"opencv","videowriter",opencv_videowriter); addFunction_proteo(L,"opencv","write",opencv_write); addFunction_proteo(L,"opencv","frame",opencv_frame); +#ifdef OPENCV_DNN addFunction_proteo(L,"opencv","readnet",opencv_readnet); addFunction_proteo(L,"opencv","forward",opencv_forward); addFunction_proteo(L,"opencv","forwardTable",opencv_forwardTable); + addFunction_proteo(L,"opencv","infoNet",opencv_infoNet); +#endif //addFunction_proteo(L,"opencv","getpoints",opencv_getpoints); addFunction_proteo(L,"opencv","circle",opencv_circle); addFunction_proteo(L,"opencv","rectangle",opencv_rectangle); @@ -481,7 +500,7 @@ int initLUA() addFunction_proteo(L,"opencv","size",opencv_size); addFunction_proteo(L,"opencv","cropImg",opencv_cropImg); addFunction_proteo(L,"opencv","infoImg",opencv_infoImg); - addFunction_proteo(L,"opencv","infoNet",opencv_infoNet); + addFunction_proteo(L,"opencv","setImg",opencv_setImg); addFunction_proteo(L,"opencv","setSize",opencv_setSize); addFunction_proteo(L,"opencv","fill",opencv_fill); @@ -526,7 +545,7 @@ int initLUA() #endif addFunction_proteo(L,"sqlite","exe",sqlite_exe); - +#ifdef EJDB2 addFunction_proteo(L,"ejdb","exe",ejdb_lua_exe); //addFunction_proteo(L,"ejdb","new",ejdb_lua_new); addFunction_proteo(L,"ejdb","del",ejdb_lua_del); @@ -534,7 +553,7 @@ int initLUA() addFunction_proteo(L,"ejdb","put",ejdb_lua_put); addFunction_proteo(L,"ejdb","merge",ejdb_lua_merge); addFunction_proteo(L,"ejdb","patch",ejdb_lua_patch); - +#endif //addFunction_proteo(L,"network","download",network_download); addFunction_proteo(L,"network","get",network_get); addFunction_proteo(L,"network","post",network_post); @@ -596,6 +615,12 @@ int initLUA() luaL_dofile(L,route_path); free(route_path); + char* ticket_path=concat(config.basedir,"ticket.lua"); + luaL_dofile(L,ticket_path); + free(ticket_path); + + addFunction_proteo(L,"system","updateTickets",info_updateTickets); + for (int i = 0; i < config.plugin_count; i++) { printf("Init Plug: %s\n",config.plugins[i].name); //init(plug_name); //proteo_lua.c @@ -607,7 +632,7 @@ int initLUA() const char* app_call(int type,const char* url,char* data,char* permissions,char* username,const char* token) { - sem_wait(lua_sem); + if(lua_sem!=SEM_FAILED) sem_wait(lua_sem); lua_getglobal(L,"route_call"); /*int type=0; if(0 == strcmp (method, "GET") ) type=GET; @@ -638,7 +663,7 @@ const char* app_call(int type,const char* url,char* data,char* permissions,char* printf("ERROR pcall(route.call): %s\n", lua_tostring(L, -1)); //lua_pop(L, 1); if(verbose) printf("App_call GetTop %d\n",lua_gettop(L)); - sem_post(lua_sem); + if(lua_sem!=SEM_FAILED) sem_post(lua_sem); return NULL; } @@ -666,7 +691,7 @@ const char* app_call(int type,const char* url,char* data,char* permissions,char* if(verbose) printf("App_call GetTop %d\n",top); //lua_pop(L, 1); - sem_post(lua_sem); + if(lua_sem!=SEM_FAILED) sem_post(lua_sem); if(paused && toreboot>=0) { @@ -794,6 +819,7 @@ struct MHD_Response* parse_info(struct connection_info_struct *con_info,const ch if (login_correct==1) { char* path=concat(config.basedir,"web/blockly/index.html"); + //char* path=concat(config.basedir,"web/ace/editor.html"); char *page=loadfile(path); free(path); @@ -893,7 +919,7 @@ struct MHD_Response* parse_info(struct connection_info_struct *con_info,const ch char permissions[512]; char username[100]; - if(verifyToken(username,permissions,app,token)==0 && verifyHMAC(con_info->url,con_info->data,token,clientkey,hmac)==0) + if(verifyToken(username,permissions,app,token)==0 && verifyHMAC(con_info->url,con_info->data,token,config.client_key,hmac)==0) { if(verbose) printf("Token and HMAC ok\n"); //luaL_dostring(L, "package.path = './lib/?.lua;' .. package.path"); @@ -1136,8 +1162,16 @@ int main(int argc,char **argv) { int c; char config_path[256]; + + //TODO andrebbe messo in una cartella standard sul server, indipendente da basedir +#ifdef __linux__ + //mkpath("/usr/local/etc/Proteo"); + //strcpy(config_path,"/usr/local/etc/Proteo/config.json"); + strcpy(config_path,"./config.json"); +#else strcpy(config_path,"./config.json"); - +#endif + while ((c = getopt (argc, argv, "vhdc:")) != -1) switch (c) { @@ -1195,13 +1229,16 @@ int main(int argc,char **argv) return 1; } + lua_pushlstring(L,config_path,strlen(config_path)); + lua_setglobal(L, "CONFIG_PATH"); +#ifdef EJDB2 iwrc rc = ejdb_init(); if (rc) { iwlog_ecode_error3(rc); printf( "Failed to initialize EJDB!\n" ); return 1; } - +#endif //pthread_t poll_event; if(config.master==1) @@ -1223,7 +1260,9 @@ int main(int argc,char **argv) printf("%s\n",LUA_VERSION); #endif printf("JSON v.%s\n",JSON_C_VERSION); +#ifdef TFLITE printf("TensorFlowLite v.%s\n", TfLiteVersion()); +#endif MHD_set_panic_func(&panicCallback, NULL); @@ -1233,7 +1272,7 @@ int main(int argc,char **argv) if(config.ssl==0) { - daemon = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD, 8888, + daemon = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD, config.port, NULL, NULL, &url_handler,NULL, MHD_OPTION_NOTIFY_COMPLETED, &request_completed, @@ -1253,7 +1292,7 @@ int main(int argc,char **argv) return 1; } - daemon = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_DEBUG | MHD_USE_SSL, 8888, + daemon = MHD_start_daemon (MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_DEBUG | MHD_USE_SSL, config.port, NULL, NULL, &url_handler,NULL, MHD_OPTION_NOTIFY_COMPLETED, &request_completed,NULL, @@ -1298,7 +1337,7 @@ int main(int argc,char **argv) } ProteoTimer* timer=timers; - double min=1000; + long min=1000; while(timer!=NULL) { if(timer->state==1) @@ -1308,7 +1347,7 @@ int main(int argc,char **argv) { if(paused) continue; - sem_wait(lua_sem); + if(lua_sem!=SEM_FAILED) sem_wait(lua_sem); if(timer->callback!=NULL) lua_getglobal(L,timer->callback); else if(timer->ref_callback!=-1) @@ -1333,11 +1372,11 @@ int main(int argc,char **argv) } } timer->last=n; - sem_post(lua_sem); + if(lua_sem!=SEM_FAILED) sem_post(lua_sem); } else { - double next=timer->time -(n-timer->last); + long next=timer->time -(n-timer->last); if(next #include //#include +#ifdef TFLITE #include +#endif + +#ifdef DEEPSPEECH +#include +#endif #include #include @@ -77,7 +83,10 @@ #define ENET_IMPLEMENTATION #define ENET_DEBUG #include "enet.h" + +#ifdef EJDB2 #include +#endif #include @@ -165,7 +174,7 @@ int paused; int toreboot=-1; int verbose=FALSE; int debug=FALSE; -char basedir[50]; +//char basedir[50]; #define PROTEOCOMPONENT "ProteoComponent" #define PROTEOTIMER "ProteoTimer" diff --git a/server/proteo_sqlite.c b/server/proteo_sqlite.c index 473e62b..27ffd2b 100644 --- a/server/proteo_sqlite.c +++ b/server/proteo_sqlite.c @@ -58,15 +58,15 @@ int sqlite_create_auth_user_db(const char* path) ");" "INSERT INTO `permissions` VALUES (1,1,'proteo','admin',1,CURRENT_TIMESTAMP);" - "INSERT INTO `permissions` VALUES (2,1,'admin','admin',1,CURRENT_TIMESTAMP);" + "INSERT INTO `permissions` VALUES (2,1,'admin','admin',1,CURRENT_TIMESTAMP);"; - "DROP TABLE IF EXISTS `tickets`;" + /*"DROP TABLE IF EXISTS `tickets`;" "CREATE TABLE `tickets` (" "`id_tick` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT," "`app` TEXT NOT NULL," "`url` TEXT NOT NULL," "`ticket` INTEGER NOT NULL," - "UNIQUE(app,url));"; + "UNIQUE(app,url));";*/ return sqlite_exec(path,sql); } @@ -303,7 +303,7 @@ static int sqlite_exe (lua_State *state) { //============================================= // TICKETS //============================================= -int sqlite_addTicket(const char* app,const char* url,int value) +/*int sqlite_addTicket(const char* app,const char* url,int value) { char sql[256]; @@ -417,7 +417,7 @@ int sqlite_getTicket(const char* app,char** url) return 1; } - +*/ //============================================= // AUTH //============================================= diff --git a/server/proteo_system.c b/server/proteo_system.c index ea952bd..907b4b9 100644 --- a/server/proteo_system.c +++ b/server/proteo_system.c @@ -44,7 +44,7 @@ static int system_fileexist(lua_State *state) { static int system_document(lua_State *state) { if(verbose) printf("system.document\n"); //lua_pushliteral(state,"./"); - lua_pushlstring(state,basedir,strlen(basedir)); + lua_pushlstring(state,config.basedir,strlen(config.basedir)); return 1; } @@ -186,6 +186,8 @@ static int system_createTimer(lua_State *state) { ProteoTimer* pt=pushProteoTimer(state); + printf("Create timer ms: %f\n",time); + pt->time=time; //pt->callback=callback; @@ -320,8 +322,8 @@ void sendMail(const char* to_mail, const char* from_mail, const char* cc_mail, c curl = curl_easy_init(); if(curl) { /* Set username and password */ - curl_easy_setopt(curl, CURLOPT_USERNAME, ""); - curl_easy_setopt(curl, CURLOPT_PASSWORD, ""); + curl_easy_setopt(curl, CURLOPT_USERNAME, "massimo.bernava@gmail.com"); + curl_easy_setopt(curl, CURLOPT_PASSWORD, "juzbjdkglpzhspnf"); /* This is the URL for your mailserver. Note the use of smtps:// rather * than smtp:// to request a SSL based connection. */ diff --git a/server/script/admin.lua b/server/script/admin.lua index 84f43ab..b739b0d 100644 --- a/server/script/admin.lua +++ b/server/script/admin.lua @@ -5,15 +5,20 @@ local json=require "json" -- delete checkbox -- password mode per i textbox -- avvisi per passord assende, sbagliata o user che non è una mail --- search +-- search textbox -- server REBOOT +-- REPOSITORY +-- A che serve PERMISSIONS? + + +admin={} --TODO una sola variabile globale form_users=nil -form_options=nil +--form_config=nil form_permissions=nil -option_button=nil +--option_button=nil users_button=nil permissions_button=nil @@ -52,10 +57,10 @@ function init() proteo.gui.setState(username_admin,proteo.gui.FormState.WindowBar) form_users=proteo.gui.newForm("form_users","Users",'Helvetica',20,"jet","crimson","blanchedalmond",30,proteo.gui.FormType.Fixed+proteo.gui.FormType.HideResize+proteo.gui.FormType.HideClose,"","",150,150,MAX_X-300,MAX_Y-300,"") - form_options=proteo.gui.newForm("form_options","Options",'Helvetica',20,"jet","crimson","blanchedalmond",30,proteo.gui.FormType.Fixed+proteo.gui.FormType.HideResize+proteo.gui.FormType.HideClose,"","",150,150,MAX_X-300,MAX_Y-300,"") + admin.form_config=proteo.gui.newForm("form_config","Config",'Helvetica',20,"jet","crimson","blanchedalmond",30,proteo.gui.FormType.Fixed+proteo.gui.FormType.HideResize+proteo.gui.FormType.HideClose,"","",150,150,MAX_X-300,MAX_Y-300,"") form_permissions=proteo.gui.newForm("form_permissions","Permissions",'Helvetica',20,"jet","crimson","blanchedalmond",30,proteo.gui.FormType.Fixed+proteo.gui.FormType.HideResize+proteo.gui.FormType.HideClose,"","",150,150,MAX_X-300,MAX_Y-300,"") - option_button=proteo.gui.newButton('option_button','Options','Helvetica',20,'jet','blanchedalmond',1,"crimson",false,MIN_X,180,150,50,open_options) + admin.config_button=proteo.gui.newButton('config_button','Config','Helvetica',20,'jet','blanchedalmond',1,"crimson",false,MIN_X,180,150,50,open_options) users_button=proteo.gui.newButton('users_button','Users','Helvetica',20,'jet','blanchedalmond',1,"crimson",false,MIN_X,230,150,50,open_users) permissions_button=proteo.gui.newButton('permissions_button','Permissions','Helvetica',20,'jet','blanchedalmond',1,"crimson",false,MIN_X,280,150,50,open_permissions) @@ -106,15 +111,15 @@ function init() removeplugin_button=proteo.gui.newButton('removeplugin_button',"Remove",'Helvetica',20,"jet","blanchedalmond",1,"crimson",false,175 ,425,100,25,"remove_plugin") save_button=proteo.gui.newButton('save_button',"Save",'Helvetica',20,"jet","blanchedalmond",1,"crimson",false,MAX_X-425 ,MAX_Y-350,100,25,"save_option") - proteo.gui.addItem(form_options,label_plugins) - proteo.gui.addItem(form_options,list_plugins) - proteo.gui.addItem(form_options,addplugin_button) - proteo.gui.addItem(form_options,removeplugin_button) - proteo.gui.addItem(form_options,save_button) + proteo.gui.addItem(admin.form_config,label_plugins) + proteo.gui.addItem(admin.form_config,list_plugins) + proteo.gui.addItem(admin.form_config,addplugin_button) + proteo.gui.addItem(admin.form_config,removeplugin_button) + proteo.gui.addItem(admin.form_config,save_button) proteo.network.proteo_get("/admin/config","config_callback") - open_options(option_button) + open_options(admin.config_button) end -------------------- @@ -146,20 +151,20 @@ end function open_options(sender) proteo.gui.setHidden(form_users,true) - proteo.gui.setHidden(form_options,false) + proteo.gui.setHidden(admin.form_config,false) proteo.gui.setHidden(form_permissions,true) - proteo.gui.setColor(option_button,'blanchedalmond') + proteo.gui.setColor(admin.config_button,'blanchedalmond') proteo.gui.setColor(users_button,'cadetgrey') proteo.gui.setColor(permissions_button,'cadetgrey') end function open_users(sender) proteo.gui.setHidden(form_users,false) - proteo.gui.setHidden(form_options,true) + proteo.gui.setHidden(admin.form_config,true) proteo.gui.setHidden(form_permissions,true) - proteo.gui.setColor(option_button,'cadetgrey') + proteo.gui.setColor(admin.config_button,'cadetgrey') proteo.gui.setColor(users_button,'blanchedalmond') proteo.gui.setColor(permissions_button,'cadetgrey') @@ -176,10 +181,10 @@ end function open_permissions(sender) proteo.gui.setHidden(form_users,true) - proteo.gui.setHidden(form_options,true) + proteo.gui.setHidden(admin.form_config,true) proteo.gui.setHidden(form_permissions,false) - proteo.gui.setColor(option_button,'cadetgrey') + proteo.gui.setColor(admin.config_button,'cadetgrey') proteo.gui.setColor(users_button,'cadetgrey') proteo.gui.setColor(permissions_button,'blanchedalmond') end diff --git a/server/script/demo/movelab.json b/server/script/demo/movelab.json index 05606e8..f6c6195 100644 --- a/server/script/demo/movelab.json +++ b/server/script/demo/movelab.json @@ -1,4 +1,5 @@ { "version": "0.1", - "plugins": ["proteo","deepcrimson"] + "plugins": ["proteo","deepcrimson"], + "libs":["json","md5","inspect","tfl_utility"] } \ No newline at end of file diff --git a/server/script/demo/movelab.lua b/server/script/demo/movelab.lua index cba995c..0167084 100644 --- a/server/script/demo/movelab.lua +++ b/server/script/demo/movelab.lua @@ -27,39 +27,74 @@ colors.button_font="black" colors.button_back="aliceblue" colors.button_border="black" + + function selectvideo(sel) selected_video=videos[proteo.system.getName(sel)] + print("Selected video: "..selected_video) + --video_cap=proteo.opencv.videocapture("http://localhost:8888/sample_video.avi") end +function frame_update(dt) + + --analyzeframe(current_frame) + --frame_wl=proteo.opencv.img() + --proteo.opencv.copy(current_video[current_frame].frame,frame_wl) + + --proteo.graphics.changeImage(video_img,frame_wl) + + --current_frame=current_frame+1 + + analyzeframe(current_frame) + + current_frame=current_frame+1 + + if current_frame>#current_video then + proteo.system.stopTimer(frame_timer) + end +end + +frame_timer=proteo.system.createTimer(50,frame_update) + function landmarks_callback(res,data) frame_wl=proteo.opencv.img() --proteo.opencv.setSize(current_video[current_frame].frame_wl,video_size.x,video_size.y) proteo.opencv.copy(current_video[current_frame].frame,frame_wl) + current_video[current_frame].request=data['request'] current_video[current_frame].data=data['data'] - - for _, b in ipairs(data['data']) do - landmarks = show_landmark(b,frame_wl,b['landmarks']) + current_video[current_frame].landmarks={} + + for i, b in ipairs(data['data']) do + --print("Center X:"..landmarks[1].x.." Y:"..landmarks[1].y) + landmarks = get_landmark(b,frame_wl,b['landmarks']) + current_video[current_frame].landmarks[i]=landmarks + + if data['request']=="TFLPOSE" or data['request']=="TFLHOLI" then + show_pose(landmarks,frame_wl) + elseif data['request'] == "TFLFACE" then + show_facemesh(landmarks,frame_wl) + else + show_hand(landmarks,frame_wl) + end end + if current_video[current_frame].request=="TFLHOLI" then + for _, b in ipairs(data['face']) do + landmarks = show_landmark(b,frame_wl,b['landmarks']) + end + end + proteo.graphics.changeImage(video_img,frame_wl) + end -function analysevideo(sender) - - sel=proteo.gui.getValue(drop_video) - if sel==nil then - return - end - --proteo.opencv.resize(video_frame,video_resized) - --proteo.opencv.cropImg(video_frame,video_resized,(videosize[2]-456)/2,(videosize[1]-256)/2,456,256) - - --proteo.opencv.convert(current_video[videoframe].frame,current_video[videoframe].frame,proteo.opencv.matType.CV_32F) - local tmp=proteo.opencv.imencode(current_video[current_frame].frame) +function analyzeframe(nframe) + local tmp=proteo.opencv.imencode(current_video[nframe].frame) local data={} data['type']='FRAME' @@ -69,6 +104,10 @@ function analysevideo(sender) data["request"]="TFLFACE" elseif proteo.gui.getId(sel)=="drop_gui_pose" then data["request"]="TFLPOSE" + elseif proteo.gui.getId(sel)=="drop_gui_holi" then + data["request"]="TFLHOLI" + elseif proteo.gui.getId(sel)=="drop_gui_hand" then + data["request"]="TFLHAND" end data["frame"]=tmp @@ -76,22 +115,64 @@ function analysevideo(sender) local js=json.encode(data) proteo.network.proteo_post("/deepcrimson/landmarks",js,landmarks_callback) +end +function analyzecurrentframe(sender) + + sel=proteo.gui.getValue(drop_video) + if sel==nil then + return + end + + analyzeframe(current_frame) + +end + +function analyzevideo(sender) + + sel=proteo.gui.getValue(drop_video) + if sel==nil then + return + end + + current_frame=1 + proteo.system.startTimer(frame_timer) + +end + +function savedata(sender) + + for i=1,#current_video do + if current_video[i].landmarks~=nil then + for j=1,#current_video[i].landmarks do + row="Frame"..i..",Box"..j + for k=1,#current_video[i].landmarks[j] do + row=row..","..current_video[i].landmarks[j][k].x + row=row..","..current_video[i].landmarks[j][k].y + row=row..","..current_video[i].landmarks[j][k].z + end + print(row) + end + end + end end function showvideo(sender) if selected_video~=nil then current_video={} --data=proteo.system.readFile(selected_file,readfile) + --selected_video="http://localhost:8888/sample_video.avi" + + --In modalità web la fase di videocapture richiede un'attesa prima di richiedere il frame, per adesso ho spostato in selectvideo video_cap=proteo.opencv.videocapture(selected_video) local i=1 video_frame=proteo.opencv.img() while proteo.opencv.frame(video_cap,video_frame)==1 do + --if proteo.opencv.frame(video_cap,video_frame)==1 then current_video[i]={} current_video[i].frame=proteo.opencv.img() - proteo.opencv.setImg(current_video[i].frame,video_size.x,video_size.y,"#000000") proteo.opencv.resize(video_frame,current_video[i].frame) --proteo.opencv.infoImg(current_video[i].frame) @@ -99,7 +180,6 @@ function showvideo(sender) end current_frame=1 - proteo.graphics.changeImage(video_img,current_video[current_frame].frame) end @@ -114,10 +194,15 @@ function nextvideo(sender) frame_wl=proteo.opencv.img() proteo.opencv.copy(current_video[current_frame].frame,frame_wl) - for _, b in ipairs(current_video[current_frame].data) do - landmarks = show_landmark(b,frame_wl,b['landmarks']) - end - + for i=1,#current_video[current_frame].landmarks do + if current_video[current_frame].request == "TFLPOSE" or current_video[current_frame].requestv=="TFLHOLI" then + show_pose(current_video[current_frame].landmarks[i],frame_wl) + elseif current_video[current_frame].request == "TFLFACE" then + show_facemesh(current_video[current_frame].landmarks[i],frame_wl) + else + show_hand(current_video[current_frame].landmarks[i],frame_wl) + end + end proteo.graphics.changeImage(video_img,frame_wl) else @@ -136,10 +221,15 @@ function prevvideo(sender) frame_wl=proteo.opencv.img() proteo.opencv.copy(current_video[current_frame].frame,frame_wl) - for _, b in ipairs(current_video[current_frame].data) do - landmarks = show_landmark(b,frame_wl,b['landmarks']) - end - + for i=1,#current_video[current_frame].landmarks do + if current_video[current_frame].request == "TFLPOSE" or current_video[current_frame].requestv=="TFLHOLI" then + show_pose(current_video[current_frame].landmarks[i],frame_wl) + elseif current_video[current_frame].request == "TFLFACE" then + show_facemesh(current_video[current_frame].landmarks[i],frame_wl) + else + show_hand(current_video[current_frame].landmarks[i],frame_wl) + end + end proteo.graphics.changeImage(video_img,frame_wl) else @@ -155,16 +245,22 @@ function create_page() video_load=proteo.gui.newList('video_load','','Helvetica',30,colors.list_font,colors.list_back,MIN_X+20,150,500,400,selectvideo) show_video=proteo.gui.newButton('show_video',"Show>>",'Helvetica',25,colors.button_font,colors.button_back,1,colors.button_border,true,MIN_X + 420 ,MAX_Y - 220,100,50,showvideo) video_img=proteo.graphics.newImage("video","@video",800,350,video_size.x,video_size.y) - next_video=proteo.gui.newButton('next_video',">>",'Helvetica',25,colors.button_font,colors.button_back,1,colors.button_border,true,MIN_X + 650 ,MAX_Y - 120,100,50,nextvideo) - prev_video=proteo.gui.newButton('prev_video',"<<",'Helvetica',25,colors.button_font,colors.button_back,1,colors.button_border,true,MIN_X + 500 ,MAX_Y - 120,100,50,prevvideo) + next_video=proteo.gui.newButton('next_video',">>",'Helvetica',25,colors.button_font,colors.button_back,1,colors.button_border,true,MIN_X + 500 ,MAX_Y - 120,100,50,nextvideo) + prev_video=proteo.gui.newButton('prev_video',"<<",'Helvetica',25,colors.button_font,colors.button_back,1,colors.button_border,true,MIN_X + 350 ,MAX_Y - 120,100,50,prevvideo) - analyse_video=proteo.gui.newButton('analyse_video',"Analyse",'Helvetica',25,colors.button_font,colors.button_back,1,colors.button_border,true,MIN_X + 800 ,MAX_Y - 120,300,50,analysevideo) + analyze_frame=proteo.gui.newButton('analyse_frame',"Analyze Frame",'Helvetica',20,colors.button_font,colors.button_back,1,colors.button_border,true,MIN_X + 650 ,MAX_Y - 120,150,50,analyzecurrentframe) + analyze_video=proteo.gui.newButton('analyse_video',"Analyze All",'Helvetica',20,colors.button_font,colors.button_back,1,colors.button_border,true,MIN_X + 820 ,MAX_Y - 120,150,50,analyzevideo) + save_data=proteo.gui.newButton('analyse_video',"Save",'Helvetica',25,colors.button_font,colors.button_back,1,colors.button_border,true,MIN_X + 990 ,MAX_Y - 120,150,50,savedata) - drop_video=proteo.gui.newDropDown('drop_video',"Select Mode",'Helvetica',20,colors.button_font,colors.button_back,"",proteo.gui.DropDownType.Normal,colors.button_back,MIN_X+200 ,MAX_Y - 110,200,30,"") + drop_video=proteo.gui.newDropDown('drop_video',"Select Mode",'Helvetica',20,colors.button_font,colors.button_back,"",proteo.gui.DropDownType.Normal,colors.button_back,MIN_X+50 ,MAX_Y - 150,200,30,"") drop_gui_pose=proteo.gui.newDropDownItem('drop_gui_pose',"BlazePose",'Helvetica',20,colors.button_font,colors.button_back,"","",200,30) drop_gui_face=proteo.gui.newDropDownItem('drop_gui_face',"BlazeFace",'Helvetica',20,colors.button_font,colors.button_back,"","",200,30) + drop_gui_hand=proteo.gui.newDropDownItem('drop_gui_hand',"Hand",'Helvetica',20,colors.button_font,colors.button_back,"","",200,30) + drop_gui_holi=proteo.gui.newDropDownItem('drop_gui_holi',"Holistic",'Helvetica',20,colors.button_font,colors.button_back,"","",200,30) proteo.gui.addItem(drop_video,drop_gui_pose) proteo.gui.addItem(drop_video,drop_gui_face) + proteo.gui.addItem(drop_video,drop_gui_hand) + proteo.gui.addItem(drop_video,drop_gui_holi) proteo.gui.addItem(form,video_load) proteo.gui.addItem(form,video_img) @@ -172,7 +268,9 @@ function create_page() proteo.gui.addItem(form,next_video) proteo.gui.addItem(form,prev_video) proteo.gui.addItem(form,drop_video) - proteo.gui.addItem(form,analyse_video) + proteo.gui.addItem(form,analyze_video) + proteo.gui.addItem(form,analyze_frame) + proteo.gui.addItem(form,save_data) page={} page.form=form @@ -189,11 +287,17 @@ function load_list(video_list) proteo.system.document(), "%a*avi$", function(filename) + print("Found:"..filename) + --if EMSCRIPTEN==0 then videos[md5.sumhexa(filename)]=filename - list_item_file=proteo.gui.newListItem(md5.sumhexa(filename),proteo.system.basename(filename),'Helvetica',15,colors.list_font,colors.list_back,"","",500,50) - proteo.gui.addItem(video_list,list_item_file) + --else + -- videos[filename]=filename + -- list_item_file=proteo.gui.newListItem(filename,proteo.system.basename(filename),'Helvetica',15,colors.list_font,colors.list_back,"","",500,50) + --end + + proteo.gui.addItem(video_list,list_item_file) end ) end @@ -203,12 +307,19 @@ function start_callback(res,data) current_session = data['session'] end +function download_callback() + +end function init() home=create_page() load_list(home.video_load) + --if EMSCRIPTEN==1 then + -- proteo.network.download("sample_video.avi","/proteo/sample_video.avi","download_callback") + --end + proteo.network.proteo_post("/deepcrimson/start",'{}',start_callback) proteo.gui.setHidden(home.form,false) diff --git a/server/script/prova.json b/server/script/prova.json index 68069cc..23821f9 100644 --- a/server/script/prova.json +++ b/server/script/prova.json @@ -1,4 +1,5 @@ { "version": "0.1", - "plugins": ["proteo"] + "plugins": ["proteo"], + "libs":["json","skl_utility","tfl_utility"] } \ No newline at end of file diff --git a/server/script/prova.lua b/server/script/prova.lua index 1f96868..4ae55ce 100644 --- a/server/script/prova.lua +++ b/server/script/prova.lua @@ -109,6 +109,7 @@ farfalla_animation = {{0,0,33,0,1,1, 2,1, 3,1, 4,1, 5,1, 6,1, 7,1, 8,1, 9,1, 10, } farfalla_animation = farfalla_animation[1] graphics_event = function(dt) + farfalla_animation[CURRENT_TICK] = farfalla_animation[CURRENT_TICK] + 1 if math.random(1, 50) == 1 then d_x = math.random(-2, 2) @@ -145,6 +146,47 @@ skl_read_callback = function(data,filename) proteo.graphics.updateSkeleton(skeleton) end +--shader=nil +shader_u_time=2.0 + +function render(my_shader) + if my_shader~=nil then + proteo.graphics.setUniform(my_shader,"u_time",shader_u_time) + shader_u_time=shader_u_time+0.1 + end +end + +particle_option={} + +function endLife(sender) + + particle_option.frame_x=0 + particle_option.frame_y=0 + particle_option.frame_width=256 + particle_option.frame_height=256 + + particle_option.startSpeed=80.0+20*math.random() + particle_option.startDirection=(-3.14/2)-(math.random()-0.5) + particle_option.lifeTime=3000*math.random() + particle_option.linearAccelerationX=150.0 + 50*math.random() + particle_option.linearAccelerationY=50.0 + 50*math.random() + particle_option.angularSpeed=0 -- 1.5708 + + particle_option.position_x=20*math.random()-10 + particle_option.position_y=20*math.random()-10 + + particle_option.spin=5.0*math.random() + + particle_option.startSize=1.0 + particle_option.endSize=2.0 + + particle_option.startColor="#aae25822" + particle_option.endColor="#00bbaaff" + + proteo.graphics.setParticle(sender,particle_option) + proteo.graphics.setPosition(sender,farfalla_x,farfalla_y) +end + graphics_init = function(sender) t5 = proteo.system.createTimer(20,graphics_event) proteo.system.startTimer(t5) @@ -165,13 +207,64 @@ graphics_init = function(sender) shape = proteo.graphics.newShape("shape",150,150) svg2shape(svgfile,shape) skeleton = proteo.graphics.newSkeleton("skeleton") - proteo.system.readFile(proteo.system.document()..'skeleton.json',skl_read_callback) + --proteo.system.readFile(proteo.system.document()..'skeleton.json',skl_read_callback) + rect_graphics=proteo.graphics.newRect("rect","white","",100,100,200,200) + +math.randomseed( os.time() ) + + particle_option.frame_x=0 + particle_option.frame_y=0 + particle_option.frame_width=128 + particle_option.frame_height=128 + particle_option.startColor="#aae25822" + particle_option.endColor="#00bbaaff" + +particles={} + for p=1,500 do + particle_option.startSpeed=80.0+20*math.random() + particle_option.startDirection=(-3.14/2)-(math.random()-0.5) + particle_option.lifeTime=3000*math.random() + particle_option.linearAccelerationX=150.0 + 50*math.random() + particle_option.linearAccelerationY=50.0 + 50*math.random() + particle_option.angularSpeed=0 -- 1.5708 + particle_option.spin=5.0*math.random() + particle_option.startSize=1.0 + particle_option.endSize=2.0 + + particles[p]=proteo.graphics.newParticle("P"..p,proteo.system.document().."sparkle.png",500,200,32,32,particle_option,endLife) + end + +if SHADER==1 then + shader=proteo.graphics.newShader([[ + void main() + { + gl_Position = ftransform(); + } +]],[[ + uniform float u_time; + + void main() + { + //gl_FragColor = vec4( 1.0, 0.0, 1.0, 1.0 ); + gl_FragColor = vec4(abs(sin(u_time)),0.0,0.0,1.0); + } +]]) + +proteo.graphics.setShader(rect_graphics,shader,render) +end + graphicsForm=Form('graphicsForm') graphicsForm.backgroundColor='#000000' graphicsForm:addControl(t_graphics) graphicsForm:addControl(back_graphics) graphicsForm:addControl(farfalla) graphicsForm:addControl(shape) + graphicsForm:addControl(rect_graphics) + --graphicsForm:addControl(part) + for p=1,500 do + graphicsForm:addControl(particles[p]) + end + forms['graphicsForm']=graphicsForm forms['graphicsForm']:show() end diff --git a/server/ticket.lua b/server/ticket.lua new file mode 100644 index 0000000..af85cda --- /dev/null +++ b/server/ticket.lua @@ -0,0 +1,41 @@ + + +current_ticket_db={} + +function ticket_get(app) + + maxT=-1 + bestUrl="localhost" + for url, value in pairs(current_ticket_db[app]) do + + if value>maxT then + maxT=value + bestUrl=url + end + end + + print("Get Ticket: " ..app.." "..bestUrl.." "..maxT) + + if maxT>0 then + current_ticket_db[app][bestUrl]=maxT-1 + else + proteo.system.updateTickets(bestUrl) + end + + return bestUrl +end + +function ticket_add(app,url,value) + + --If the url is localhost you have to modify it before sending it to the client + url=url:gsub("localhost",BASEURL) + + print("Add Ticket: " ..app.." "..url.." "..value) + + if current_ticket_db[app]==nil then + current_ticket_db[app]={} + end + + current_ticket_db[app][url]=value + +end \ No newline at end of file diff --git a/server/update.sh b/server/update.sh deleted file mode 100755 index 271b761..0000000 --- a/server/update.sh +++ /dev/null @@ -1,6 +0,0 @@ -git pull -cd build -cmake -DCMAKE_BUILD_TYPE=Debug -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl .. -make -cp ./proteo_server ../ -cd .. diff --git a/server/upload.sh b/server/upload.sh deleted file mode 100755 index ba9e24d..0000000 --- a/server/upload.sh +++ /dev/null @@ -1,3 +0,0 @@ -git stage * -git commit -git push diff --git a/server/web/blockly/code.js b/server/web/blockly/code.js index 7363799..0ac7a77 100644 --- a/server/web/blockly/code.js +++ b/server/web/blockly/code.js @@ -14,7 +14,7 @@ * Create a namespace for the application. */ var Code = {}; -var appKey="1234567890123456789012"; +var appKey="}~?d1BE+\"d5?TZ(j`{+n`pfK&*2U(WPy"; /** * Lookup for names of supported languages. Keys should be in ISO 639 format. diff --git a/server/web/blockly/demo.js b/server/web/blockly/demo.js index 814420e..774a938 100644 --- a/server/web/blockly/demo.js +++ b/server/web/blockly/demo.js @@ -537,7 +537,7 @@ Blockly.Lua['tetris_getjoint'] = function(block) { Blockly.Blocks['tetris_move'] = { init: function() { this.appendDummyInput() - .appendField("move") + .appendField("move block") .appendField(new Blockly.FieldDropdown([["left","left"], ["right","right"], ["rotate","rotate"], ["down","down"]]), "joint"); this.setPreviousStatement(true, null); this.setNextStatement(true, null); @@ -559,4 +559,94 @@ Blockly.Lua['tetris_move'] = function(block) { return code; }; +Blockly.Blocks['tetris_move_action'] = { + init: function() { + this.appendStatementInput("effect") + .setCheck(null) + .appendField("if user") + .appendField(new Blockly.FieldDropdown([["raise left arm","LEFT_ARM"], ["raise right arm","RIGHT_ARM"], ["crouch","CROUCH"], ["jump","JUMP"], ["tilt head left","TILT_LEFT"], ["tilt head right","TILT_RIGHT"]]), "NAME"); + this.setPreviousStatement(true, null); + this.setNextStatement(true, null); + this.setColour(225); + this.setTooltip(""); + this.setHelpUrl(""); + } +}; + +Blockly.Lua['tetris_move_action'] = function(block) { + var dropdown_name = block.getFieldValue('NAME'); + var statements_effect = Blockly.Lua.statementToCode(block, 'effect'); + // TODO: Assemble Lua into code variable. + var code = '...\n'; + return code; +}; + +Blockly.Blocks['tetris_save_block'] = { + init: function() { + this.appendDummyInput() + .appendField("save current information:"); + this.appendDummyInput() + .setAlign(Blockly.ALIGN_RIGHT) + .appendField("number of times raise left arm") + .appendField(new Blockly.FieldCheckbox("TRUE"), "NAME"); + this.appendDummyInput() + .setAlign(Blockly.ALIGN_RIGHT) + .appendField("number of times raise right arm") + .appendField(new Blockly.FieldCheckbox("TRUE"), "NAME"); + this.appendDummyInput() + .setAlign(Blockly.ALIGN_RIGHT) + .appendField("greater angle of rotation of the right shoulder") + .appendField(new Blockly.FieldCheckbox("TRUE"), "NAME"); + this.appendDummyInput() + .setAlign(Blockly.ALIGN_RIGHT) + .appendField("greater angle of rotation of the left shoulder") + .appendField(new Blockly.FieldCheckbox("TRUE"), "NAME"); + this.appendDummyInput() + .setAlign(Blockly.ALIGN_RIGHT) + .appendField("number of jumps") + .appendField(new Blockly.FieldCheckbox("TRUE"), "NAME"); + this.appendDummyInput() + .setAlign(Blockly.ALIGN_RIGHT) + .appendField("number of squats") + .appendField(new Blockly.FieldCheckbox("TRUE"), "NAME"); + this.appendDummyInput() + .setAlign(Blockly.ALIGN_RIGHT) + .appendField("number of left head tilts") + .appendField(new Blockly.FieldCheckbox("TRUE"), "NAME"); + this.appendDummyInput() + .setAlign(Blockly.ALIGN_RIGHT) + .appendField("number of right head tilts") + .appendField(new Blockly.FieldCheckbox("TRUE"), "NAME"); + this.appendDummyInput() + .setAlign(Blockly.ALIGN_RIGHT) + .appendField("greater angle of left head tilts") + .appendField(new Blockly.FieldCheckbox("TRUE"), "NAME"); + this.appendDummyInput() + .setAlign(Blockly.ALIGN_RIGHT) + .appendField("greater angle of right head tilts") + .appendField(new Blockly.FieldCheckbox("TRUE"), "NAME"); + this.setPreviousStatement(true, null); + this.setNextStatement(true, null); + this.setColour(225); + this.setTooltip(""); + this.setHelpUrl(""); + } +}; + +Blockly.Lua['tetris_save_block'] = function(block) { + var checkbox_name = block.getFieldValue('NAME') == 'TRUE'; + var checkbox_name = block.getFieldValue('NAME') == 'TRUE'; + var checkbox_name = block.getFieldValue('NAME') == 'TRUE'; + var checkbox_name = block.getFieldValue('NAME') == 'TRUE'; + var checkbox_name = block.getFieldValue('NAME') == 'TRUE'; + var checkbox_name = block.getFieldValue('NAME') == 'TRUE'; + var checkbox_name = block.getFieldValue('NAME') == 'TRUE'; + var checkbox_name = block.getFieldValue('NAME') == 'TRUE'; + var checkbox_name = block.getFieldValue('NAME') == 'TRUE'; + var checkbox_name = block.getFieldValue('NAME') == 'TRUE'; + // TODO: Assemble Lua into code variable. + var code = '...\n'; + return code; +}; + diff --git a/server/web/blockly/index.html b/server/web/blockly/index.html index 06cfff6..bdb02fd 100644 --- a/server/web/blockly/index.html +++ b/server/web/blockly/index.html @@ -711,6 +711,8 @@

+ +