mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 23:19:19 +02:00
basic lua support
This commit is contained in:
@@ -65,6 +65,7 @@ set(SOURCES
|
|||||||
"mouseinput.cpp"
|
"mouseinput.cpp"
|
||||||
"translation.cpp"
|
"translation.cpp"
|
||||||
"material.cpp"
|
"material.cpp"
|
||||||
|
"lua.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
@@ -125,5 +126,10 @@ find_package(libsndfile REQUIRED)
|
|||||||
include_directories(${LIBSNDFILE_INCLUDE_DIR})
|
include_directories(${LIBSNDFILE_INCLUDE_DIR})
|
||||||
target_link_libraries(${PROJECT_NAME} ${LIBSNDFILE_LIBRARY})
|
target_link_libraries(${PROJECT_NAME} ${LIBSNDFILE_LIBRARY})
|
||||||
|
|
||||||
#set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
|
find_package(LuaJIT REQUIRED)
|
||||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -g")
|
include_directories(${LUAJIT_INCLUDE_DIR})
|
||||||
|
target_link_libraries(${PROJECT_NAME} ${LUAJIT_LIBRARIES})
|
||||||
|
|
||||||
|
if (UNIX)
|
||||||
|
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined")
|
||||||
|
endif()
|
||||||
|
|||||||
81
CMake_modules/FindLuaJIT.cmake
Normal file
81
CMake_modules/FindLuaJIT.cmake
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
# Locate Lua library
|
||||||
|
# This module defines
|
||||||
|
# LUAJIT_FOUND, if false, do not try to link to Lua
|
||||||
|
# LUAJIT_LIBRARIES
|
||||||
|
# LUAJIT_INCLUDE_DIR, where to find lua.h
|
||||||
|
# LUAJIT_VERSION_STRING, the version of Lua found (since CMake 2.8.8)
|
||||||
|
#
|
||||||
|
# Note that the expected include convention is
|
||||||
|
# #include "lua.h"
|
||||||
|
# and not
|
||||||
|
# #include <lua/lua.h>
|
||||||
|
# This is because, the lua location is not standardized and may exist
|
||||||
|
# in locations other than lua/
|
||||||
|
|
||||||
|
#=============================================================================
|
||||||
|
# Copyright 2007-2009 Kitware, Inc.
|
||||||
|
#
|
||||||
|
# Distributed under the OSI-approved BSD License (the "License");
|
||||||
|
# see accompanying file Copyright.txt for details.
|
||||||
|
#
|
||||||
|
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||||
|
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
# See the License for more information.
|
||||||
|
#=============================================================================
|
||||||
|
# (To distribute this file outside of CMake, substitute the full
|
||||||
|
# License text for the above reference.)
|
||||||
|
|
||||||
|
find_path(LUAJIT_INCLUDE_DIR luajit.h
|
||||||
|
HINTS
|
||||||
|
$ENV{LUA_DIR}
|
||||||
|
PATH_SUFFIXES include/luajit-2.0 include
|
||||||
|
PATHS
|
||||||
|
~/Library/Frameworks
|
||||||
|
/Library/Frameworks
|
||||||
|
/sw # Fink
|
||||||
|
/opt/local # DarwinPorts
|
||||||
|
/opt/csw # Blastwave
|
||||||
|
/opt
|
||||||
|
)
|
||||||
|
|
||||||
|
find_library(LUAJIT_LIBRARY
|
||||||
|
NAMES luajit luajit-5.1
|
||||||
|
HINTS
|
||||||
|
$ENV{LUA_DIR}
|
||||||
|
PATH_SUFFIXES lib64 lib
|
||||||
|
PATHS
|
||||||
|
~/Library/Frameworks
|
||||||
|
/Library/Frameworks
|
||||||
|
/sw
|
||||||
|
/opt/local
|
||||||
|
/opt/csw
|
||||||
|
/opt
|
||||||
|
)
|
||||||
|
|
||||||
|
if (LUAJIT_LIBRARY)
|
||||||
|
# include the math library for Unix
|
||||||
|
if (UNIX AND NOT APPLE)
|
||||||
|
find_library(LUAJIT_MATH_LIBRARY m)
|
||||||
|
set(LUAJIT_LIBRARIES "${LUAJIT_LIBRARY};${LUAJIT_MATH_LIBRARY}" CACHE STRING "Lua Libraries")
|
||||||
|
# For Windows and Mac, don't need to explicitly include the math library
|
||||||
|
else ()
|
||||||
|
set(LUAJIT_LIBRARIES "${LUAJIT_LIBRARY}" CACHE STRING "Lua Libraries")
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if(LUAJIT_INCLUDE_DIR AND EXISTS "${LUAJIT_INCLUDE_DIR}/lua.h")
|
||||||
|
file(STRINGS "${LUAJIT_INCLUDE_DIR}/lua.h" luajit_version_str REGEX "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua .+\"")
|
||||||
|
|
||||||
|
string(REGEX REPLACE "^#define[ \t]+LUA_RELEASE[ \t]+\"Lua ([^\"]+)\".*" "\\1" LUAJIT_VERSION_STRING "${luajit_version_str}")
|
||||||
|
unset(luajit_version_str)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
# handle the QUIETLY and REQUIRED arguments and set LUAJIT_FOUND to TRUE if
|
||||||
|
# all listed variables are TRUE
|
||||||
|
find_package_handle_standard_args(LuaJIT
|
||||||
|
REQUIRED_VARS LUAJIT_LIBRARIES LUAJIT_INCLUDE_DIR
|
||||||
|
VERSION_VAR LUAJIT_VERSION_STRING)
|
||||||
|
|
||||||
|
mark_as_advanced(LUAJIT_INCLUDE_DIR LUAJIT_LIBRARIES LUAJIT_LIBRARY LUAJIT_MATH_LIBRARY)
|
||||||
|
|
||||||
7
EU07.cpp
7
EU07.cpp
@@ -365,7 +365,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
catch (std::runtime_error e)
|
catch (std::runtime_error e)
|
||||||
{
|
{
|
||||||
WriteLog(e.what());
|
ErrorLog(e.what());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,6 +406,11 @@ int main(int argc, char *argv[])
|
|||||||
ErrorLog( "Critical error, memory allocation failure: " + std::string( Error.what() ) );
|
ErrorLog( "Critical error, memory allocation failure: " + std::string( Error.what() ) );
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
catch (std::runtime_error e)
|
||||||
|
{
|
||||||
|
ErrorLog(e.what());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
Console::Off(); // wyłączenie konsoli (komunikacji zwrotnej)
|
Console::Off(); // wyłączenie konsoli (komunikacji zwrotnej)
|
||||||
|
|||||||
3
Event.h
3
Event.h
@@ -39,7 +39,8 @@ enum TEventType {
|
|||||||
tp_Visible,
|
tp_Visible,
|
||||||
tp_Voltage,
|
tp_Voltage,
|
||||||
tp_Message,
|
tp_Message,
|
||||||
tp_Friction
|
tp_Friction,
|
||||||
|
tp_Lua
|
||||||
};
|
};
|
||||||
|
|
||||||
const int update_memstring = 0x0000001; // zmodyfikować tekst (UpdateValues)
|
const int update_memstring = 0x0000001; // zmodyfikować tekst (UpdateValues)
|
||||||
|
|||||||
139
Ground.cpp
139
Ground.cpp
@@ -1761,6 +1761,72 @@ void TGround::FirstInit()
|
|||||||
WriteLog("FirstInit is done");
|
WriteLog("FirstInit is done");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void TGround::add_event(TEvent *tmp)
|
||||||
|
{
|
||||||
|
if (tmp->Type == tp_Unknown)
|
||||||
|
delete tmp;
|
||||||
|
else
|
||||||
|
{ // najpierw sprawdzamy, czy nie ma, a potem dopisujemy
|
||||||
|
TEvent *found = FindEvent(tmp->asName);
|
||||||
|
if (found)
|
||||||
|
{ // jeśli znaleziony duplikat
|
||||||
|
auto const size = tmp->asName.size();
|
||||||
|
if( tmp->asName[0] == '#' ) // zawsze jeden znak co najmniej jest
|
||||||
|
{
|
||||||
|
delete tmp;
|
||||||
|
tmp = nullptr;
|
||||||
|
} // utylizacja duplikatu z krzyżykiem
|
||||||
|
else if( ( size > 8 )
|
||||||
|
&& ( tmp->asName.substr( 0, 9 ) == "lineinfo:" ))
|
||||||
|
// tymczasowo wyjątki
|
||||||
|
{
|
||||||
|
delete tmp;
|
||||||
|
tmp = nullptr;
|
||||||
|
} // tymczasowa utylizacja duplikatów W5
|
||||||
|
else if( ( size > 8 )
|
||||||
|
&& ( tmp->asName.substr( size - 8 ) == "_warning"))
|
||||||
|
// tymczasowo wyjątki
|
||||||
|
{
|
||||||
|
delete tmp;
|
||||||
|
tmp = nullptr;
|
||||||
|
} // tymczasowa utylizacja duplikatu z trąbieniem
|
||||||
|
else if( ( size > 4 )
|
||||||
|
&& ( tmp->asName.substr( size - 4 ) == "_shp" ))
|
||||||
|
// nie podlegają logowaniu
|
||||||
|
{
|
||||||
|
delete tmp;
|
||||||
|
tmp = NULL;
|
||||||
|
} // tymczasowa utylizacja duplikatu SHP
|
||||||
|
if (tmp) // jeśli nie został zutylizowany
|
||||||
|
if (Global::bJoinEvents)
|
||||||
|
found->Append(tmp); // doczepka (taki wirtualny multiple bez warunków)
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ErrorLog("Duplicated event: " + tmp->asName);
|
||||||
|
found->Append(tmp); // doczepka (taki wirtualny multiple bez warunków)
|
||||||
|
found->Type = tp_Ignored; // dezaktywacja pierwotnego - taka proteza na
|
||||||
|
// wsteczną zgodność
|
||||||
|
// SafeDelete(tmp); //bezlitośnie usuwamy wszelkie duplikaty, żeby nie
|
||||||
|
// zaśmiecać drzewka
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( nullptr != tmp )
|
||||||
|
{ // jeśli nie duplikat
|
||||||
|
tmp->evNext2 = RootEvent; // lista wszystkich eventów (m.in. do InitEvents)
|
||||||
|
RootEvent = tmp;
|
||||||
|
if (!found)
|
||||||
|
{ // jeśli nazwa wystąpiła, to do kolejki i wyszukiwarki dodawany jest tylko pierwszy
|
||||||
|
if( ( RootEvent->Type != tp_Ignored )
|
||||||
|
&& ( RootEvent->asName.find( "onstart" ) != std::string::npos ) ) {
|
||||||
|
// event uruchamiany automatycznie po starcie
|
||||||
|
AddToQuery( RootEvent, NULL ); // dodanie do kolejki
|
||||||
|
}
|
||||||
|
m_eventmap.emplace( tmp->asName, tmp ); // dodanie do wyszukiwarki
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool TGround::Init(std::string File)
|
bool TGround::Init(std::string File)
|
||||||
{ // główne wczytywanie scenerii
|
{ // główne wczytywanie scenerii
|
||||||
if (ToLower(File).substr(0, 7) == "scenery")
|
if (ToLower(File).substr(0, 7) == "scenery")
|
||||||
@@ -1920,68 +1986,14 @@ bool TGround::Init(std::string File)
|
|||||||
{
|
{
|
||||||
TEvent *tmp = new TEvent();
|
TEvent *tmp = new TEvent();
|
||||||
tmp->Load(&parser, &pOrigin);
|
tmp->Load(&parser, &pOrigin);
|
||||||
if (tmp->Type == tp_Unknown)
|
add_event(tmp);
|
||||||
delete tmp;
|
}
|
||||||
else
|
else if (str == "lua")
|
||||||
{ // najpierw sprawdzamy, czy nie ma, a potem dopisujemy
|
{
|
||||||
TEvent *found = FindEvent(tmp->asName);
|
parser.getTokens();
|
||||||
if (found)
|
std::string file;
|
||||||
{ // jeśli znaleziony duplikat
|
parser >> file;
|
||||||
auto const size = tmp->asName.size();
|
m_lua.interpret(subpath + file);
|
||||||
if( tmp->asName[0] == '#' ) // zawsze jeden znak co najmniej jest
|
|
||||||
{
|
|
||||||
delete tmp;
|
|
||||||
tmp = nullptr;
|
|
||||||
} // utylizacja duplikatu z krzyżykiem
|
|
||||||
else if( ( size > 8 )
|
|
||||||
&& ( tmp->asName.substr( 0, 9 ) == "lineinfo:" ))
|
|
||||||
// tymczasowo wyjątki
|
|
||||||
{
|
|
||||||
delete tmp;
|
|
||||||
tmp = nullptr;
|
|
||||||
} // tymczasowa utylizacja duplikatów W5
|
|
||||||
else if( ( size > 8 )
|
|
||||||
&& ( tmp->asName.substr( size - 8 ) == "_warning"))
|
|
||||||
// tymczasowo wyjątki
|
|
||||||
{
|
|
||||||
delete tmp;
|
|
||||||
tmp = nullptr;
|
|
||||||
} // tymczasowa utylizacja duplikatu z trąbieniem
|
|
||||||
else if( ( size > 4 )
|
|
||||||
&& ( tmp->asName.substr( size - 4 ) == "_shp" ))
|
|
||||||
// nie podlegają logowaniu
|
|
||||||
{
|
|
||||||
delete tmp;
|
|
||||||
tmp = NULL;
|
|
||||||
} // tymczasowa utylizacja duplikatu SHP
|
|
||||||
if (tmp) // jeśli nie został zutylizowany
|
|
||||||
if (Global::bJoinEvents)
|
|
||||||
found->Append(tmp); // doczepka (taki wirtualny multiple bez warunków)
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ErrorLog("Duplicated event: " + tmp->asName);
|
|
||||||
found->Append(tmp); // doczepka (taki wirtualny multiple bez warunków)
|
|
||||||
found->Type = tp_Ignored; // dezaktywacja pierwotnego - taka proteza na
|
|
||||||
// wsteczną zgodność
|
|
||||||
// SafeDelete(tmp); //bezlitośnie usuwamy wszelkie duplikaty, żeby nie
|
|
||||||
// zaśmiecać drzewka
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( nullptr != tmp )
|
|
||||||
{ // jeśli nie duplikat
|
|
||||||
tmp->evNext2 = RootEvent; // lista wszystkich eventów (m.in. do InitEvents)
|
|
||||||
RootEvent = tmp;
|
|
||||||
if (!found)
|
|
||||||
{ // jeśli nazwa wystąpiła, to do kolejki i wyszukiwarki dodawany jest tylko pierwszy
|
|
||||||
if( ( RootEvent->Type != tp_Ignored )
|
|
||||||
&& ( RootEvent->asName.find( "onstart" ) != std::string::npos ) ) {
|
|
||||||
// event uruchamiany automatycznie po starcie
|
|
||||||
AddToQuery( RootEvent, NULL ); // dodanie do kolejki
|
|
||||||
}
|
|
||||||
m_eventmap.emplace( tmp->asName, tmp ); // dodanie do wyszukiwarki
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (str == "rotate")
|
else if (str == "rotate")
|
||||||
{
|
{
|
||||||
@@ -3445,6 +3457,9 @@ bool TGround::CheckQuery()
|
|||||||
break;
|
break;
|
||||||
case tp_Message: // wyświetlenie komunikatu
|
case tp_Message: // wyświetlenie komunikatu
|
||||||
break;
|
break;
|
||||||
|
case tp_Lua:
|
||||||
|
((lua::eventhandler_t)tmpEvent->Params[0].asPointer)(tmpEvent, tmpEvent->Activator);
|
||||||
|
break;
|
||||||
} // switch (tmpEvent->Type)
|
} // switch (tmpEvent->Type)
|
||||||
} // if (tmpEvent->bEnabled)
|
} // if (tmpEvent->bEnabled)
|
||||||
} // while
|
} // while
|
||||||
|
|||||||
4
Ground.h
4
Ground.h
@@ -20,6 +20,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "Float3d.h"
|
#include "Float3d.h"
|
||||||
#include "Names.h"
|
#include "Names.h"
|
||||||
#include "lightarray.h"
|
#include "lightarray.h"
|
||||||
|
#include "lua.h"
|
||||||
|
|
||||||
typedef int TGroundNodeType;
|
typedef int TGroundNodeType;
|
||||||
// Ra: zmniejszone liczby, aby zrobić tabelkę i zoptymalizować wyszukiwanie
|
// Ra: zmniejszone liczby, aby zrobić tabelkę i zoptymalizować wyszukiwanie
|
||||||
@@ -260,6 +261,7 @@ class TGround
|
|||||||
event_map m_eventmap;
|
event_map m_eventmap;
|
||||||
TNames<TGroundNode *> m_trackmap;
|
TNames<TGroundNode *> m_trackmap;
|
||||||
light_array m_lights; // collection of dynamic light sources present in the scene
|
light_array m_lights; // collection of dynamic light sources present in the scene
|
||||||
|
lua m_lua;
|
||||||
|
|
||||||
vector3 pOrigin;
|
vector3 pOrigin;
|
||||||
vector3 aRotate;
|
vector3 aRotate;
|
||||||
@@ -342,6 +344,8 @@ class TGround
|
|||||||
void IsolatedBusyList();
|
void IsolatedBusyList();
|
||||||
void IsolatedBusy(const std::string t);
|
void IsolatedBusy(const std::string t);
|
||||||
void Silence(vector3 gdzie);
|
void Silence(vector3 gdzie);
|
||||||
|
|
||||||
|
void add_event(TEvent *event);
|
||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
3
World.h
3
World.h
@@ -121,7 +121,6 @@ private:
|
|||||||
|
|
||||||
TCamera Camera;
|
TCamera Camera;
|
||||||
TCamera DebugCamera;
|
TCamera DebugCamera;
|
||||||
TGround Ground;
|
|
||||||
world_environment Environment;
|
world_environment Environment;
|
||||||
TTrain *Train;
|
TTrain *Train;
|
||||||
TDynamicObject *pDynamicNearest;
|
TDynamicObject *pDynamicNearest;
|
||||||
@@ -147,6 +146,8 @@ private:
|
|||||||
void CabChange(TDynamicObject *old, TDynamicObject *now);
|
void CabChange(TDynamicObject *old, TDynamicObject *now);
|
||||||
// handles vehicle change flag
|
// handles vehicle change flag
|
||||||
void ChangeDynamic();
|
void ChangeDynamic();
|
||||||
|
|
||||||
|
TGround Ground; //m7todo: tmp
|
||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -15,5 +15,7 @@ cmake ../.. -T v140_xp ^
|
|||||||
-DOPENAL_INCLUDE_DIR=%DEPS_DIR%/openal/include ^
|
-DOPENAL_INCLUDE_DIR=%DEPS_DIR%/openal/include ^
|
||||||
-DOPENAL_LIBRARY=%DEPS_DIR%/openal/lib/win32/OpenAL32.lib ^
|
-DOPENAL_LIBRARY=%DEPS_DIR%/openal/lib/win32/OpenAL32.lib ^
|
||||||
-DLIBSNDFILE_INCLUDE_DIR=%DEPS_DIR%/libsndfile/include ^
|
-DLIBSNDFILE_INCLUDE_DIR=%DEPS_DIR%/libsndfile/include ^
|
||||||
-DLIBSNDFILE_LIBRARY=%DEPS_DIR%/libsndfile/lib/win32/libsndfile-1.lib
|
-DLIBSNDFILE_LIBRARY=%DEPS_DIR%/libsndfile/lib/win32/libsndfile-1.lib ^
|
||||||
|
-DLUAJIT_INCLUDE_DIR=%DEPS_DIR%/luajit/include ^
|
||||||
|
-DLUAJIT_LIBRARIES=%DEPS_DIR%/luajit/lib/win32/lua51.lib
|
||||||
popd
|
popd
|
||||||
@@ -15,5 +15,7 @@ cmake ../.. -A x64 ^
|
|||||||
-DOPENAL_INCLUDE_DIR=%DEPS_DIR%/openal/include ^
|
-DOPENAL_INCLUDE_DIR=%DEPS_DIR%/openal/include ^
|
||||||
-DOPENAL_LIBRARY=%DEPS_DIR%/openal/lib/win64/OpenAL32.lib ^
|
-DOPENAL_LIBRARY=%DEPS_DIR%/openal/lib/win64/OpenAL32.lib ^
|
||||||
-DLIBSNDFILE_INCLUDE_DIR=%DEPS_DIR%/libsndfile/include ^
|
-DLIBSNDFILE_INCLUDE_DIR=%DEPS_DIR%/libsndfile/include ^
|
||||||
-DLIBSNDFILE_LIBRARY=%DEPS_DIR%/libsndfile/lib/win64/libsndfile-1.lib
|
-DLIBSNDFILE_LIBRARY=%DEPS_DIR%/libsndfile/lib/win64/libsndfile-1.lib ^
|
||||||
|
-DLUAJIT_INCLUDE_DIR=%DEPS_DIR%/luajit/include ^
|
||||||
|
-DLUAJIT_LIBRARIES=%DEPS_DIR%/luajit/lib/win64/lua51.lib
|
||||||
popd
|
popd
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
powershell "$wc = New-Object System.Net.WebClient; $wc.DownloadFile(\"https://milek7.pl/.stuff/eu07exe/builddep2.zip\", \"%cd%\deps_win.zip\")"
|
powershell "$wc = New-Object System.Net.WebClient; $wc.DownloadFile(\"https://milek7.pl/.stuff/eu07exe/builddep3.zip\", \"%cd%\deps_win.zip\")"
|
||||||
powershell "$s = New-Object -ComObject shell.application; $z = $s.Namespace(\"%cd%\deps_win.zip\"); foreach ($i in $z.items()) { $s.Namespace(\"%cd%\").CopyHere($i) }"
|
powershell "$s = New-Object -ComObject shell.application; $z = $s.Namespace(\"%cd%\deps_win.zip\"); foreach ($i in $z.items()) { $s.Namespace(\"%cd%\").CopyHere($i) }"
|
||||||
|
|||||||
170
lua.cpp
Normal file
170
lua.cpp
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
#include "stdafx.h"
|
||||||
|
#include "lua.h"
|
||||||
|
#include "Event.h"
|
||||||
|
#include "Logs.h"
|
||||||
|
#include "MemCell.h"
|
||||||
|
#include "World.h"
|
||||||
|
#include "Driver.h"
|
||||||
|
#include "lua_ffi.h"
|
||||||
|
|
||||||
|
extern TWorld World;
|
||||||
|
|
||||||
|
lua::lua()
|
||||||
|
{
|
||||||
|
state = luaL_newstate();
|
||||||
|
if (!state)
|
||||||
|
throw std::runtime_error("cannot create lua state");
|
||||||
|
lua_atpanic(state, atpanic);
|
||||||
|
luaL_openlibs(state);
|
||||||
|
|
||||||
|
lua_getglobal(state, "package");
|
||||||
|
lua_pushstring(state, "preload");
|
||||||
|
lua_gettable(state, -2);
|
||||||
|
lua_pushcclosure(state, openffi, 0);
|
||||||
|
lua_setfield(state, -2, "eu07.events");
|
||||||
|
lua_settop(state, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
lua::~lua()
|
||||||
|
{
|
||||||
|
lua_close(state);
|
||||||
|
state = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lua::interpret(std::string file)
|
||||||
|
{
|
||||||
|
if (luaL_dofile(state, file.c_str()))
|
||||||
|
throw std::runtime_error(lua_tostring(state, -1));
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: we cannot throw exceptions in callbacks
|
||||||
|
// because it is not supported by LuaJIT on x86 windows
|
||||||
|
|
||||||
|
int lua::atpanic(lua_State *s)
|
||||||
|
{
|
||||||
|
ErrorLog(std::string(lua_tostring(s, -1)));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lua::openffi(lua_State *s)
|
||||||
|
{
|
||||||
|
if (luaL_dostring(s, lua_ffi))
|
||||||
|
{
|
||||||
|
ErrorLog(std::string(lua_tostring(s, -1)));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
TEvent* scriptapi_event_create(const char* name, lua::eventhandler_t handler, double delay)
|
||||||
|
{
|
||||||
|
TEvent *event = new TEvent();
|
||||||
|
event->bEnabled = true;
|
||||||
|
event->Type = tp_Lua;
|
||||||
|
event->asName = std::string(name);
|
||||||
|
event->fDelay = delay;
|
||||||
|
event->Params[0].asPointer = (void*)handler;
|
||||||
|
World.Ground.add_event(event);
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEvent* scriptapi_event_find(const char* name)
|
||||||
|
{
|
||||||
|
std::string str(name);
|
||||||
|
TEvent *e = World.Ground.FindEvent(str);
|
||||||
|
if (e)
|
||||||
|
return e;
|
||||||
|
else
|
||||||
|
WriteLog("missing event: " + str);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
TTrack* scriptapi_track_find(const char* name)
|
||||||
|
{
|
||||||
|
std::string str(name);
|
||||||
|
TGroundNode *n = World.Ground.FindGroundNode(str, TP_TRACK);
|
||||||
|
if (n)
|
||||||
|
return n->pTrack;
|
||||||
|
else
|
||||||
|
WriteLog("missing track: " + str);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool scriptapi_track_isoccupied(TTrack* track)
|
||||||
|
{
|
||||||
|
if (track)
|
||||||
|
return !track->IsEmpty();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* scriptapi_event_getname(TEvent *e)
|
||||||
|
{
|
||||||
|
if (e)
|
||||||
|
return e->asName.c_str();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* scriptapi_train_getname(TDynamicObject *dyn)
|
||||||
|
{
|
||||||
|
if (dyn && dyn->Mechanik)
|
||||||
|
return dyn->Mechanik->TrainName().c_str();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void scriptapi_event_dispatch(TEvent *e, TDynamicObject *activator)
|
||||||
|
{
|
||||||
|
if (e)
|
||||||
|
World.Ground.AddToQuery(e, activator);
|
||||||
|
}
|
||||||
|
|
||||||
|
double scriptapi_random(double a, double b)
|
||||||
|
{
|
||||||
|
return Random(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scriptapi_writelog(const char* txt)
|
||||||
|
{
|
||||||
|
WriteLog("lua log: " + std::string(txt));
|
||||||
|
}
|
||||||
|
|
||||||
|
struct memcell_values { const char *str; double num1; double num2; };
|
||||||
|
|
||||||
|
TMemCell* scriptapi_memcell_find(const char *name)
|
||||||
|
{
|
||||||
|
std::string str(name);
|
||||||
|
TGroundNode *n = World.Ground.FindGroundNode(str, TP_MEMCELL);
|
||||||
|
if (n)
|
||||||
|
return n->MemCell;
|
||||||
|
else
|
||||||
|
WriteLog("missing memcell: " + str);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcell_values scriptapi_memcell_read(TMemCell *mc)
|
||||||
|
{
|
||||||
|
if (!mc)
|
||||||
|
return { nullptr, 0.0, 0.0 };
|
||||||
|
return { mc->Text().c_str(), mc->Value1(), mc->Value2() };
|
||||||
|
}
|
||||||
|
|
||||||
|
void scriptapi_memcell_update(TMemCell *mc, const char *str, double num1, double num2)
|
||||||
|
{
|
||||||
|
if (!mc)
|
||||||
|
return;
|
||||||
|
mc->UpdateValues(std::string(str), num1, num2,
|
||||||
|
update_memstring | update_memval1 | update_memval2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void scriptapi_dynobj_putvalues(TDynamicObject *dyn, const char *str, double num1, double num2)
|
||||||
|
{
|
||||||
|
if (!dyn)
|
||||||
|
return;
|
||||||
|
TLocation loc;
|
||||||
|
if (dyn->Mechanik)
|
||||||
|
dyn->Mechanik->PutCommand(std::string(str), num1, num2, nullptr);
|
||||||
|
else
|
||||||
|
dyn->MoverParameters->PutCommand(std::string(str), num1, num2, loc);
|
||||||
|
}
|
||||||
|
}
|
||||||
21
lua.h
Normal file
21
lua.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <lua.hpp>
|
||||||
|
|
||||||
|
class TEvent;
|
||||||
|
class TDynamicObject;
|
||||||
|
|
||||||
|
class lua
|
||||||
|
{
|
||||||
|
lua_State *state;
|
||||||
|
|
||||||
|
static int atpanic(lua_State *s);
|
||||||
|
static int openffi(lua_State *s);
|
||||||
|
|
||||||
|
public:
|
||||||
|
lua();
|
||||||
|
~lua();
|
||||||
|
|
||||||
|
void interpret(std::string file);
|
||||||
|
|
||||||
|
typedef void (*eventhandler_t)(TEvent*, TDynamicObject*);
|
||||||
|
};
|
||||||
78
lua_ffi.h
Normal file
78
lua_ffi.h
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
const char lua_ffi[] = "local ffi = require(\"ffi\")\n"
|
||||||
|
"ffi.cdef[[\n"
|
||||||
|
"struct memcell_values { const char *str; double num1; double num2; };\n"
|
||||||
|
"\n"
|
||||||
|
"typedef struct TEvent TEvent;\n"
|
||||||
|
"typedef struct TTrack TTrack;\n"
|
||||||
|
"typedef struct TDynamicObject TDynamicObject;\n"
|
||||||
|
"typedef struct TMemCell TMemCell;\n"
|
||||||
|
"typedef struct memcell_values memcell_values;\n"
|
||||||
|
"\n"
|
||||||
|
"TEvent* scriptapi_event_create(const char* name, void (*handler)(TEvent*, TDynamicObject*), double delay);\n"
|
||||||
|
"TEvent* scriptapi_event_find(const char* name);\n"
|
||||||
|
"const char* scriptapi_event_getname(TEvent *e);\n"
|
||||||
|
"void scriptapi_event_dispatch(TEvent *e, TDynamicObject *activator);\n"
|
||||||
|
"\n"
|
||||||
|
"TTrack* scriptapi_track_find(const char* name);\n"
|
||||||
|
"bool scriptapi_track_isoccupied(TTrack *track);\n"
|
||||||
|
"\n"
|
||||||
|
"const char* scriptapi_train_getname(TDynamicObject *dyn);\n"
|
||||||
|
"void scriptapi_dynobj_putvalues(TDynamicObject *dyn, const char *str, double num1, double num2);\n"
|
||||||
|
"\n"
|
||||||
|
"TMemCell* scriptapi_memcell_find(const char *name);\n"
|
||||||
|
"memcell_values scriptapi_memcell_read(TMemCell *mc);\n"
|
||||||
|
"void scriptapi_memcell_update(TMemCell *mc, const char *str, double num1, double num2);\n"
|
||||||
|
"\n"
|
||||||
|
"double scriptapi_random(double a, double b);\n"
|
||||||
|
"void scriptapi_writelog(const char* txt);\n"
|
||||||
|
"]]\n"
|
||||||
|
"\n"
|
||||||
|
"local ns = ffi.C\n"
|
||||||
|
"\n"
|
||||||
|
"local module = {}\n"
|
||||||
|
"\n"
|
||||||
|
"module.event_create = ns.scriptapi_event_create\n"
|
||||||
|
"module.event_find = ns.scriptapi_event_find\n"
|
||||||
|
"function module.event_getname(a)\n"
|
||||||
|
" return ffi.string(ns.scriptapi_event_getname(a))\n"
|
||||||
|
"end\n"
|
||||||
|
"module.event_dispatch = ns.scriptapi_event_dispatch\n"
|
||||||
|
"function module.event_dispatch_n(a, b)\n"
|
||||||
|
" ns.scriptapi_event_dispatch(ns.scriptapi_event_find(a), b)\n"
|
||||||
|
"end\n"
|
||||||
|
"\n"
|
||||||
|
"module.track_find = ns.scriptapi_track_find\n"
|
||||||
|
"module.track_isoccupied = ns.scriptapi_track_isoccupied\n"
|
||||||
|
"function module.track_isoccupied_n(a)\n"
|
||||||
|
" return ns.scriptapi_track_isoccupied(ns.scriptapi_track_find(a))\n"
|
||||||
|
"end\n"
|
||||||
|
"\n"
|
||||||
|
"function module.train_getname(a)\n"
|
||||||
|
" return ffi.string(ns.scriptapi_train_getname(a))\n"
|
||||||
|
"end\n"
|
||||||
|
"function module.dynobj_putvalues(a, b)\n"
|
||||||
|
" ns.scriptapi_dynobj_putvalues(a, b.str, b.num1, b.num2)\n"
|
||||||
|
"end\n"
|
||||||
|
"\n"
|
||||||
|
"module.memcell_find = ns.scriptapi_memcell_find\n"
|
||||||
|
"function module.memcell_read(a)\n"
|
||||||
|
" native = ns.scriptapi_memcell_read(a)\n"
|
||||||
|
" mc = { }\n"
|
||||||
|
" mc.str = ffi.string(native.str)\n"
|
||||||
|
" mc.num1 = native.num1\n"
|
||||||
|
" mc.num2 = native.num2\n"
|
||||||
|
" return mc\n"
|
||||||
|
"end\n"
|
||||||
|
"function module.memcell_read_n(a)\n"
|
||||||
|
" return module.memcell_read(ns.scriptapi_memcell_find(a))\n"
|
||||||
|
"end\n"
|
||||||
|
"function module.memcell_update(a, b)\n"
|
||||||
|
" ns.scriptapi_memcell_update(a, b.str, b.num1, b.num2)\n"
|
||||||
|
"end\n"
|
||||||
|
"function module.memcell_update_n(a, b)\n"
|
||||||
|
" ns.scriptapi_memcell_update(ns.scriptapi_memcell_find(a), b.str, b.num1, b.num2)\n"
|
||||||
|
"end\n"
|
||||||
|
"\n"
|
||||||
|
"module.random = ns.scriptapi_random\n"
|
||||||
|
"module.writelog = ns.scriptapi_writelog\n"
|
||||||
|
"\nreturn module\n";
|
||||||
Reference in New Issue
Block a user