Compare commits
	
		
			14 Commits
		
	
	
		
			v9.5.0
			...
			feature/lu
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					22fc8e981d | ||
| 
						 | 
					fb0de53efd | ||
| 
						 | 
					62a7483e41 | ||
| 
						 | 
					36fbdd0daa | ||
| 
						 | 
					feff2e38c0 | ||
| 
						 | 
					a040ff06e8 | ||
| 
						 | 
					755493eaf3 | ||
| 
						 | 
					4c61aede2e | ||
| 
						 | 
					fbca513008 | ||
| 
						 | 
					33ebd00932 | ||
| 
						 | 
					fbe5e74109 | ||
| 
						 | 
					a9f5d5353f | ||
| 
						 | 
					22e0083832 | ||
| 
						 | 
					5632360fbd | 
							
								
								
									
										9
									
								
								.github/workflows/ccpp.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								.github/workflows/ccpp.yml
									
									
									
									
										vendored
									
									
								
							@@ -19,15 +19,6 @@ jobs:
 | 
				
			|||||||
    - name: make test_tsan
 | 
					    - name: make test_tsan
 | 
				
			||||||
      run: make test_tsan
 | 
					      run: make test_tsan
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  mac_tsan_openssl:
 | 
					 | 
				
			||||||
    runs-on: macOS-latest
 | 
					 | 
				
			||||||
    steps:
 | 
					 | 
				
			||||||
    - uses: actions/checkout@v1
 | 
					 | 
				
			||||||
    - name: install openssl
 | 
					 | 
				
			||||||
      run: brew install openssl@1.1
 | 
					 | 
				
			||||||
    - name: make test
 | 
					 | 
				
			||||||
      run: make test_tsan_openssl
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  mac_tsan_mbedtls:
 | 
					  mac_tsan_mbedtls:
 | 
				
			||||||
    runs-on: macOS-latest
 | 
					    runs-on: macOS-latest
 | 
				
			||||||
    steps:
 | 
					    steps:
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										106
									
								
								CMakeLists.txt
									
									
									
									
									
								
							
							
						
						
									
										106
									
								
								CMakeLists.txt
									
									
									
									
									
								
							@@ -114,18 +114,15 @@ endif()
 | 
				
			|||||||
option(USE_TLS "Enable TLS support" FALSE)
 | 
					option(USE_TLS "Enable TLS support" FALSE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if (USE_TLS)
 | 
					if (USE_TLS)
 | 
				
			||||||
    option(USE_MBED_TLS "Use Mbed TLS" OFF)
 | 
					    # default to securetranport on Apple if nothing is configured
 | 
				
			||||||
    option(USE_OPEN_SSL "Use OpenSSL" OFF)
 | 
					    if (APPLE)
 | 
				
			||||||
    option(USE_SECURE_TRANSPORT "Use Secure Transport" OFF)
 | 
					      if (NOT USE_MBED_TLS AND NOT USE_OPEN_SSL) # unless we want something else
 | 
				
			||||||
 | 
					        set(USE_SECURE_TRANSPORT ON)
 | 
				
			||||||
    # default to OpenSSL on windows if nothing is configured
 | 
					      endif()
 | 
				
			||||||
    if (WIN32 AND NOT USE_MBED_TLS)
 | 
					    else() # default to OpenSSL on all other platforms
 | 
				
			||||||
      option(USE_OPEN_SSL "Use OpenSSL" ON)
 | 
					      if (NOT USE_MBED_TLS) # Unless mbedtls is requested
 | 
				
			||||||
 | 
					        set(USE_OPEN_SSL ON)
 | 
				
			||||||
      endif()
 | 
					      endif()
 | 
				
			||||||
 | 
					 | 
				
			||||||
    # default to securetranport on windows if nothing is configured
 | 
					 | 
				
			||||||
    if (APPLE AND NOT USE_OPEN_SSL AND NOT USE_MBED_TLS)
 | 
					 | 
				
			||||||
      option(USE_SECURE_TRANSPORT "Use Secure Transport" ON)
 | 
					 | 
				
			||||||
    endif()
 | 
					    endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (USE_MBED_TLS)
 | 
					    if (USE_MBED_TLS)
 | 
				
			||||||
@@ -134,10 +131,11 @@ if (USE_TLS)
 | 
				
			|||||||
    elseif (USE_SECURE_TRANSPORT)
 | 
					    elseif (USE_SECURE_TRANSPORT)
 | 
				
			||||||
        list( APPEND IXWEBSOCKET_HEADERS ixwebsocket/IXSocketAppleSSL.h)
 | 
					        list( APPEND IXWEBSOCKET_HEADERS ixwebsocket/IXSocketAppleSSL.h)
 | 
				
			||||||
        list( APPEND IXWEBSOCKET_SOURCES ixwebsocket/IXSocketAppleSSL.cpp)
 | 
					        list( APPEND IXWEBSOCKET_SOURCES ixwebsocket/IXSocketAppleSSL.cpp)
 | 
				
			||||||
    else()
 | 
					    elseif (USE_OPEN_SSL)
 | 
				
			||||||
        set(USE_OPEN_SSL ON)
 | 
					 | 
				
			||||||
        list( APPEND IXWEBSOCKET_HEADERS ixwebsocket/IXSocketOpenSSL.h)
 | 
					        list( APPEND IXWEBSOCKET_HEADERS ixwebsocket/IXSocketOpenSSL.h)
 | 
				
			||||||
        list( APPEND IXWEBSOCKET_SOURCES ixwebsocket/IXSocketOpenSSL.cpp)
 | 
					        list( APPEND IXWEBSOCKET_SOURCES ixwebsocket/IXSocketOpenSSL.cpp)
 | 
				
			||||||
 | 
					    else()
 | 
				
			||||||
 | 
					        message(FATAL_ERROR "TLS Configuration error: unknown backend")
 | 
				
			||||||
    endif()
 | 
					    endif()
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -154,11 +152,53 @@ if (USE_TLS)
 | 
				
			|||||||
        target_compile_definitions(ixwebsocket PUBLIC IXWEBSOCKET_USE_OPEN_SSL)
 | 
					        target_compile_definitions(ixwebsocket PUBLIC IXWEBSOCKET_USE_OPEN_SSL)
 | 
				
			||||||
    elseif (USE_SECURE_TRANSPORT)
 | 
					    elseif (USE_SECURE_TRANSPORT)
 | 
				
			||||||
        target_compile_definitions(ixwebsocket PUBLIC IXWEBSOCKET_USE_SECURE_TRANSPORT)
 | 
					        target_compile_definitions(ixwebsocket PUBLIC IXWEBSOCKET_USE_SECURE_TRANSPORT)
 | 
				
			||||||
 | 
					    else()
 | 
				
			||||||
 | 
					        message(FATAL_ERROR "TLS Configuration error: unknown backend")
 | 
				
			||||||
    endif()
 | 
					    endif()
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if (APPLE AND USE_TLS AND NOT USE_MBED_TLS AND NOT USE_OPEN_SSL)
 | 
					if (USE_TLS)
 | 
				
			||||||
 | 
					  if (USE_OPEN_SSL)
 | 
				
			||||||
 | 
					    message(STATUS "TLS configured to use openssl")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Help finding Homebrew's OpenSSL on macOS
 | 
				
			||||||
 | 
					    if (APPLE)
 | 
				
			||||||
 | 
					      set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} /usr/local/opt/openssl/lib)
 | 
				
			||||||
 | 
					      set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} /usr/local/opt/openssl/include)
 | 
				
			||||||
 | 
					    endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # This OPENSSL_FOUND check is to help find a cmake manually configured OpenSSL
 | 
				
			||||||
 | 
					    if (NOT OPENSSL_FOUND)
 | 
				
			||||||
 | 
					      find_package(OpenSSL REQUIRED)
 | 
				
			||||||
 | 
					    endif()
 | 
				
			||||||
 | 
					    message(STATUS "OpenSSL: " ${OPENSSL_VERSION})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    add_definitions(${OPENSSL_DEFINITIONS})
 | 
				
			||||||
 | 
					    target_include_directories(ixwebsocket PUBLIC ${OPENSSL_INCLUDE_DIR})
 | 
				
			||||||
 | 
					    target_link_libraries(ixwebsocket ${OPENSSL_LIBRARIES})
 | 
				
			||||||
 | 
					  elseif (USE_MBED_TLS)
 | 
				
			||||||
 | 
					    message(STATUS "TLS configured to use mbedtls")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    find_package(MbedTLS REQUIRED)
 | 
				
			||||||
 | 
					    target_include_directories(ixwebsocket PUBLIC ${MBEDTLS_INCLUDE_DIRS})
 | 
				
			||||||
 | 
					    target_link_libraries(ixwebsocket ${MBEDTLS_LIBRARIES})
 | 
				
			||||||
 | 
					  elseif (USE_SECURE_TRANSPORT)
 | 
				
			||||||
 | 
					    message(STATUS "TLS configured to use secure transport")
 | 
				
			||||||
    target_link_libraries(ixwebsocket "-framework foundation" "-framework security")
 | 
					    target_link_libraries(ixwebsocket "-framework foundation" "-framework security")
 | 
				
			||||||
 | 
					  endif()
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This ZLIB_FOUND check is to help find a cmake manually configured zlib
 | 
				
			||||||
 | 
					if (NOT ZLIB_FOUND)
 | 
				
			||||||
 | 
					  find_package(ZLIB)
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					if (ZLIB_FOUND)
 | 
				
			||||||
 | 
					  include_directories(${ZLIB_INCLUDE_DIRS})
 | 
				
			||||||
 | 
					  target_link_libraries(ixwebsocket ${ZLIB_LIBRARIES})
 | 
				
			||||||
 | 
					else()
 | 
				
			||||||
 | 
					  include_directories(third_party/zlib ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib)
 | 
				
			||||||
 | 
					  add_subdirectory(third_party/zlib)
 | 
				
			||||||
 | 
					  target_link_libraries(ixwebsocket zlibstatic)
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if (WIN32)
 | 
					if (WIN32)
 | 
				
			||||||
@@ -175,40 +215,6 @@ if (UNIX)
 | 
				
			|||||||
  target_link_libraries(ixwebsocket ${CMAKE_THREAD_LIBS_INIT})
 | 
					  target_link_libraries(ixwebsocket ${CMAKE_THREAD_LIBS_INIT})
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if (USE_TLS AND USE_OPEN_SSL)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  # Help finding Homebrew's OpenSSL on macOS
 | 
					 | 
				
			||||||
  if (APPLE)
 | 
					 | 
				
			||||||
    set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} /usr/local/opt/openssl/lib)
 | 
					 | 
				
			||||||
    set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} /usr/local/opt/openssl/include)
 | 
					 | 
				
			||||||
  endif()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if(NOT OPENSSL_FOUND)
 | 
					 | 
				
			||||||
    find_package(OpenSSL REQUIRED)
 | 
					 | 
				
			||||||
  endif()
 | 
					 | 
				
			||||||
  add_definitions(${OPENSSL_DEFINITIONS})
 | 
					 | 
				
			||||||
  message(STATUS "OpenSSL: " ${OPENSSL_VERSION})
 | 
					 | 
				
			||||||
  include_directories(${OPENSSL_INCLUDE_DIR})
 | 
					 | 
				
			||||||
  target_link_libraries(ixwebsocket ${OPENSSL_LIBRARIES})
 | 
					 | 
				
			||||||
endif()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if (USE_TLS AND USE_MBED_TLS)
 | 
					 | 
				
			||||||
  find_package(MbedTLS REQUIRED)
 | 
					 | 
				
			||||||
  target_include_directories(ixwebsocket PUBLIC ${MBEDTLS_INCLUDE_DIRS})
 | 
					 | 
				
			||||||
  target_link_libraries(ixwebsocket ${MBEDTLS_LIBRARIES})
 | 
					 | 
				
			||||||
endif()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if (NOT ZLIB_FOUND)
 | 
					 | 
				
			||||||
  find_package(ZLIB)
 | 
					 | 
				
			||||||
endif()
 | 
					 | 
				
			||||||
