From 8aa635f8c1a1efdd424663c3c2d07f792e8061f5 Mon Sep 17 00:00:00 2001 From: mihacooper Date: Tue, 17 Jan 2017 23:53:07 +0300 Subject: [PATCH] initial --- CMakeLists.txt | 26 ++++++++++++ LICENSE | 2 +- README.md | 3 +- build.sh | 12 ++++++ lua-api/woofer.lua | 10 +++++ src/threading.cpp | 92 ++++++++++++++++++++++++++++++++++++++++++ tests/smoke_test.lua | 95 ++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 238 insertions(+), 2 deletions(-) create mode 100644 CMakeLists.txt create mode 100755 build.sh create mode 100644 lua-api/woofer.lua create mode 100644 src/threading.cpp create mode 100644 tests/smoke_test.lua diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..97a0dc7 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required(VERSION 2.8) +project(bevy) + +find_package(Lua REQUIRED) + +if( "${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}" LESS "5.2") + message(FATAL_ERROR "Wrong Lua version ${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}, use 5.2 or higher") +endif() + +include_directories(src/lib src/sol2/single/sol ${LUA_INCLUDE_DIR}) + +FILE(GLOB SOURCES src/lib/*.cpp) + +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build) + +add_library(bevy SHARED ${SOURCES}) +target_link_libraries(bevy -lpthread ${LUA_LIBRARY}) +set_target_properties(bevy PROPERTIES COMPILE_FLAGS "-Wall -Wextra -pedantic -O3 -g -std=c++14 -pthread") + +#---------- +# INSTALL - +#---------- + +FILE(GLOB TESTS tests/*) +FILE(GLOB LUA_SOURCES src/*.lua) +install(FILES ${TESTSz} ${LUA_SOURCES} DESTINATION ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) \ No newline at end of file diff --git a/LICENSE b/LICENSE index 76d147d..b18dca9 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2017 loud-hound +Copyright (c) 2017 mihacooper Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index fd35e16..dd65f67 100644 --- a/README.md +++ b/README.md @@ -1 +1,2 @@ -# woofer \ No newline at end of file +# Bevy +Pure threads for Lua diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..86c45d6 --- /dev/null +++ b/build.sh @@ -0,0 +1,12 @@ +#!/bin/sh +ROOT_DIR=$( cd $(dirname $0); pwd ) +WORK_DIR=$ROOT_DIR/.work_dir + +if ! [ -d $WORK_DIR ]; then + mkdir $WORK_DIR +fi + +cd $WORK_DIR +cmake $ROOT_DIR +make -j4 +make install diff --git a/lua-api/woofer.lua b/lua-api/woofer.lua new file mode 100644 index 0000000..8f185a9 --- /dev/null +++ b/lua-api/woofer.lua @@ -0,0 +1,10 @@ +--local thr = require('libbevy') +require('libbevy') +local thr = thread +return { + new = function(func) + local str_func = ("%q"):format(string.dump(func)) + return thr.new(str_func) + end, + thread_id = thr.thread_id +} diff --git a/src/threading.cpp b/src/threading.cpp new file mode 100644 index 0000000..30f7bb6 --- /dev/null +++ b/src/threading.cpp @@ -0,0 +1,92 @@ +extern "C" +{ +#include "lua.h" +#include "lauxlib.h" +#include "lualib.h" +} + +#include +#include +#include +#include + +#include "shared-table.h" + +core::SharedTable shareTable; + +class LuaThread +{ +public: + + LuaThread(const std::string& rawFunction) + : m_strFunction(rawFunction) + { + std::cout << "LuaThread" << std::endl; + m_pState.reset(new sol::state); + core::SharedTable::bind(*m_pState); + (*m_pState)["share"] = &shareTable; + assert(m_pState.get() != NULL); + m_pState->open_libraries( + sol::lib::base, sol::lib::string, + sol::lib::package, sol::lib::io, sol::lib::os + ); + m_pThread.reset(new std::thread(&LuaThread::Impl, this)); + assert(m_pThread.get() != NULL); + std::cout << "LuaThread##" << std::endl; + } + + virtual ~LuaThread() + { + std::cout << "~LuaThread" << std::endl; + Join(); + } + + void Join() + { + std::cout << "Join started" << std::endl; + if (m_pThread.get()) + { + m_pThread->join(); + m_pThread.reset(); + } + if (m_pState.get()) + { + m_pState.reset(); + } + std::cout << "Join finished" << std::endl; + } + +private: + void Impl() + { + std::cout << "Impl" << std::endl; + std::stringstream script; + script << "loadstring(" << m_strFunction << ")()"; + m_pState->script(script.str()); + } + + std::string m_strFunction; + std::shared_ptr m_pState; + std::shared_ptr m_pThread; +}; + +static std::string ThreadId() +{ + std::stringstream ss; + ss << std::hash()(std::this_thread::get_id()); + return ss.str(); +} + +extern "C" int luaopen_libbevy(lua_State *L) +{ + sol::state_view lua(L); + lua.new_usertype("thread", + sol::constructors>(), + "join", &LuaThread::Join + ); + lua["thread"]["thread_id"] = ThreadId; + + core::SharedTable::bind(lua); + lua["share"] = &shareTable; + return 0; +} diff --git a/tests/smoke_test.lua b/tests/smoke_test.lua new file mode 100644 index 0000000..d0078c5 --- /dev/null +++ b/tests/smoke_test.lua @@ -0,0 +1,95 @@ +local thr = require('bevy') +t = thr.new( + function() + local thr = require('bevy') + print(share['key1']) + print(share['key2']) + print(share['key3']) + print(thr.thread_id()) + for i = 1, 100 do + io.write('2') + io.flush() + os.execute("sleep 0.1") + end + end +) + +share['key1'] = 'val' +share['key2'] = 100500 +share['key3'] = true +print(thr.thread_id()) +for i = 1, 100 do + io.write('1') + io.flush() + os.execute("sleep 0.1") +end +t:join() + +--[[ +ppp("qwe") +t = thr.new( + function() + local thr = require('bevy') + print(("0x%x"):format(thr.thread_id())) + for i = 1, 10 do + io.write('.') + io.flush() + os.execute("sleep " .. 1) + end + end +) +print(("0x%x"):format(thr.thread_id())) + +for i = 1, 10 do + io.write(',') + io.flush() + os.execute("sleep " .. 1) +end + +t:join() + +print() +]] + +--[[ +str_foo = "" + +asd =10 +qwe = 20 +function bar() + local lala = { 40 } + function foo(a, b) + local d = asd + local l = lala[1] + lala = 10 + return function() return a + asd + b + qwe + l end + end + + print(debug.getupvalue(foo, 1)) + print(debug.getupvalue(foo, 2)) + table_print(debug.getinfo(foo)) + str_foo = string.dump(foo) +end + +bar() + +foo2 = loadstring(str_foo) + + +local t = {} +setmetatable(t, + { + __index = function(self, key) + print("Call ", key) + return _ENV[key] + end, + __newindex = function(self, key, value) + print("Call ", key, value) + _ENV[key] = value + end + } +) +debug.setupvalue(foo2, 1, t) +debug.setupvalue(foo2, 2, { 99 }) +print(foo2(10, 20)()) +]]