if (ZLIB_FOUND)
 | 
					 | 
				
			||||||
  include_directories(${ZLIB_INCLUDE_DIRS})
 | 
					 | 
				
			||||||
  target_link_libraries(ixwebsocket ${ZLIB_LIBRARIES})
 | 
					 | 
				
			||||||
else()
 | 
					 | 
				
			||||||
  include_directories(third_party/zlib ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib)
 | 
					 | 
				
			||||||
  add_subdirectory(third_party/zlib)
 | 
					 | 
				
			||||||
  target_link_libraries(ixwebsocket zlibstatic)
 | 
					 | 
				
			||||||
endif()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
set( IXWEBSOCKET_INCLUDE_DIRS
 | 
					set( IXWEBSOCKET_INCLUDE_DIRS
 | 
				
			||||||
    ${CMAKE_CURRENT_SOURCE_DIR}
 | 
					    ${CMAKE_CURRENT_SOURCE_DIR}
 | 
				
			||||||
@@ -245,3 +251,7 @@ if (USE_WS OR USE_TEST)
 | 
				
			|||||||
      add_subdirectory(test)
 | 
					      add_subdirectory(test)
 | 
				
			||||||
  endif()
 | 
					  endif()
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (USE_LUAROCKS)
 | 
				
			||||||
 | 
					    add_subdirectory(luarocks)
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,14 @@
 | 
				
			|||||||
# Changelog
 | 
					# Changelog
 | 
				
			||||||
All changes to this project will be documented in this file.
 | 
					All changes to this project will be documented in this file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## [9.5.2] - 2020-04-27
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(cmake) fix cmake broken tls option parsing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## [9.5.1] - 2020-04-27
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(http client) Set default values for most HttpRequestArgs struct members (fix #185)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## [9.5.0] - 2020-04-25
 | 
					## [9.5.0] - 2020-04-25
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(ssl) Default to OpenSSL on Windows, since it can load the system certificates by default
 | 
					(ssl) Default to OpenSSL on Windows, since it can load the system certificates by default
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -78,12 +78,12 @@ namespace ix
 | 
				
			|||||||
        WebSocketHttpHeaders extraHeaders;
 | 
					        WebSocketHttpHeaders extraHeaders;
 | 
				
			||||||
        std::string body;
 | 
					        std::string body;
 | 
				
			||||||
        std::string multipartBoundary;
 | 
					        std::string multipartBoundary;
 | 
				
			||||||
        int connectTimeout;
 | 
					        int connectTimeout = 60;
 | 
				
			||||||
        int transferTimeout;
 | 
					        int transferTimeout = 1800;
 | 
				
			||||||
        bool followRedirects;
 | 
					        bool followRedirects = true;
 | 
				
			||||||
        int maxRedirects;
 | 
					        int maxRedirects = 5;
 | 
				
			||||||
        bool verbose;
 | 
					        bool verbose = false;
 | 
				
			||||||
        bool compress;
 | 
					        bool compress = true;
 | 
				
			||||||
        Logger logger;
 | 
					        Logger logger;
 | 
				
			||||||
        OnProgressCallback onProgressCallback;
 | 
					        OnProgressCallback onProgressCallback;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,4 +6,4 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define IX_WEBSOCKET_VERSION "9.5.0"
 | 
					#define IX_WEBSOCKET_VERSION "9.5.2"
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										30
									
								
								luarocks/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								luarocks/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					#
 | 
				
			||||||
 | 
					# Author: Benjamin Sergeant
 | 
				
			||||||
 | 
					# Copyright (c) 2020 Machine Zone, Inc. All rights reserved.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cmake_minimum_required (VERSION 3.4.1)
 | 
				
			||||||
 | 
					project (luarocks)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# There's -Weverything too for clang
 | 
				
			||||||
 | 
					if (NOT WIN32)
 | 
				
			||||||
 | 
					  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic")
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					set (CMAKE_CXX_STANDARD 14)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					option(USE_TLS "Add TLS support" ON)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include_directories(luarocks .)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add_executable(luarocks main.cpp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include(FindLua)
 | 
				
			||||||
 | 
					find_package(lua REQUIRED)
 | 
				
			||||||
 | 
					target_link_libraries(luarocks ${LUA_LIBRARIES})
 | 
				
			||||||
 | 
					target_include_directories(luarocks PRIVATE ${LUA_INCLUDE_DIR})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# library with the most dependencies come first
 | 
				
			||||||
 | 
					target_link_libraries(luarocks ixwebsocket)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					install(TARGETS luarocks RUNTIME DESTINATION bin)
 | 
				
			||||||
							
								
								
									
										163
									
								
								luarocks/LuaWebSocket.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								luarocks/LuaWebSocket.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,163 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *  LuaWebSocket.h
 | 
				
			||||||
 | 
					 *  Author: Benjamin Sergeant
 | 
				
			||||||
 | 
					 *  Copyright (c) 2020 Machine Zone, Inc. All rights reserved.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern "C"
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    #include "lua.h"
 | 
				
			||||||
 | 
					    #include "lauxlib.h"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "luawrapper.hpp"
 | 
				
			||||||
 | 
					#include <ixwebsocket/IXWebSocket.h>
 | 
				
			||||||
 | 
					#include <chrono>
 | 
				
			||||||
 | 
					#include <thread>
 | 
				
			||||||
 | 
					#include <queue>
 | 
				
			||||||
 | 
					#include <mutex>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace ix
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    class LuaWebSocket
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public:
 | 
				
			||||||
 | 
					            LuaWebSocket()
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                _webSocket.setOnMessageCallback([this](const WebSocketMessagePtr& msg) {
 | 
				
			||||||
 | 
					                    if (msg->type == ix::WebSocketMessageType::Message)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        std::lock_guard<std::mutex> lock(_queueMutex);
 | 
				
			||||||
 | 
					                        _queue.push(msg->str);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            void setUrl(const std::string& url) { _webSocket.setUrl(url); }
 | 
				
			||||||
 | 
					            const std::string& getUrl() { return _webSocket.getUrl(); }
 | 
				
			||||||
 | 
					            void start() { _webSocket.start(); }
 | 
				
			||||||
 | 
					            void send(const std::string& msg) { _webSocket.send(msg); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            const std::string& getMessage()
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                std::lock_guard<std::mutex> lock(_queueMutex);
 | 
				
			||||||
 | 
					                return _queue.front();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            bool hasMessage()
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                std::lock_guard<std::mutex> lock(_queueMutex);
 | 
				
			||||||
 | 
					                return !_queue.empty();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            void popMessage()
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                std::lock_guard<std::mutex> lock(_queueMutex);
 | 
				
			||||||
 | 
					                _queue.pop();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private:
 | 
				
			||||||
 | 
					            WebSocket _webSocket;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            std::queue<std::string> _queue;
 | 
				
			||||||
 | 
					            std::mutex _queueMutex;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    LuaWebSocket* WebSocket_new(lua_State* /*L*/)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        LuaWebSocket* webSocket = new LuaWebSocket();
 | 
				
			||||||
 | 
					        return webSocket;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int WebSocket_getUrl(lua_State* L)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        LuaWebSocket* luaWebSocket = luaW_check<LuaWebSocket>(L, 1);
 | 
				
			||||||
 | 
					        lua_pushstring(L, luaWebSocket->getUrl().c_str());
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int WebSocket_setUrl(lua_State* L)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        LuaWebSocket* luaWebSocket = luaW_check<LuaWebSocket>(L, 1);
 | 
				
			||||||
 | 
					        const char* url = luaL_checkstring(L, 2);
 | 
				
			||||||
 | 
					        luaWebSocket->setUrl(url);
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int WebSocket_start(lua_State* L)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        LuaWebSocket* luaWebSocket = luaW_check<LuaWebSocket>(L, 1);
 | 
				
			||||||
 | 
					        luaWebSocket->start();
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int WebSocket_send(lua_State* L)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        LuaWebSocket* luaWebSocket = luaW_check<LuaWebSocket>(L, 1);
 | 
				
			||||||
 | 
					        const char* msg = luaL_checkstring(L, 2);
 | 
				
			||||||
 | 
					        luaWebSocket->send(msg);
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int WebSocket_getMessage(lua_State* L)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        LuaWebSocket* luaWebSocket = luaW_check<LuaWebSocket>(L, 1);
 | 
				
			||||||
 | 
					        lua_pushstring(L, luaWebSocket->getMessage().c_str());
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int WebSocket_hasMessage(lua_State* L)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        LuaWebSocket* luaWebSocket = luaW_check<LuaWebSocket>(L, 1);
 | 
				
			||||||
 | 
					        lua_pushboolean(L, luaWebSocket->hasMessage());
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int WebSocket_popMessage(lua_State* L)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        LuaWebSocket* luaWebSocket = luaW_check<LuaWebSocket>(L, 1);
 | 
				
			||||||
 | 
					        luaWebSocket->popMessage();
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // FIXME: This should be a static method, or be part of a different module
 | 
				
			||||||
 | 
					    int WebSocket_sleep(lua_State* L)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // LuaWebSocket* luaWebSocket = luaW_check<LuaWebSocket>(L, 1);
 | 
				
			||||||
 | 
					        auto duration = luaL_checkinteger(L, 2);
 | 
				
			||||||
 | 
					        std::this_thread::sleep_for(std::chrono::milliseconds(duration));
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static luaL_Reg WebSocket_table[] = {
 | 
				
			||||||
 | 
					        { NULL, NULL }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static luaL_Reg WebSocket_metatable[] = {
 | 
				
			||||||
 | 
					        { "getUrl", WebSocket_getUrl },
 | 
				
			||||||
 | 
					        { "setUrl", WebSocket_setUrl },
 | 
				
			||||||
 | 
					        { "start", WebSocket_start },
 | 
				
			||||||
 | 
					        { "send", WebSocket_send },
 | 
				
			||||||
 | 
					        { "getMessage", WebSocket_getMessage },
 | 
				
			||||||
 | 
					        { "hasMessage", WebSocket_hasMessage },
 | 
				
			||||||
 | 
					        { "popMessage", WebSocket_popMessage },
 | 
				
			||||||
 | 
					        { "sleep", WebSocket_sleep },
 | 
				
			||||||
 | 
					        { NULL, NULL }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int luaopen_WebSocket(lua_State* L)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        luaW_register<LuaWebSocket>(L,
 | 
				
			||||||
 | 
					            "WebSocket",
 | 
				
			||||||
 | 
					            WebSocket_table,
 | 
				
			||||||
 | 
					            WebSocket_metatable,
 | 
				
			||||||
 | 
					            WebSocket_new
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										56
									
								
								luarocks/Player.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								luarocks/Player.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
				
			|||||||
 | 
					#ifndef PLAYER_HPP
 | 
				
			||||||
 | 
					#define PLAYER_HPP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Player
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    Player(const char* name, unsigned int health) :
 | 
				
			||||||
 | 
					        m_Name(name),
 | 
				
			||||||
 | 
					        m_Health(health)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void info()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        std::cout << m_Name << " have " << m_Health << " HP" << std::endl;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void say(const char* text)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        std::cout << m_Name << ": " << text << std::endl;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void heal(Player* target)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        target->setHealth(100);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const char* getName()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return m_Name;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    unsigned int getHealth()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return m_Health;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool setHealth(unsigned int health)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (health >= 0 && health <= 100)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            m_Health = health;
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    const char* m_Name;
 | 
				
			||||||
 | 
					    unsigned int m_Health;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // PLAYER_HPP
 | 
				
			||||||
							
								
								
									
										7
									
								
								luarocks/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								luarocks/README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					Wrapper based on https://github.com/LuaxY/cpp-lua
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Examples to build C++
 | 
				
			||||||
 | 
					https://github.com/siffiejoe/lua-fltk4lua/blob/master/fltk4lua-scm-0.rockspec
 | 
				
			||||||
 | 
					https://github.com/lua4web/refser/blob/master/rockspecs/refser-0.2-1.rockspec
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										30
									
								
								luarocks/echo_client.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								luarocks/echo_client.lua
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					--
 | 
				
			||||||
 | 
					-- make luarocks && (cd luarocks ; ../build/luarocks/luarocks)
 | 
				
			||||||
 | 
					--
 | 
				
			||||||
 | 
					-- ... git push test with ssh key
 | 
				
			||||||
 | 
					--
 | 
				
			||||||
 | 
					local webSocket = WebSocket.new()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					webSocket:setUrl("ws://localhost:8008")
 | 
				
			||||||
 | 
					print("Url: " .. webSocket:getUrl())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- Start the background thread
 | 
				
			||||||
 | 
					webSocket:start()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					local i = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					while true
 | 
				
			||||||
 | 
					do
 | 
				
			||||||
 | 
					    print("Sending message...")
 | 
				
			||||||
 | 
					    webSocket:send("msg_" .. tostring(i));
 | 
				
			||||||
 | 
					    i = i + 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    print("Waiting 1s...")
 | 
				
			||||||
 | 
					    webSocket:sleep(1000)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if webSocket:hasMessage() then
 | 
				
			||||||
 | 
					        local msg = webSocket:getMessage()
 | 
				
			||||||
 | 
					        print("Received: " .. msg)
 | 
				
			||||||
 | 
					        webSocket:popMessage()
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
							
								
								
									
										15
									
								
								luarocks/functions.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								luarocks/functions.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *  functions.hpp
 | 
				
			||||||
 | 
					 *  Author: Benjamin Sergeant
 | 
				
			||||||
 | 
					 *  Copyright (c) 2020 Machine Zone, Inc. All rights reserved.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int lua_info(lua_State* /*L*/)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    std::cout << "C++ Lua v0.1" << std::endl << std::endl;
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										709
									
								
								luarocks/luawrapper.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										709
									
								
								luarocks/luawrapper.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,709 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2010-2013 Alexander Ames
 | 
				
			||||||
 | 
					 * Alexander.Ames@gmail.com
 | 
				
			||||||
 | 
					 * See Copyright Notice at the end of this file
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// API Summary:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// LuaWrapper is a library designed to help bridge the gab between Lua and
 | 
				
			||||||
 | 
					// C++. It is designed to be small (a single header file), simple, fast,
 | 
				
			||||||
 | 
					// and typesafe. It has no external dependencies, and does not need to be
 | 
				
			||||||
 | 
					// precompiled; the header can simply be dropped into a project and used
 | 
				
			||||||
 | 
					// immediately. It even supports class inheritance to a certain degree. Objects
 | 
				
			||||||
 | 
					// can be created in either Lua or C++, and passed back and forth.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// The main functions of interest are the following:
 | 
				
			||||||
 | 
					//  luaW_is<T>
 | 
				
			||||||
 | 
					//  luaW_to<T>
 | 
				
			||||||
 | 
					//  luaW_check<T>
 | 
				
			||||||
 | 
					//  luaW_push<T>
 | 
				
			||||||
 | 
					//  luaW_register<T>
 | 
				
			||||||
 | 
					//  luaW_setfuncs<T>
 | 
				
			||||||
 | 
					//  luaW_extend<T, U>
 | 
				
			||||||
 | 
					//  luaW_hold<T>
 | 
				
			||||||
 | 
					//  luaW_release<T>
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// These functions allow you to manipulate arbitrary classes just like you
 | 
				
			||||||
 | 
					// would the primitive types (e.g. numbers or strings). If you are familiar
 | 
				
			||||||
 | 
					// with the normal Lua API the behavior of these functions should be very
 | 
				
			||||||
 | 
					// intuative.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// For more information see the README and the comments below
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef LUA_WRAPPER_H_
 | 
				
			||||||
 | 
					#define LUA_WRAPPER_H_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// If you are linking against Lua compiled in C++, define LUAW_NO_EXTERN_C
 | 
				
			||||||
 | 
					#ifndef LUAW_NO_EXTERN_C
 | 
				
			||||||
 | 
					extern "C"
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#endif // LUAW_NO_EXTERN_C
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "lua.h"
 | 
				
			||||||
 | 
					#include "lauxlib.h"
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					#ifndef LUAW_NO_EXTERN_C
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif // LUAW_NO_EXTERN_C
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define LUAW_POSTCTOR_KEY "__postctor"
 | 
				
			||||||
 | 
					#define LUAW_EXTENDS_KEY "__extends"
 | 
				
			||||||
 | 
					#define LUAW_STORAGE_KEY "storage"
 | 
				
			||||||
 | 
					#define LUAW_CACHE_KEY "cache"
 | 
				
			||||||
 | 
					#define LUAW_CACHE_METATABLE_KEY "cachemetatable"
 | 
				
			||||||
 | 
					#define LUAW_HOLDS_KEY "holds"
 | 
				
			||||||
 | 
					#define LUAW_WRAPPER_KEY "LuaWrapper"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A simple utility function to adjust a given index
 | 
				
			||||||
 | 
					// Useful for when a parameter index needs to be adjusted
 | 
				
			||||||
 | 
					// after pushing or popping things off the stack
 | 
				
			||||||
 | 
					inline int luaW_correctindex(lua_State* /*L*/, int index, int correction)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return index < 0 ? index - correction : index;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// These are the default allocator and deallocator. If you would prefer an
 | 
				
			||||||
 | 
					// alternative option, you may select a different function when registering
 | 
				
			||||||
 | 
					// your class.
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					T* luaW_defaultallocator(lua_State*)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return new T();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					void luaW_defaultdeallocator(lua_State*, T* obj)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    delete obj;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// The identifier function is responsible for pushing a value unique to each
 | 
				
			||||||
 | 
					// object on to the stack. Most of the time, this can simply be the address
 | 
				
			||||||
 | 
					// of the pointer, but sometimes that is not adaquate. For example, if you
 | 
				
			||||||
 | 
					// are using shared_ptr you would need to push the address of the object the
 | 
				
			||||||
 | 
					// shared_ptr represents, rather than the address of the shared_ptr itself.
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					void luaW_defaultidentifier(lua_State* L, T* obj)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    lua_pushlightuserdata(L, obj);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// This class is what is used by LuaWrapper to contain the userdata. data
 | 
				
			||||||
 | 
					// stores a pointer to the object itself, and cast is used to cast toward the
 | 
				
			||||||
 | 
					// base class if there is one and it is necessary. Rather than use RTTI and
 | 
				
			||||||
 | 
					// typid to compare types, I use the clever trick of using the cast to compare
 | 
				
			||||||
 | 
					// types. Because there is at most one cast per type, I can use it to identify
 | 
				
			||||||
 | 
					// when and object is the type I want. This is only used internally.
 | 
				
			||||||
 | 
					struct luaW_Userdata
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    luaW_Userdata(void* vptr = NULL, luaW_Userdata (*udcast)(const luaW_Userdata&) = NULL)
 | 
				
			||||||
 | 
					        : data(vptr), cast(udcast) {}
 | 
				
			||||||
 | 
					    void* data;
 | 
				
			||||||
 | 
					    luaW_Userdata (*cast)(const luaW_Userdata&);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// This class cannot actually to be instantiated. It is used only hold the
 | 
				
			||||||
 | 
					// table name and other information.
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					class LuaWrapper
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    static const char* classname;
 | 
				
			||||||
 | 
					    static void (*identifier)(lua_State*, T*);
 | 
				
			||||||
 | 
					    static T* (*allocator)(lua_State*);
 | 
				
			||||||
 | 
					    static void (*deallocator)(lua_State*, T*);
 | 
				
			||||||
 | 
					    static luaW_Userdata (*cast)(const luaW_Userdata&);
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    LuaWrapper();
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					template <typename T> const char* LuaWrapper<T>::classname;
 | 
				
			||||||
 | 
					template <typename T> void (*LuaWrapper<T>::identifier)(lua_State*, T*);
 | 
				
			||||||
 | 
					template <typename T> T* (*LuaWrapper<T>::allocator)(lua_State*);
 | 
				
			||||||
 | 
					template <typename T> void (*LuaWrapper<T>::deallocator)(lua_State*, T*);
 | 
				
			||||||
 | 
					template <typename T> luaW_Userdata (*LuaWrapper<T>::cast)(const luaW_Userdata&);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Cast from an object of type T to an object of type U. This template
 | 
				
			||||||
 | 
					// function is instantiated by calling luaW_extend<T, U>(L). This is only used
 | 
				
			||||||
 | 
					// internally.
 | 
				
			||||||
 | 
					template <typename T, typename U>
 | 
				
			||||||
 | 
					luaW_Userdata luaW_cast(const luaW_Userdata& obj)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return luaW_Userdata(static_cast<U*>(static_cast<T*>(obj.data)), LuaWrapper<U>::cast);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T, typename U>
 | 
				
			||||||
 | 
					void luaW_identify(lua_State* L, T* obj)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    LuaWrapper<U>::identifier(L, static_cast<U*>(obj));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					inline void luaW_wrapperfield(lua_State* L, const char* field)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    lua_getfield(L, LUA_REGISTRYINDEX, LUAW_WRAPPER_KEY); // ... LuaWrapper
 | 
				
			||||||
 | 
					    lua_getfield(L, -1, field); // ... LuaWrapper LuaWrapper.field
 | 
				
			||||||
 | 
					    lua_getfield(L, -1, LuaWrapper<T>::classname); // ... LuaWrapper LuaWrapper.field LuaWrapper.field.class
 | 
				
			||||||
 | 
					    lua_replace(L, -3); // ... LuaWrapper.field.class LuaWrapper.field
 | 
				
			||||||
 | 
					    lua_pop(L, 1); // ... LuaWrapper.field.class
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Analogous to lua_is(boolean|string|*)
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Returns 1 if the value at the given acceptable index is of type T (or if
 | 
				
			||||||
 | 
					// strict is false, convertable to type T) and 0 otherwise.
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					bool luaW_is(lua_State *L, int index, bool strict = false)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    bool equal = false;// lua_isnil(L, index);
 | 
				
			||||||
 | 
					    if (!equal && lua_isuserdata(L, index) && lua_getmetatable(L, index))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // ... ud ... udmt
 | 
				
			||||||
 | 
					        luaL_getmetatable(L, LuaWrapper<T>::classname); // ... ud ... udmt Tmt
 | 
				
			||||||
 | 
					        equal = lua_rawequal(L, -1, -2) != 0;
 | 
				
			||||||
 | 
					        if (!equal && !strict)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            lua_getfield(L, -2, LUAW_EXTENDS_KEY); // ... ud ... udmt Tmt udmt.extends
 | 
				
			||||||
 | 
					            for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                // ... ud ... udmt Tmt udmt.extends k v
 | 
				
			||||||
 | 
					                equal = lua_rawequal(L, -1, -4) != 0;
 | 
				
			||||||
 | 
					                if (equal)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    lua_pop(L, 2); // ... ud ... udmt Tmt udmt.extends
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            lua_pop(L, 1); // ... ud ... udmt Tmt
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        lua_pop(L, 2); // ... ud ...
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return equal;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Analogous to lua_to(boolean|string|*)
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Converts the given acceptable index to a T*. That value must be of (or
 | 
				
			||||||
 | 
					// convertable to) type T; otherwise, returns NULL.
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					T* luaW_to(lua_State* L, int index, bool strict = false)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (luaW_is<T>(L, index, strict))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        luaW_Userdata* pud = static_cast<luaW_Userdata*>(lua_touserdata(L, index));
 | 
				
			||||||
 | 
					        luaW_Userdata ud;
 | 
				
			||||||
 | 
					        while (!strict && LuaWrapper<T>::cast != pud->cast)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            ud = pud->cast(*pud);
 | 
				
			||||||
 | 
					            pud = &ud;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return static_cast<T*>(pud->data);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Analogous to luaL_check(boolean|string|*)
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Converts the given acceptable index to a T*. That value must be of (or
 | 
				
			||||||
 | 
					// convertable to) type T; otherwise, an error is raised.
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					T* luaW_check(lua_State* L, int index, bool strict = false)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    T* obj = NULL;
 | 
				
			||||||
 | 
					    if (luaW_is<T>(L, index, strict))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        luaW_Userdata* pud = (luaW_Userdata*)lua_touserdata(L, index);
 | 
				
			||||||
 | 
					        luaW_Userdata ud;
 | 
				
			||||||
 | 
					        while (!strict && LuaWrapper<T>::cast != pud->cast)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            ud = pud->cast(*pud);
 | 
				
			||||||
 | 
					            pud = &ud;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        obj = (T*)pud->data;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        const char *msg = lua_pushfstring(L, "%s expected, got %s", LuaWrapper<T>::classname, luaL_typename(L, index));
 | 
				
			||||||
 | 
					        luaL_argerror(L, index, msg);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return obj;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					T* luaW_opt(lua_State* L, int index, T* fallback = NULL, bool strict = false)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (lua_isnil(L, index))
 | 
				
			||||||
 | 
					        return fallback;
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        return luaW_check<T>(L, index, strict);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Analogous to lua_push(boolean|string|*)
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Pushes a userdata of type T onto the stack. If this object already exists in
 | 
				
			||||||
 | 
					// the Lua environment, it will assign the existing storage table to it.
 | 
				
			||||||
 | 
					// Otherwise, a new storage table will be created for it.
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					void luaW_push(lua_State* L, T* obj)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (obj)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        LuaWrapper<T>::identifier(L, obj); // ... id
 | 
				
			||||||
 | 
					        luaW_wrapperfield<T>(L, LUAW_CACHE_KEY); // ... id cache
 | 
				
			||||||
 | 
					        lua_pushvalue(L, -2); // ... id cache id
 | 
				
			||||||
 | 
					        lua_gettable(L, -2); // ... id cache obj
 | 
				
			||||||
 | 
					        if (lua_isnil(L, -1))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // Create the new luaW_userdata and place it in the cache
 | 
				
			||||||
 | 
					            lua_pop(L, 1); // ... id cache
 | 
				
			||||||
 | 
					            lua_insert(L, -2); // ... cache id
 | 
				
			||||||
 | 
					            luaW_Userdata* ud = static_cast<luaW_Userdata*>(lua_newuserdata(L, sizeof(luaW_Userdata))); // ... cache id obj
 | 
				
			||||||
 | 
					            ud->data = obj;
 | 
				
			||||||
 | 
					            ud->cast = LuaWrapper<T>::cast;
 | 
				
			||||||
 | 
					            lua_pushvalue(L, -1); // ... cache id obj obj
 | 
				
			||||||
 | 
					            lua_insert(L, -4); // ... obj cache id obj
 | 
				
			||||||
 | 
					            lua_settable(L, -3); // ... obj cache
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            luaL_getmetatable(L, LuaWrapper<T>::classname); // ... obj cache mt
 | 
				
			||||||
 | 
					            lua_setmetatable(L, -3); // ... obj cache
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            lua_pop(L, 1); // ... obj
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            lua_replace(L, -3); // ... obj cache
 | 
				
			||||||
 | 
					            lua_pop(L, 1); // ... obj
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        lua_pushnil(L);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Instructs LuaWrapper that it owns the userdata, and can manage its memory.
 | 
				
			||||||
 | 
					// When all references to the object are removed, Lua is free to garbage
 | 
				
			||||||
 | 
					// collect it and delete the object.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Returns true if luaW_hold took hold of the object, and false if it was
 | 
				
			||||||
 | 
					// already held
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					bool luaW_hold(lua_State* L, T* obj)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    luaW_wrapperfield<T>(L, LUAW_HOLDS_KEY); // ... holds
 | 
				
			||||||
 | 
					    LuaWrapper<T>::identifier(L, obj); // ... holds id
 | 
				
			||||||
 | 
					    lua_pushvalue(L, -1); // ... holds id id
 | 
				
			||||||
 | 
					    lua_gettable(L, -3); // ... holds id hold
 | 
				
			||||||
 | 
					    // If it's not held, hold it
 | 
				
			||||||
 | 
					    if (!lua_toboolean(L, -1))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // Apply hold boolean
 | 
				
			||||||
 | 
					        lua_pop(L, 1); // ... holds id
 | 
				
			||||||
 | 
					        lua_pushboolean(L, true); // ... holds id true
 | 
				
			||||||
 | 
					        lua_settable(L, -3); // ... holds
 | 
				
			||||||
 | 
					        lua_pop(L, 1); // ...
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    lua_pop(L, 3); // ...
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Releases LuaWrapper's hold on an object. This allows the user to remove
 | 
				
			||||||
 | 
					// all references to an object in Lua and ensure that Lua will not attempt to
 | 
				
			||||||
 | 
					// garbage collect it.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This function takes the index of the identifier for an object rather than
 | 
				
			||||||
 | 
					// the object itself. This is because needs to be able to run after the object
 | 
				
			||||||
 | 
					// has already been deallocated. A wrapper is provided for when it is more
 | 
				
			||||||
 | 
					// convenient to pass in the object directly.
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					void luaW_release(lua_State* L, int index)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    luaW_wrapperfield<T>(L, LUAW_HOLDS_KEY); // ... id ... holds
 | 
				
			||||||
 | 
					    lua_pushvalue(L, luaW_correctindex(L, index, 1)); // ... id ... holds id
 | 
				
			||||||
 | 
					    lua_pushnil(L); // ... id ... holds id nil
 | 
				
			||||||
 | 
					    lua_settable(L, -3); // ... id ... holds
 | 
				
			||||||
 | 
					    lua_pop(L, 1); // ... id ...
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					void luaW_release(lua_State* L, T* obj)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    LuaWrapper<T>::identifier(L, obj); // ... id
 | 
				
			||||||
 | 
					    luaW_release<T>(L, -1); // ... id
 | 
				
			||||||
 | 
					    lua_pop(L, 1); // ...
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// This function is called from Lua, not C++
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Calls the lua post-constructor (LUAW_POSTCTOR_KEY or "__postctor") on a
 | 
				
			||||||
 | 
					// userdata. Assumes the userdata is on top of the stack, and numargs arguments
 | 
				
			||||||
 | 
					// are below it. This runs the LUAW_POSTCTOR_KEY function on T's metatable,
 | 
				
			||||||
 | 
					// using the object as the first argument and whatever else is below it as
 | 
				
			||||||
 | 
					// the rest of the arguments This exists to allow types to adjust values in
 | 
				
			||||||
 | 
					// thier storage table, which can not be created until after the constructor is
 | 
				
			||||||
 | 
					// called.
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					void luaW_postconstructor(lua_State* L, int numargs)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // ... args... ud
 | 
				
			||||||
 | 
					    lua_getfield(L, -1, LUAW_POSTCTOR_KEY); // ... args... ud ud.__postctor
 | 
				
			||||||
 | 
					    if (lua_type(L, -1) == LUA_TFUNCTION)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        lua_pushvalue(L, -2); // ... args... ud ud.__postctor ud
 | 
				
			||||||
 | 
					        lua_insert(L, -3 - numargs); // ... ud args... ud ud.__postctor
 | 
				
			||||||
 | 
					        lua_insert(L, -3 - numargs); // ... ud.__postctor ud args... ud
 | 
				
			||||||
 | 
					        lua_insert(L, -3 - numargs); // ... ud ud.__postctor ud args...
 | 
				
			||||||
 | 
					        lua_call(L, numargs + 1, 0); // ... ud
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        lua_pop(L, 1); // ... ud
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// This function is generally called from Lua, not C++
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Creates an object of type T using the constructor and subsequently calls the
 | 
				
			||||||
 | 
					// post-constructor on it.
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					inline int luaW_new(lua_State* L, int args)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    T* obj = LuaWrapper<T>::allocator(L);
 | 
				
			||||||
 | 
					    luaW_push<T>(L, obj);
 | 
				
			||||||
 | 
					    luaW_hold<T>(L, obj);
 | 
				
			||||||
 | 
					    luaW_postconstructor<T>(L, args);
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					int luaW_new(lua_State* L)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return luaW_new<T>(L, lua_gettop(L));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// This function is called from Lua, not C++
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// The default metamethod to call when indexing into lua userdata representing
 | 
				
			||||||
 | 
					// an object of type T. This will first check the userdata's environment table
 | 
				
			||||||
 | 
					// and if it's not found there it will check the metatable. This is done so
 | 
				
			||||||
 | 
					// individual userdata can be treated as a table, and can hold thier own
 | 
				
			||||||
 | 
					// values.
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					int luaW_index(lua_State* L)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // obj key
 | 
				
			||||||
 | 
					    T* obj = luaW_to<T>(L, 1);
 | 
				
			||||||
 | 
					    luaW_wrapperfield<T>(L, LUAW_STORAGE_KEY); // obj key storage
 | 
				
			||||||
 | 
					    LuaWrapper<T>::identifier(L, obj); // obj key storage id
 | 
				
			||||||
 | 
					    lua_gettable(L, -2); // obj key storage store
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Check if storage table exists
 | 
				
			||||||
 | 
					    if (!lua_isnil(L, -1))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        lua_pushvalue(L, -3); // obj key storage store key
 | 
				
			||||||
 | 
					        lua_gettable(L, -2); // obj key storage store store[k]
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // If either there is no storage table or the key wasn't found
 | 
				
			||||||
 | 
					    // then fall back to the metatable
 | 
				
			||||||
 | 
					    if (lua_isnil(L, -1))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        lua_settop(L, 2); // obj key
 | 
				
			||||||
 | 
					        lua_getmetatable(L, -2); // obj key mt
 | 
				
			||||||
 | 
					        lua_pushvalue(L, -2); // obj key mt k
 | 
				
			||||||
 | 
					        lua_gettable(L, -2); // obj key mt mt[k]
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// This function is called from Lua, not C++
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// The default metamethod to call when creating a new index on lua userdata
 | 
				
			||||||
 | 
					// representing an object of type T. This will index into the the userdata's
 | 
				
			||||||
 | 
					// environment table that it keeps for personal storage. This is done so
 | 
				
			||||||
 | 
					// individual userdata can be treated as a table, and can hold thier own
 | 
				
			||||||
 | 
					// values.
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					int luaW_newindex(lua_State* L)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // obj key value
 | 
				
			||||||
 | 
					    T* obj = luaW_check<T>(L, 1);
 | 
				
			||||||
 | 
					    luaW_wrapperfield<T>(L, LUAW_STORAGE_KEY); // obj key value storage
 | 
				
			||||||
 | 
					    LuaWrapper<T>::identifier(L, obj); // obj key value storage id
 | 
				
			||||||
 | 
					    lua_pushvalue(L, -1); // obj key value storage id id
 | 
				
			||||||
 | 
					    lua_gettable(L, -3); // obj key value storage id store
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Add the storage table if there isn't one already
 | 
				
			||||||
 | 
					    if (lua_isnil(L, -1))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        lua_pop(L, 1); // obj key value storage id
 | 
				
			||||||
 | 
					        lua_newtable(L); // obj key value storage id store
 | 
				
			||||||
 | 
					        lua_pushvalue(L, -1); // obj key value storage id store store
 | 
				
			||||||
 | 
					        lua_insert(L, -3); // obj key value storage store id store
 | 
				
			||||||
 | 
					        lua_settable(L, -4); // obj key value storage store
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    lua_pushvalue(L, 2); // obj key value ... store key
 | 
				
			||||||
 | 
					    lua_pushvalue(L, 3); // obj key value ... store key value
 | 
				
			||||||
 | 
					    lua_settable(L, -3); // obj key value ... store
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// This function is called from Lua, not C++
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// The __gc metamethod handles cleaning up userdata. The userdata's reference
 | 
				
			||||||
 | 
					// count is decremented and if this is the final reference to the userdata its
 | 
				
			||||||
 | 
					// environment table is nil'd and pointer deleted with the destructor callback.
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					int luaW_gc(lua_State* L)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // obj
 | 
				
			||||||
 | 
					    T* obj = luaW_to<T>(L, 1);
 | 
				
			||||||
 | 
					    LuaWrapper<T>::identifier(L, obj); // obj key value storage id
 | 
				
			||||||
 | 
					    luaW_wrapperfield<T>(L, LUAW_HOLDS_KEY); // obj id counts count holds
 | 
				
			||||||
 | 
					    lua_pushvalue(L, 2); // obj id counts count holds id
 | 
				
			||||||
 | 
					    lua_gettable(L, -2); // obj id counts count holds hold
 | 
				
			||||||
 | 
					    if (lua_toboolean(L, -1) && LuaWrapper<T>::deallocator)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        LuaWrapper<T>::deallocator(L, obj);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    luaW_wrapperfield<T>(L, LUAW_STORAGE_KEY); // obj id counts count holds hold storage
 | 
				
			||||||
 | 
					    lua_pushvalue(L, 2); // obj id counts count holds hold storage id
 | 
				
			||||||
 | 
					    lua_pushnil(L); // obj id counts count holds hold storage id nil
 | 
				
			||||||
 | 
					    lua_settable(L, -3); // obj id counts count holds hold storage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    luaW_release<T>(L, 2);
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Thakes two tables and registers them with Lua to the table on the top of the
 | 
				
			||||||
 | 
					// stack. 
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This function is only called from LuaWrapper internally. 
 | 
				
			||||||
 | 
					inline void luaW_registerfuncs(lua_State* L, const luaL_Reg defaulttable[], const luaL_Reg table[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // ... T
 | 
				
			||||||
 | 
					#if LUA_VERSION_NUM > 501
 | 
				
			||||||
 | 
					    if (defaulttable)
 | 
				
			||||||
 | 
					        luaL_setfuncs(L, defaulttable, 0); // ... T
 | 
				
			||||||
 | 
					    if (table)
 | 
				
			||||||
 | 
					        luaL_setfuncs(L, table, 0); // ... T
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					    if (defaulttable)
 | 
				
			||||||
 | 
					        luaL_register(L, NULL, defaulttable); // ... T
 | 
				
			||||||
 | 
					    if (table)
 | 
				
			||||||
 | 
					        luaL_register(L, NULL, table); // ... T
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Initializes the LuaWrapper tables used to track internal state. 
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This function is only called from LuaWrapper internally. 
 | 
				
			||||||
 | 
					inline void luaW_initialize(lua_State* L)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // Ensure that the LuaWrapper table is set up
 | 
				
			||||||
 | 
					    lua_getfield(L, LUA_REGISTRYINDEX, LUAW_WRAPPER_KEY); // ... LuaWrapper
 | 
				
			||||||
 | 
					    if (lua_isnil(L, -1))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        lua_newtable(L); // ... nil {}
 | 
				
			||||||
 | 
					        lua_pushvalue(L, -1); // ... nil {} {}
 | 
				
			||||||
 | 
					        lua_setfield(L, LUA_REGISTRYINDEX, LUAW_WRAPPER_KEY); // ... nil LuaWrapper
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // Create a storage table        
 | 
				
			||||||
 | 
					        lua_newtable(L); // ... LuaWrapper nil {}
 | 
				
			||||||
 | 
					        lua_setfield(L, -2, LUAW_STORAGE_KEY); // ... nil LuaWrapper
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // Create a holds table
 | 
				
			||||||
 | 
					        lua_newtable(L); // ... LuaWrapper {}
 | 
				
			||||||
 | 
					        lua_setfield(L, -2, LUAW_HOLDS_KEY); // ... nil LuaWrapper
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Create a cache table, with weak values so that the userdata will not
 | 
				
			||||||
 | 
					        // be ref counted
 | 
				
			||||||
 | 
					        lua_newtable(L); // ... nil LuaWrapper {}
 | 
				
			||||||
 | 
					        lua_setfield(L, -2, LUAW_CACHE_KEY); // ... nil LuaWrapper
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        lua_newtable(L); // ... nil LuaWrapper {}
 | 
				
			||||||
 | 
					        lua_pushstring(L, "v"); // ... nil LuaWrapper {} "v"
 | 
				
			||||||
 | 
					        lua_setfield(L, -2, "__mode"); // ... nil LuaWrapper {}
 | 
				
			||||||
 | 
					        lua_setfield(L, -2, LUAW_CACHE_METATABLE_KEY); // ... nil LuaWrapper
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        lua_pop(L, 1); // ... nil
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    lua_pop(L, 1); // ...
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Run luaW_register or luaW_setfuncs to create a table and metatable for your
 | 
				
			||||||
 | 
					// class.  These functions create a table with filled with the function from
 | 
				
			||||||
 | 
					// the table argument in addition to the functions new and build (This is
 | 
				
			||||||
 | 
					// generally for things you think of as static methods in C++). The given
 | 
				
			||||||
 | 
					// metatable argument becomes a metatable for each object of your class. These
 | 
				
			||||||
 | 
					// can be thought of as member functions or methods.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// You may also supply constructors and destructors for classes that do not
 | 
				
			||||||
 | 
					// have a default constructor or that require special set up or tear down. You
 | 
				
			||||||
 | 
					// may specify NULL as the constructor, which means that you will not be able
 | 
				
			||||||
 | 
					// to call the new function on your class table. You will need to manually push
 | 
				
			||||||
 | 
					// objects from C++. By default, the default constructor is used to create
 | 
				
			||||||
 | 
					// objects and a simple call to delete is used to destroy them.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// By default LuaWrapper uses the address of C++ object to identify unique
 | 
				
			||||||
 | 
					// objects. In some cases this is not desired, such as in the case of
 | 
				
			||||||
 | 
					// shared_ptrs. Two shared_ptrs may themselves have unique locations in memory
 | 
				
			||||||
 | 
					// but still represent the same object. For cases like that, you may specify an
 | 
				
			||||||
 | 
					// identifier function which is responsible for pushing a key representing your
 | 
				
			||||||
 | 
					// object on to the stack.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// luaW_register will set table as the new value of the global of the given
 | 
				
			||||||
 | 
					// name. luaW_setfuncs is identical to luaW_register, but it does not set the
 | 
				
			||||||
 | 
					// table globally.  As with luaL_register and luaL_setfuncs, both funcstions
 | 
				
			||||||
 | 
					// leave the new table on the top of the stack.
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					void luaW_setfuncs(lua_State* L, const char* classname, const luaL_Reg* table, const luaL_Reg* metatable, T* (*allocator)(lua_State*) = luaW_defaultallocator<T>, void (*deallocator)(lua_State*, T*) = luaW_defaultdeallocator<T>, void (*identifier)(lua_State*, T*) = luaW_defaultidentifier<T>)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    luaW_initialize(L);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    LuaWrapper<T>::classname = classname;
 | 
				
			||||||
 | 
					    LuaWrapper<T>::identifier = identifier;
 | 
				
			||||||
 | 
					    LuaWrapper<T>::allocator = allocator;
 | 
				
			||||||
 | 
					    LuaWrapper<T>::deallocator = deallocator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const luaL_Reg defaulttable[] =
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        { "new", luaW_new<T> },
 | 
				
			||||||
 | 
					        { NULL, NULL }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    const luaL_Reg defaultmetatable[] = 
 | 
				
			||||||
 | 
					    { 
 | 
				
			||||||
 | 
					        { "__index", luaW_index<T> }, 
 | 
				
			||||||
 | 
					        { "__newindex", luaW_newindex<T> }, 
 | 
				
			||||||
 | 
					        { "__gc", luaW_gc<T> }, 
 | 
				
			||||||
 | 
					        { NULL, NULL } 
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Set up per-type tables
 | 
				
			||||||
 | 
					    lua_getfield(L, LUA_REGISTRYINDEX, LUAW_WRAPPER_KEY); // ... LuaWrapper
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    lua_getfield(L, -1, LUAW_STORAGE_KEY); // ... LuaWrapper LuaWrapper.storage
 | 
				
			||||||
 | 
					    lua_newtable(L); // ... LuaWrapper LuaWrapper.storage {}
 | 
				
			||||||
 | 
					    lua_setfield(L, -2, LuaWrapper<T>::classname); // ... LuaWrapper LuaWrapper.storage
 | 
				
			||||||
 | 
					    lua_pop(L, 1); // ... LuaWrapper
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    lua_getfield(L, -1, LUAW_HOLDS_KEY); // ... LuaWrapper LuaWrapper.holds
 | 
				
			||||||
 | 
					    lua_newtable(L); // ... LuaWrapper LuaWrapper.holds {}
 | 
				
			||||||
 | 
					    lua_setfield(L, -2, LuaWrapper<T>::classname); // ... LuaWrapper LuaWrapper.holds
 | 
				
			||||||
 | 
					    lua_pop(L, 1); // ... LuaWrapper
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    lua_getfield(L, -1, LUAW_CACHE_KEY); // ... LuaWrapper LuaWrapper.cache
 | 
				
			||||||
 | 
					    lua_newtable(L); // ... LuaWrapper LuaWrapper.cache {}
 | 
				
			||||||
 | 
					    luaW_wrapperfield<T>(L, LUAW_CACHE_METATABLE_KEY); // ... LuaWrapper LuaWrapper.cache {} cmt
 | 
				
			||||||
 | 
					    lua_setmetatable(L, -2); // ... LuaWrapper LuaWrapper.cache {}
 | 
				
			||||||
 | 
					    lua_setfield(L, -2, LuaWrapper<T>::classname); // ... LuaWrapper LuaWrapper.cache
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    lua_pop(L, 2); // ...
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // Open table
 | 
				
			||||||
 | 
					    lua_newtable(L); // ... T
 | 
				
			||||||
 | 
					    luaW_registerfuncs(L, allocator ? defaulttable : NULL, table); // ... T
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Open metatable, set up extends table
 | 
				
			||||||
 | 
					    luaL_newmetatable(L, classname); // ... T mt
 | 
				
			||||||
 | 
					    lua_newtable(L); // ... T mt {}
 | 
				
			||||||
 | 
					    lua_setfield(L, -2, LUAW_EXTENDS_KEY); // ... T mt
 | 
				
			||||||
 | 
					    luaW_registerfuncs(L, defaultmetatable, metatable); // ... T mt
 | 
				
			||||||
 | 
					    lua_setfield(L, -2, "metatable"); // ... T
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					void luaW_register(lua_State* L, const char* classname, const luaL_Reg* table, const luaL_Reg* metatable, T* (*allocator)(lua_State*) = luaW_defaultallocator<T>, void (*deallocator)(lua_State*, T*) = luaW_defaultdeallocator<T>, void (*identifier)(lua_State*, T*) = luaW_defaultidentifier<T>)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    luaW_setfuncs(L, classname, table, metatable, allocator, deallocator, identifier); // ... T
 | 
				
			||||||
 | 
					    lua_pushvalue(L, -1); // ... T T
 | 
				
			||||||
 | 
					    lua_setglobal(L, classname); // ... T
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// luaW_extend is used to declare that class T inherits from class U. All
 | 
				
			||||||
 | 
					// functions in the base class will be available to the derived class (except
 | 
				
			||||||
 | 
					// when they share a function name, in which case the derived class's function
 | 
				
			||||||
 | 
					// wins). This also allows luaW_to<T> to cast your object apropriately, as
 | 
				
			||||||
 | 
					// casts straight through a void pointer do not work.
 | 
				
			||||||
 | 
					template <typename T, typename U>
 | 
				
			||||||
 | 
					void luaW_extend(lua_State* L)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if(!LuaWrapper<T>::classname)
 | 
				
			||||||
 | 
					        luaL_error(L, "attempting to call extend on a type that has not been registered");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(!LuaWrapper<U>::classname)
 | 
				
			||||||
 | 
					        luaL_error(L, "attempting to extend %s by a type that has not been registered", LuaWrapper<T>::classname);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    LuaWrapper<T>::cast = luaW_cast<T, U>;
 | 
				
			||||||
 | 
					    LuaWrapper<T>::identifier = luaW_identify<T, U>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    luaL_getmetatable(L, LuaWrapper<T>::classname); // mt
 | 
				
			||||||
 | 
					    luaL_getmetatable(L, LuaWrapper<U>::classname); // mt emt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Point T's metatable __index at U's metatable for inheritance
 | 
				
			||||||
 | 
					    lua_newtable(L); // mt emt {}
 | 
				
			||||||
 | 
					    lua_pushvalue(L, -2); // mt emt {} emt
 | 
				
			||||||
 | 
					    lua_setfield(L, -2, "__index"); // mt emt {}
 | 
				
			||||||
 | 
					    lua_setmetatable(L, -3); // mt emt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Set up per-type tables to point at parent type
 | 
				
			||||||
 | 
					    lua_getfield(L, LUA_REGISTRYINDEX, LUAW_WRAPPER_KEY); // ... LuaWrapper
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    lua_getfield(L, -1, LUAW_STORAGE_KEY); // ... LuaWrapper LuaWrapper.storage
 | 
				
			||||||
 | 
					    lua_getfield(L, -1, LuaWrapper<U>::classname); // ... LuaWrapper LuaWrapper.storage U
 | 
				
			||||||
 | 
					    lua_setfield(L, -2, LuaWrapper<T>::classname); // ... LuaWrapper LuaWrapper.storage
 | 
				
			||||||
 | 
					    lua_pop(L, 1); // ... LuaWrapper
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    lua_getfield(L, -1, LUAW_HOLDS_KEY); // ... LuaWrapper LuaWrapper.holds
 | 
				
			||||||
 | 
					    lua_getfield(L, -1, LuaWrapper<U>::classname); // ... LuaWrapper LuaWrapper.holds U
 | 
				
			||||||
 | 
					    lua_setfield(L, -2, LuaWrapper<T>::classname); // ... LuaWrapper LuaWrapper.holds
 | 
				
			||||||
 | 
					    lua_pop(L, 1); // ... LuaWrapper
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    lua_getfield(L, -1, LUAW_CACHE_KEY); // ... LuaWrapper LuaWrapper.cache
 | 
				
			||||||
 | 
					    lua_getfield(L, -1, LuaWrapper<U>::classname); // ... LuaWrapper LuaWrapper.cache U
 | 
				
			||||||
 | 
					    lua_setfield(L, -2, LuaWrapper<T>::classname); // ... LuaWrapper LuaWrapper.cache
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    lua_pop(L, 2); // ...
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // Make a list of all types that inherit from U, for type checking
 | 
				
			||||||
 | 
					    lua_getfield(L, -2, LUAW_EXTENDS_KEY); // mt emt mt.extends
 | 
				
			||||||
 | 
					    lua_pushvalue(L, -2); // mt emt mt.extends emt
 | 
				
			||||||
 | 
					    lua_setfield(L, -2, LuaWrapper<U>::classname); // mt emt mt.extends
 | 
				
			||||||
 | 
					    lua_getfield(L, -2, LUAW_EXTENDS_KEY); // mt emt mt.extends emt.extends
 | 
				
			||||||
 | 
					    for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // mt emt mt.extends emt.extends k v
 | 
				
			||||||
 | 
					        lua_pushvalue(L, -2); // mt emt mt.extends emt.extends k v k
 | 
				
			||||||
 | 
					        lua_pushvalue(L, -2); // mt emt mt.extends emt.extends k v k
 | 
				
			||||||
 | 
					        lua_rawset(L, -6); // mt emt mt.extends emt.extends k v
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    lua_pop(L, 4); // mt emt
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2010-2013 Alexander Ames
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // LUA_WRAPPER_H_
 | 
				
			||||||
							
								
								
									
										714
									
								
								luarocks/luawrapperutil.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										714
									
								
								luarocks/luawrapperutil.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,714 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2010-2013 Alexander Ames
 | 
				
			||||||
 | 
					 * Alexander.Ames@gmail.com
 | 
				
			||||||
 | 
					 * See Copyright Notice at the end of this file
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// API Summary:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This is a set of utility functions that add to the functionalit of
 | 
				
			||||||
 | 
					// LuaWrapper. Over time I found myself repeating a few patterns, such as
 | 
				
			||||||
 | 
					// writing many trvial getter and setter functions, and wanting pass ownership
 | 
				
			||||||
 | 
					// of one object to another and have the Lua script properly handle that case.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This file contains the additional functions that I've added but that do
 | 
				
			||||||
 | 
					// not really belong in the core API.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef LUAWRAPPERUTILS_HPP_
 | 
				
			||||||
 | 
					#define LUAWRAPPERUTILS_HPP_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "luawrapper.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef LUAW_NO_CXX11
 | 
				
			||||||
 | 
					#include <type_traits>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef LUAW_STD
 | 
				
			||||||
 | 
					#define LUAW_STD std
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// A set of templated luaL_check and lua_push functions for use in the getters
 | 
				
			||||||
 | 
					// and setters below
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// It is often useful to override luaU_check, luaU_to and/or luaU_push to
 | 
				
			||||||
 | 
					// operate on your own simple types rather than register your type with
 | 
				
			||||||
 | 
					// LuaWrapper, especially with small objects.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename U, typename = void>
 | 
				
			||||||
 | 
					struct luaU_Impl
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    static U    luaU_check(lua_State* L, int      index);
 | 
				
			||||||
 | 
					    static U    luaU_to   (lua_State* L, int      index);
 | 
				
			||||||
 | 
					    static void luaU_push (lua_State* L, const U& value);
 | 
				
			||||||
 | 
					    static void luaU_push (lua_State* L,       U& value);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename U> U    luaU_check(lua_State* L, int      index) { return luaU_Impl<U>::luaU_check(L, index); }
 | 
				
			||||||
 | 
					template<typename U> U    luaU_to   (lua_State* L, int      index) { return luaU_Impl<U>::luaU_to   (L, index); }
 | 
				
			||||||
 | 
					template<typename U> void luaU_push (lua_State* L, const U& value) {        luaU_Impl<U>::luaU_push (L, value); }
 | 
				
			||||||
 | 
					template<typename U> void luaU_push (lua_State* L,       U& value) {        luaU_Impl<U>::luaU_push (L, value); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					////////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This is slightly different than the previous three functions in that you
 | 
				
			||||||
 | 
					// shouldn't need to write your own version of it, since it uses luaU_check
 | 
				
			||||||
 | 
					// automatically.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					template<typename U>
 | 
				
			||||||
 | 
					U luaU_opt(lua_State* L, int index, const U& fallback = U())
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (lua_isnil(L, index))
 | 
				
			||||||
 | 
					        return fallback;
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        return luaU_Impl<U>::luaU_check(L, index);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<>
 | 
				
			||||||
 | 
					struct luaU_Impl<bool>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    static bool luaU_check(lua_State* L, int         index) { return lua_toboolean  (L, index) != 0; }
 | 
				
			||||||
 | 
					    static bool luaU_to   (lua_State* L, int         index) { return lua_toboolean  (L, index) != 0; }
 | 
				
			||||||
 | 
					    static void luaU_push (lua_State* L, const bool& value) {        lua_pushboolean(L, value); }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<>
 | 
				
			||||||
 | 
					struct luaU_Impl<const char*>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    static const char* luaU_check(lua_State* L, int                index) { return luaL_checkstring(L, index); }
 | 
				
			||||||
 | 
					    static const char* luaU_to   (lua_State* L, int                index) { return lua_tostring    (L, index); }
 | 
				
			||||||
 | 
					    static void        luaU_push (lua_State* L, const char* const& value) {        lua_pushstring  (L, value); }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<>
 | 
				
			||||||
 | 
					struct luaU_Impl<unsigned int>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    static unsigned int luaU_check(lua_State* L, int                 index) { return static_cast<unsigned int>(luaL_checkinteger(L, index)); }
 | 
				
			||||||
 | 
					    static unsigned int luaU_to   (lua_State* L, int                 index) { return static_cast<unsigned int>(lua_tointeger    (L, index)); }
 | 
				
			||||||
 | 
					    static void         luaU_push (lua_State* L, const unsigned int& value) {                                  lua_pushinteger  (L, value); }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<>
 | 
				
			||||||
 | 
					struct luaU_Impl<int>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    static int  luaU_check(lua_State* L, int        index) { return static_cast<int>(luaL_checkinteger(L, index)); }
 | 
				
			||||||
 | 
					    static int  luaU_to   (lua_State* L, int        index) { return static_cast<int>(lua_tointeger    (L, index)); }
 | 
				
			||||||
 | 
					    static void luaU_push (lua_State* L, const int& value) {                         lua_pushinteger  (L, value); }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<>
 | 
				
			||||||
 | 
					struct luaU_Impl<unsigned char>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    static unsigned char luaU_check(lua_State* L, int                  index) { return static_cast<unsigned char>(luaL_checkinteger(L, index)); }
 | 
				
			||||||
 | 
					    static unsigned char luaU_to   (lua_State* L, int                  index) { return static_cast<unsigned char>(lua_tointeger    (L, index)); }
 | 
				
			||||||
 | 
					    static void          luaU_push (lua_State* L, const unsigned char& value) {                                   lua_pushinteger  (L, value); }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<>
 | 
				
			||||||
 | 
					struct luaU_Impl<char>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    static char luaU_check(lua_State* L, int         index) { return static_cast<char>(luaL_checkinteger(L, index)); }
 | 
				
			||||||
 | 
					    static char luaU_to   (lua_State* L, int         index) { return static_cast<char>(lua_tointeger    (L, index)); }
 | 
				
			||||||
 | 
					    static void luaU_push (lua_State* L, const char& value) {                          lua_pushinteger  (L, value); }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<>
 | 
				
			||||||
 | 
					struct luaU_Impl<float>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    static float luaU_check(lua_State* L, int          index) { return static_cast<float>(luaL_checknumber(L, index)); }
 | 
				
			||||||
 | 
					    static float luaU_to   (lua_State* L, int          index) { return static_cast<float>(lua_tonumber    (L, index)); }
 | 
				
			||||||
 | 
					    static void  luaU_push (lua_State* L, const float& value) {                           lua_pushnumber  (L, value); }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<>
 | 
				
			||||||
 | 
					struct luaU_Impl<double>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    static double luaU_check(lua_State* L, int           index) { return static_cast<double>(luaL_checknumber(L, index)); }
 | 
				
			||||||
 | 
					    static double luaU_to   (lua_State* L, int           index) { return static_cast<double>(lua_tonumber    (L, index)); }
 | 
				
			||||||
 | 
					    static void   luaU_push (lua_State* L, const double& value) {                            lua_pushnumber  (L, value); }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef LUAW_NO_CXX11
 | 
				
			||||||
 | 
					template<typename T>
 | 
				
			||||||
 | 
					struct luaU_Impl<T, typename LUAW_STD::enable_if<LUAW_STD::is_enum<T>::value>::type>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    static T    luaU_check(lua_State* L, int      index) { return static_cast<T>(luaL_checkinteger  (L, index)); }
 | 
				
			||||||
 | 
					    static T    luaU_to   (lua_State* L, int      index) { return static_cast<T>(lua_tointeger      (L, index)); }
 | 
				
			||||||
 | 
					    static void luaU_push (lua_State* L, const T& value) {        lua_pushnumber(L, static_cast<int>(value   )); }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename T>
 | 
				
			||||||
 | 
					struct luaU_Impl<T*, typename LUAW_STD::enable_if<LUAW_STD::is_class<T>::value>::type>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    static T*   luaU_check( lua_State* L, int index) { return luaW_check<T>(L, index); }
 | 
				
			||||||
 | 
					    static T*   luaU_to   ( lua_State* L, int index) { return luaW_to   <T>(L, index); }
 | 
				
			||||||
 | 
					    static void luaU_push ( lua_State* L, T*& value) {        luaW_push <T>(L, value); }
 | 
				
			||||||
 | 
					    static void luaU_push ( lua_State* L, T*  value) {        luaW_push <T>(L, value); }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					///////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// These are just some functions I've always felt should exist
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename U>
 | 
				
			||||||
 | 
					inline U luaU_getfield(lua_State* L, int index, const char* field)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#ifndef LUAW_NO_CXX11
 | 
				
			||||||
 | 
					    static_assert(!std::is_same<U, const char*>::value, 
 | 
				
			||||||
 | 
					        "luaU_getfield is not safe to use on const char*'s. (The string will be popped from the stack.)");
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    lua_getfield(L, index, field);
 | 
				
			||||||
 | 
					    U val = luaU_to<U>(L, -1);
 | 
				
			||||||
 | 
					    lua_pop(L, 1);
 | 
				
			||||||
 | 
					    return val;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename U>
 | 
				
			||||||
 | 
					inline U luaU_checkfield(lua_State* L, int index, const char* field)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#ifndef LUAW_NO_CXX11
 | 
				
			||||||
 | 
					    static_assert(!std::is_same<U, const char*>::value, 
 | 
				
			||||||
 | 
					        "luaU_checkfield is not safe to use on const char*'s. (The string will be popped from the stack.)");
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    lua_getfield(L, index, field);
 | 
				
			||||||
 | 
					    U val = luaU_check<U>(L, -1);
 | 
				
			||||||
 | 
					    lua_pop(L, 1);
 | 
				
			||||||
 | 
					    return val;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename U>
 | 
				
			||||||
 | 
					inline void luaU_setfield(lua_State* L, int index, const char* field, U val)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    luaU_push<U>(L, val);
 | 
				
			||||||
 | 
					    lua_setfield(L, luaW_correctindex(L, index, 1), field);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					///////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// A set of trivial getter and setter templates. These templates are designed
 | 
				
			||||||
 | 
					// to call trivial getters or setters.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// There are four forms:
 | 
				
			||||||
 | 
					//  1. Getting or setting a public member variable that is of a primitive type
 | 
				
			||||||
 | 
					//  2. Getting or setting a public member variable that is a pointer to an
 | 
				
			||||||
 | 
					//     object
 | 
				
			||||||
 | 
					//  3. Getting or setting a private member variable that is of a primitive type
 | 
				
			||||||
 | 
					//     through a getter or setter
 | 
				
			||||||
 | 
					//  3. Getting or setting a private member variable that is is a pointer to an
 | 
				
			||||||
 | 
					//     object through a getter or setter
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// The interface to all of them is the same however. In addition to plain
 | 
				
			||||||
 | 
					// getter and setter functions, there is a getset which does both - if an
 | 
				
			||||||
 | 
					// argument is supplied it attempts to set the value, and in either case it
 | 
				
			||||||
 | 
					// returns the value. In your lua table declaration in C++ rather than write
 | 
				
			||||||
 | 
					// individiual wrappers for each getter and setter you may do the following:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// static luaL_reg Foo_metatable[] =
 | 
				
			||||||
 | 
					// {
 | 
				
			||||||
 | 
					//     { "GetBar", luaU_get<Foo, bool, &Widget::GetBar> },
 | 
				
			||||||
 | 
					//     { "SetBar", luaU_set<Foo, bool, &Widget::SetBar> },
 | 
				
			||||||
 | 
					//     { "Bar", luaU_getset<Foo, bool, &Widget::GetBar, &Widget::SetBar> },
 | 
				
			||||||
 | 
					//     { NULL, NULL }
 | 
				
			||||||
 | 
					// }
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Getters and setters must have one of the following signatures:
 | 
				
			||||||
 | 
					//    void T::Setter(U value);
 | 
				
			||||||
 | 
					//    void T::Setter(U* value);
 | 
				
			||||||
 | 
					//    void T::Setter(const U& value);
 | 
				
			||||||
 | 
					//    U Getter() const;
 | 
				
			||||||
 | 
					//    U* Getter() const;
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// In this example, the variable Foo::bar is private and so it is accessed
 | 
				
			||||||
 | 
					// through getter and setter functions. If Foo::bar were public, it could be
 | 
				
			||||||
 | 
					// accessed directly, like so:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// static luaL_reg Foo_metatable[] =
 | 
				
			||||||
 | 
					// {
 | 
				
			||||||
 | 
					//     { "GetBar", luaU_get<Foo, bool, &Widget::bar> },
 | 
				
			||||||
 | 
					//     { "SetBar", luaU_set<Foo, bool, &Widget::bar> },
 | 
				
			||||||
 | 
					//     { "Bar", luaU_getset<Foo, bool, &Widget::bar> },
 | 
				
			||||||
 | 
					// }
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// In a Lua script, you can now use foo:GetBar(), foo:SetBar() and foo:Bar()
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T, typename U, U T::*Member>
 | 
				
			||||||
 | 
					int luaU_get(lua_State* L)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    T* obj = luaW_check<T>(L, 1);
 | 
				
			||||||
 | 
					    luaU_push<U>(L, obj->*Member);
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T, typename U, U* T::*Member>
 | 
				
			||||||
 | 
					int luaU_get(lua_State* L)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    T* obj = luaW_check<T>(L, 1);
 | 
				
			||||||
 | 
					    luaW_push<U>(L, obj->*Member);
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T, typename U, U (T::*Getter)() const>
 | 
				
			||||||
 | 
					int luaU_get(lua_State* L)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    T* obj = luaW_check<T>(L, 1);
 | 
				
			||||||
 | 
					    luaU_push<U>(L, (obj->*Getter)());
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T, typename U, const U& (T::*Getter)() const>
 | 
				
			||||||
 | 
					int luaU_get(lua_State* L)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    T* obj = luaW_check<T>(L, 1);
 | 
				
			||||||
 | 
					    luaU_push<U>(L, (obj->*Getter)());
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T, typename U, U* (T::*Getter)() const>
 | 
				
			||||||
 | 
					int luaU_get(lua_State* L)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    T* obj = luaW_check<T>(L, 1);
 | 
				
			||||||
 | 
					    luaW_push<U>(L, (obj->*Getter)());
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T, typename U, U T::*Member>
 | 
				
			||||||
 | 
					int luaU_set(lua_State* L)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    T* obj = luaW_check<T>(L, 1);
 | 
				
			||||||
 | 
					    if (obj)
 | 
				
			||||||
 | 
					        obj->*Member = luaU_check<U>(L, 2);
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T, typename U, U* T::*Member>
 | 
				
			||||||
 | 
					int luaU_set(lua_State* L)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    T* obj = luaW_check<T>(L, 1);
 | 
				
			||||||
 | 
					    if (obj)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        U* member = luaW_opt<U>(L, 2);
 | 
				
			||||||
 | 
					        obj->*Member = member;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T, typename U, const U* T::*Member>
 | 
				
			||||||
 | 
					int luaU_set(lua_State* L)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    T* obj = luaW_check<T>(L, 1);
 | 
				
			||||||
 | 
					    if (obj)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        U* member = luaW_opt<U>(L, 2);
 | 
				
			||||||
 | 
					        obj->*Member = member;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T, typename U, const U* T::*Member>
 | 
				
			||||||
 | 
					int luaU_setandrelease(lua_State* L)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    T* obj = luaW_check<T>(L, 1);
 | 
				
			||||||
 | 
					    if (obj)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        U* member = luaW_opt<U>(L, 2);
 | 
				
			||||||
 | 
					        obj->*Member = member;
 | 
				
			||||||
 | 
					        if (member)
 | 
				
			||||||
 | 
					            luaW_release<U>(L, member);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T, typename U, void (T::*Setter)(U)>
 | 
				
			||||||
 | 
					int luaU_set(lua_State* L)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    T* obj = luaW_check<T>(L, 1);
 | 
				
			||||||
 | 
					    if (obj)
 | 
				
			||||||
 | 
					        (obj->*Setter)(luaU_check<U>(L, 2));
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T, typename U, void (T::*Setter)(const U&)>
 | 
				
			||||||
 | 
					int luaU_set(lua_State* L)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    T* obj = luaW_check<T>(L, 1);
 | 
				
			||||||
 | 
					    if (obj)
 | 
				
			||||||
 | 
					        (obj->*Setter)(luaU_check<U>(L, 2));
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T, typename U, void (T::*Setter)(U*)>
 | 
				
			||||||
 | 
					int luaU_set(lua_State* L)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    T* obj = luaW_check<T>(L, 1);
 | 
				
			||||||
 | 
					    if (obj)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        U* member = luaW_opt<U>(L, 2);
 | 
				
			||||||
 | 
					        (obj->*Setter)(member);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T, typename U, void (T::*Setter)(U*)>
 | 
				
			||||||
 | 
					int luaU_setandrelease(lua_State* L)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    T* obj = luaW_check<T>(L, 1);
 | 
				
			||||||
 | 
					    if (obj)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        U* member = luaW_opt<U>(L, 2);
 | 
				
			||||||
 | 
					        (obj->*Setter)(member);
 | 
				
			||||||
 | 
					        if (member)
 | 
				
			||||||
 | 
					            luaW_release<U>(L, member);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T, typename U, U T::*Member>
 | 
				
			||||||
 | 
					int luaU_getset(lua_State* L)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    T* obj = luaW_check<T>(L, 1);
 | 
				
			||||||
 | 
					    if (obj && lua_gettop(L) >= 2)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        obj->*Member = luaU_check<U>(L, 2);
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        luaU_push<U>(L, obj->*Member);
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T, typename U, U* T::*Member>
 | 
				
			||||||
 | 
					int luaU_getset(lua_State* L)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    T* obj = luaW_check<T>(L, 1);
 | 
				
			||||||
 | 
					    if (obj && lua_gettop(L) >= 2)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        U* member = luaW_opt<U>(L, 2);
 | 
				
			||||||
 | 
					        obj->*Member = member;
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        luaW_push<U>(L, obj->*Member);
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T, typename U, U* T::*Member>
 | 
				
			||||||
 | 
					int luaU_getsetandrelease(lua_State* L)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    T* obj = luaW_check<T>(L, 1);
 | 
				
			||||||
 | 
					    if (obj && lua_gettop(L) >= 2)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        U* member = luaW_opt<U>(L, 2);
 | 
				
			||||||
 | 
					        obj->*Member = member;
 | 
				
			||||||
 | 
					        if (member)
 | 
				
			||||||
 | 
					            luaW_release<U>(L, member);
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        luaW_push<U>(L, obj->*Member);
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T, typename U, U (T::*Getter)() const, void (T::*Setter)(U)>
 | 
				
			||||||
 | 
					int luaU_getset(lua_State* L)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    T* obj = luaW_check<T>(L, 1);
 | 
				
			||||||
 | 
					    if (obj && lua_gettop(L) >= 2)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        (obj->*Setter)(luaU_check<U>(L, 2));
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        luaU_push<U>(L, (obj->*Getter)());
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T, typename U, U (T::*Getter)() const, void (T::*Setter)(const U&)>
 | 
				
			||||||
 | 
					int luaU_getset(lua_State* L)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    T* obj = luaW_check<T>(L, 1);
 | 
				
			||||||
 | 
					    if (obj && lua_gettop(L) >= 2)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        (obj->*Setter)(luaU_check<U>(L, 2));
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        luaU_push<U>(L, (obj->*Getter)());
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T, typename U, const U& (T::*Getter)() const, void (T::*Setter)(const U&)>
 | 
				
			||||||
 | 
					int luaU_getset(lua_State* L)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    T* obj = luaW_check<T>(L, 1);
 | 
				
			||||||
 | 
					    if (obj && lua_gettop(L) >= 2)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        (obj->*Setter)(luaU_check<U>(L, 2));
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        luaU_push<U>(L, (obj->*Getter)());
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T, typename U, U* (T::*Getter)() const, void (T::*Setter)(U*)>
 | 
				
			||||||
 | 
					int luaU_getset(lua_State* L)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    T* obj = luaW_check<T>(L, 1);
 | 
				
			||||||
 | 
					    if (obj && lua_gettop(L) >= 2)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        U* member = luaW_opt<U>(L, 2);
 | 
				
			||||||
 | 
					        (obj->*Setter)(member);
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        luaW_push<U>(L, (obj->*Getter)());
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template <typename T, typename U, U* (T::*Getter)() const, void (T::*Setter)(U*)>
 | 
				
			||||||
 | 
					int luaU_getsetandrelease(lua_State* L)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    T* obj = luaW_check<T>(L, 1);
 | 
				
			||||||
 | 
					    if (obj && lua_gettop(L) >= 2)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        U* member = luaW_opt<U>(L, 2);
 | 
				
			||||||
 | 
					        (obj->*Setter)(member);
 | 
				
			||||||
 | 
					        if (member)
 | 
				
			||||||
 | 
					            luaW_release<U>(L, member);
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        luaW_push<U>(L, (obj->*Getter)());
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !defined(_WIN32) && !defined(LUAW_NO_CXX11)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					///////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// luaU_func is a special macro that expands into a simple function wrapper.
 | 
				
			||||||
 | 
					// Unlike the getter setters above, you merely need to name the function you
 | 
				
			||||||
 | 
					// would like to wrap.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// For example,
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// struct Foo
 | 
				
			||||||
 | 
					// {
 | 
				
			||||||
 | 
					//     int DoSomething(int, const char*);
 | 
				
			||||||
 | 
					// };
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// static luaL_reg Foo_metatable[] =
 | 
				
			||||||
 | 
					// {
 | 
				
			||||||
 | 
					//     { "DoSomething", luaU_func(&Foo::DoSomething) },
 | 
				
			||||||
 | 
					//     { NULL, NULL }
 | 
				
			||||||
 | 
					// }
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This macro will expand based on the function signature of Foo::DoSomething
 | 
				
			||||||
 | 
					// In this example, it would expand into the following wrapper:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//     luaU_push(luaW_check<T>(L, 1)->DoSomething(luaU_check<int>(L, 2), luaU_check<const char*>(L, 3)));
 | 
				
			||||||
 | 
					//     return 1;
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// In this example there is only one member function called DoSomething. In some 
 | 
				
			||||||
 | 
					// cases there may be multiple overrides for a function. For those cases, an 
 | 
				
			||||||
 | 
					// additional macro has been provided, luaU_funcsig, which takes the entire
 | 
				
			||||||
 | 
					// function signature. The arguments to the macro reflect the order they would
 | 
				
			||||||
 | 
					// appear in the function signature: return type, type name, function name, and
 | 
				
			||||||
 | 
					// finally a list of all the argument types. For example:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// struct Foo
 | 
				
			||||||
 | 
					// {
 | 
				
			||||||
 | 
					//     int DoSomething (const char*);
 | 
				
			||||||
 | 
					//     int DoSomething (const char*, int);
 | 
				
			||||||
 | 
					// };
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// const struct luaL_Reg Foo_metatable[] =
 | 
				
			||||||
 | 
					// {
 | 
				
			||||||
 | 
					//     {"DoSomething1", luaU_funcsig(int, Foo, DoSomething, const char*)) },
 | 
				
			||||||
 | 
					//     {"DoSomething1", luaU_funcsig(int, Foo, DoSomething, const char*, int)) },
 | 
				
			||||||
 | 
					//     { NULL, NULL }
 | 
				
			||||||
 | 
					// };
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// These macros and it's underlying templates are somewhat experimental and some
 | 
				
			||||||
 | 
					// refinements are probably needed.  There are cases where it does not
 | 
				
			||||||
 | 
					// currently work and I expect some changes can be made to refine its behavior.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define luaU_func(memberfunc) &luaU_FuncWrapper<decltype(memberfunc),memberfunc>::call
 | 
				
			||||||
 | 
					#define luaU_funcsig(returntype, type, funcname, ...) luaU_func(static_cast<returntype (type::*)(__VA_ARGS__)>(&type::funcname))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<int... ints> struct luaU_IntPack { };
 | 
				
			||||||
 | 
					template<int start, int count, int... tail> struct luaU_MakeIntRangeType { typedef typename luaU_MakeIntRangeType<start, count-1, start+count-1, tail...>::type type; };
 | 
				
			||||||
 | 
					template<int start, int... tail> struct luaU_MakeIntRangeType<start, 0, tail...> { typedef luaU_IntPack<tail...> type; };
 | 
				
			||||||
 | 
					template<int start, int count> inline typename luaU_MakeIntRangeType<start, count>::type luaU_makeIntRange() { return typename luaU_MakeIntRangeType<start, count>::type(); }
 | 
				
			||||||
 | 
					template<class MemFunPtrType, MemFunPtrType MemberFunc> struct luaU_FuncWrapper;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<class T, class ReturnType, class... Args, ReturnType(T::*MemberFunc)(Args...)>
 | 
				
			||||||
 | 
					struct luaU_FuncWrapper<ReturnType (T::*)(Args...), MemberFunc>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    static int call(lua_State* L)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return callImpl(L, luaU_makeIntRange<2,sizeof...(Args)>());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    template<int... indices>
 | 
				
			||||||
 | 
					    static int callImpl(lua_State* L, luaU_IntPack<indices...>)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        luaU_push<ReturnType>(L, (luaW_check<T>(L, 1)->*MemberFunc)(luaU_check<Args>(L, indices)...));
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					///////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Calls the copy constructor for an object of type T.
 | 
				
			||||||
 | 
					// Arguments may be passed in, in case they're needed for the postconstructor
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// e.g.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// C++:
 | 
				
			||||||
 | 
					// luaL_reg Foo_Metatable[] =
 | 
				
			||||||
 | 
					// {
 | 
				
			||||||
 | 
					//     { "clone", luaU_clone<Foo> },
 | 
				
			||||||
 | 
					//     { NULL, NULL }
 | 
				
			||||||
 | 
					// };
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Lua:
 | 
				
			||||||
 | 
					// foo = Foo.new()
 | 
				
			||||||
 | 
					// foo2 = foo:clone()
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					int luaU_clone(lua_State* L)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // obj ...
 | 
				
			||||||
 | 
					    T* obj = new T(*luaW_check<T>(L, 1));
 | 
				
			||||||
 | 
					    lua_remove(L, 1); // ...
 | 
				
			||||||
 | 
					    int numargs = lua_gettop(L);
 | 
				
			||||||
 | 
					    luaW_push<T>(L, obj); // ... clone
 | 
				
			||||||
 | 
					    luaW_hold<T>(L, obj);
 | 
				
			||||||
 | 
					    luaW_postconstructor<T>(L, numargs);
 | 
				
			||||||
 | 
					    return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					///////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// luaU_build is intended to be used to initialize many values by passing in a
 | 
				
			||||||
 | 
					// table. They keys of the table are used as function names, and values are
 | 
				
			||||||
 | 
					// used as arguments to the function. This is intended to be used on functions
 | 
				
			||||||
 | 
					// that are simple setters.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// For example, if luaU_build is set as the post constructor, you can
 | 
				
			||||||
 | 
					// initialize an object as so:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// f = Foo.new
 | 
				
			||||||
 | 
					// {
 | 
				
			||||||
 | 
					//     X = 10;
 | 
				
			||||||
 | 
					//     Y = 20;
 | 
				
			||||||
 | 
					// }
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// After the object is constructed, luaU_build will do the equivalent of
 | 
				
			||||||
 | 
					// calling f:X(10) and f:Y(20).
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					int luaU_build(lua_State* L)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // obj {}
 | 
				
			||||||
 | 
					    lua_insert(L, -2); // {} obj
 | 
				
			||||||
 | 
					    if (lua_type(L, 1) == LUA_TTABLE)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        for (lua_pushnil(L); lua_next(L, 1); lua_pop(L, 1))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // {} obj k v
 | 
				
			||||||
 | 
					            lua_pushvalue(L, -2); // {} obj k v k
 | 
				
			||||||
 | 
					            lua_gettable(L, -4); // {} obj k v ud[k]
 | 
				
			||||||
 | 
					            lua_pushvalue(L, -4); // {} obj k v ud[k] ud
 | 
				
			||||||
 | 
					            lua_pushvalue(L, -3); // {} obj k v ud[k] ud v
 | 
				
			||||||
 | 
					            lua_call(L, 2, 0); // {} obj k v
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // {} ud
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					///////////////////////////////////////////////////////////////////////////////
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Takes the object of type T at the top of the stack and stores it in on a
 | 
				
			||||||
 | 
					// table with the name storagetable, on the table at the specified index.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// You may manually call luaW_hold and luaW_release to handle pointer
 | 
				
			||||||
 | 
					// ownership, but it is often easier to simply store a Lua userdata on a table
 | 
				
			||||||
 | 
					// that is owned by its parent. This ensures that your object will not be
 | 
				
			||||||
 | 
					// prematurely freed, and that it can only be destoryed after its parent.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// e.g.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Foo* parent = luaW_check<Foo>(L, 1);
 | 
				
			||||||
 | 
					// Bar* child = luaW_check<Bar>(L, 2);
 | 
				
			||||||
 | 
					// if (parent && child)
 | 
				
			||||||
 | 
					// {
 | 
				
			||||||
 | 
					//     luaU_store<Bar>(L, 1, "Children");
 | 
				
			||||||
 | 
					//     parent->AddChild(child);
 | 
				
			||||||
 | 
					// }
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					template <typename T>
 | 
				
			||||||
 | 
					void luaU_store(lua_State* L, int index, const char* storagetable, const char* key = NULL)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // ... store ... obj
 | 
				
			||||||
 | 
					    lua_getfield(L, index, storagetable); // ... store ... obj store.storagetable
 | 
				
			||||||
 | 
					    if (key)
 | 
				
			||||||
 | 
					        lua_pushstring(L, key); // ... store ... obj store.storagetable key
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        LuaWrapper<T>::identifier(L, luaW_to<T>(L, -2)); // ... store ... obj store.storagetable key
 | 
				
			||||||
 | 
					    lua_pushvalue(L, -3); // ... store ... obj store.storagetable key obj
 | 
				
			||||||
 | 
					    lua_settable(L, -3); // ... store ... obj store.storagetable
 | 
				
			||||||
 | 
					    lua_pop(L, 1); // ... store ... obj
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2010-2011 Alexander Ames
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * 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.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // LUAWRAPPERUTILS_HPP_
 | 
				
			||||||
							
								
								
									
										64
									
								
								luarocks/main.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								luarocks/main.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,64 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 *  main.cpp
 | 
				
			||||||
 | 
					 *  Author: Benjamin Sergeant
 | 
				
			||||||
 | 
					 *  Copyright (c) 2020 Machine Zone, Inc. All rights reserved.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern "C"
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    #include "lua.h"
 | 
				
			||||||
 | 
					    #include "lualib.h"
 | 
				
			||||||
 | 
					    #include "lauxlib.h"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "functions.hpp"
 | 
				
			||||||
 | 
					#include "LuaWebSocket.h"
 | 
				
			||||||
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    lua_State* L = luaL_newstate();
 | 
				
			||||||
 | 
					    luaL_openlibs(L);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Functions
 | 
				
			||||||
 | 
					    lua_register(L, "info", lua_info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Objets
 | 
				
			||||||
 | 
					    ix::luaopen_WebSocket(L);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    // Simple version does little error handling
 | 
				
			||||||
 | 
					    // luaL_dofile(L, "echo_client.lua");
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    std::string luaFile("echo_client.lua");
 | 
				
			||||||
 | 
					    int loadStatus = luaL_loadfile(L, luaFile.c_str());
 | 
				
			||||||
 | 
					    if (loadStatus)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        std::cerr << "Error loading " << luaFile << std::endl;
 | 
				
			||||||
 | 
					        std::cerr << lua_tostring(L, -1) << std::endl;
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        std::cout << "loaded " << luaFile << std::endl;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    // Capture lua errors
 | 
				
			||||||
 | 
					    //
 | 
				
			||||||
 | 
					    try
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        lua_call(L, 0, 0);
 | 
				
			||||||
 | 
					        lua_close(L);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    catch (const std::runtime_error& ex)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        lua_close(L);
 | 
				
			||||||
 | 
					        std::cerr << ex.what() << std::endl;
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										4
									
								
								makefile
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								makefile
									
									
									
									
									
								
							@@ -159,6 +159,9 @@ test_no_ssl:
 | 
				
			|||||||
	mkdir -p build && (cd build ; cmake -DCMAKE_BUILD_TYPE=Debug -DUSE_TEST=1 .. ; make -j 4)
 | 
						mkdir -p build && (cd build ; cmake -DCMAKE_BUILD_TYPE=Debug -DUSE_TEST=1 .. ; make -j 4)
 | 
				
			||||||
	(cd test ; python2.7 run.py -r)
 | 
						(cd test ; python2.7 run.py -r)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					luarocks:
 | 
				
			||||||
 | 
						mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_BUILD_TYPE=Debug -DUSE_LUAROCKS=1 .. ; ninja)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ws_test: ws
 | 
					ws_test: ws
 | 
				
			||||||
	(cd ws ; env DEBUG=1 PATH=../ws/build:$$PATH bash test_ws.sh)
 | 
						(cd ws ; env DEBUG=1 PATH=../ws/build:$$PATH bash test_ws.sh)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -185,3 +188,4 @@ doc:
 | 
				
			|||||||
.PHONY: test
 | 
					.PHONY: test
 | 
				
			||||||
.PHONY: build
 | 
					.PHONY: build
 | 
				
			||||||
.PHONY: ws
 | 
					.PHONY: ws
 | 
				
			||||||
 | 
					.PHONY: luarocks
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user