' + os.linesep
diff --git a/manual/luadoc/example/pv/checkingforpersistentdata.lua b/manual/luadoc/example/pv/checkingforpersistentdata.lua
new file mode 100644
index 00000000..df83b85e
--- /dev/null
+++ b/manual/luadoc/example/pv/checkingforpersistentdata.lua
@@ -0,0 +1,6 @@
+if pv.freight_car_1 == nil then
+ pv.freight_car_1 = {
+ cargo = 'none',
+ destination = 'unset'
+ }
+end
diff --git a/manual/luadoc/example/pv/deletingpersistentdata.lua b/manual/luadoc/example/pv/deletingpersistentdata.lua
new file mode 100644
index 00000000..5e94ee05
--- /dev/null
+++ b/manual/luadoc/example/pv/deletingpersistentdata.lua
@@ -0,0 +1,4 @@
+pv.number = nil
+pv.title = nil
+pv.very_cool = nil
+pv.freight_car_1 = nil
diff --git a/manual/luadoc/example/pv/retrievingpersistentdata.lua b/manual/luadoc/example/pv/retrievingpersistentdata.lua
new file mode 100644
index 00000000..31d1f011
--- /dev/null
+++ b/manual/luadoc/example/pv/retrievingpersistentdata.lua
@@ -0,0 +1,9 @@
+log.debug(pv.number)
+log.debug(pv.title)
+log.debug(pv.very_cool)
+
+log.debug(pv.freight_car_1.cargo)
+
+for k, v in pairs(pv['freight_car_1']) do
+ log.debug(k, v)
+end
diff --git a/manual/luadoc/example/pv/storingpersistentdata.lua b/manual/luadoc/example/pv/storingpersistentdata.lua
new file mode 100644
index 00000000..014bf024
--- /dev/null
+++ b/manual/luadoc/example/pv/storingpersistentdata.lua
@@ -0,0 +1,8 @@
+pv.number = 42
+pv.title = 'Traintastic is awesome!'
+pv.very_cool = true
+
+pv['freight_car_1'] = {
+ cargo = 'grain',
+ destination = 'upper yard'
+}
diff --git a/manual/luadoc/globals.json b/manual/luadoc/globals.json
index ee67139c..920a80c2 100644
--- a/manual/luadoc/globals.json
+++ b/manual/luadoc/globals.json
@@ -67,6 +67,10 @@
"type": "constant",
"since": "0.1"
},
+ "pv": {
+ "type": "object",
+ "since": "0.3"
+ },
"world": {
"type": "object",
"since": "0.1"
@@ -102,4 +106,4 @@
"type": "library",
"since": "0.1"
}
-}
\ No newline at end of file
+}
diff --git a/manual/luadoc/object/train.json b/manual/luadoc/object/train.json
index 95fe3e14..ae0be6d5 100644
--- a/manual/luadoc/object/train.json
+++ b/manual/luadoc/object/train.json
@@ -8,6 +8,7 @@
"mode": {},
"mute": {},
"no_smoke": {},
+ "blocks": {},
"zones": {},
"on_block_assigned": {
"parameters": [
diff --git a/manual/luadoc/terms/en-us.json b/manual/luadoc/terms/en-us.json
index 3020248d..23bbc1cb 100644
--- a/manual/luadoc/terms/en-us.json
+++ b/manual/luadoc/terms/en-us.json
@@ -2218,5 +2218,53 @@
{
"term": "object.zone.trains:description",
"definition": "List of {ref:object.trainzonestatus|train zone status} objects of all trains that are entering, entered or leaving the zone."
+ },
+ {
+ "term": "globals.pv:description",
+ "definition": "The {ref:pv|persistent variable} table."
+ },
+ {
+ "term": "pv:title",
+ "definition": "Persistent variables"
+ },
+ {
+ "term": "pv:paragraph_1",
+ "definition": "Persistent variables allow you to store and retrieve data that remains available across multiple executions of the Lua script. This can be particularly useful for maintaining state information that needs to be retained beyond the current script's lifetime."
+ },
+ {
+ "term": "pv:paragraph_2",
+ "definition": "The {ref:globals#pv|`pv`} global provides a simple and efficient interface for interacting with persistent data. Any values stored in {ref:globals#pv|`pv`} are saved across script executions and world save and loads. Below is a detailed breakdown of how to use the {ref:globals#pv|`pv`} global."
+ },
+ {
+ "term": "pv.storing:title",
+ "definition": "Storing persistent data"
+ },
+ {
+ "term": "pv.storing:paragraph_1",
+ "definition": "You can store data in {ref:globals#pv|`pv`} just like you would with a regular Lua table. Supported data types are numbers, strings, booleans, tables, {ref:enum|enums}, {ref:set|sets}, {ref:object|objects} and object methods."
+ },
+ {
+ "term": "pv.retrieving:title",
+ "definition": "Retrieving persistent data"
+ },
+ {
+ "term": "pv.retrieving:paragraph_1",
+ "definition": "To retrieve a previously stored value, including tables, access the corresponding key in the {ref:globals#pv|`pv`} global:"
+ },
+ {
+ "term": "pv.deleting:title",
+ "definition": "Deleting persistent data"
+ },
+ {
+ "term": "pv.deleting:paragraph_1",
+ "definition": "To delete a stored persistent value, including tables, simply assign `nil` to the desired key:"
+ },
+ {
+ "term": "pv.checking:title",
+ "definition": "Checking for persistent data"
+ },
+ {
+ "term": "pv.checking:paragraph_1",
+ "definition": "To determine if a persistent variable has been set, use an `if` statement with `nil` checks. Variables in {ref:globals#pv|`pv`} that haven't been initialized or have been deleted will return `nil`. This pattern is useful for initializing default values or handling cases where the persistent variables are cleared."
}
]
diff --git a/manual/traintasticmanualbuilder/utils.py b/manual/traintasticmanualbuilder/utils.py
index 4db7acf3..11a6f5a7 100644
--- a/manual/traintasticmanualbuilder/utils.py
+++ b/manual/traintasticmanualbuilder/utils.py
@@ -25,7 +25,7 @@ def highlight_replace(code: str, css_class: str, clickable_links: bool = False)
def highlight_lua(code: str) -> str:
- code = re.sub(r'\b(math|table|string|class|enum|set|log|world)\b', r'\1', code) # globals
+ code = re.sub(r'\b(math|table|string|class|enum|set|log|world|pv)\b', r'\1', code) # globals
code = re.sub(r'\b([A-Z_][A-Z0-9_]*)\b', r'\1', code) # CONSTANTS
code = re.sub(r'\b(and|break|do|else|elseif|end|false|for|function|goto|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b', r'\1', code) # keywords
code = re.sub(r'\b((|-|\+)[0-9]+(\\.[0-9]*|)((e|E)(|-|\+)[0-9]+|))\b', r'\1', code) # numbers: infloat, decimal
diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt
index c914db1a..2371c176 100644
--- a/server/CMakeLists.txt
+++ b/server/CMakeLists.txt
@@ -32,6 +32,8 @@ target_include_directories(traintastic-server SYSTEM PRIVATE
thirdparty)
if(BUILD_TESTING)
+ add_subdirectory(thirdparty/catch2)
+ set_target_properties(Catch2 PROPERTIES CXX_STANDARD 17)
add_executable(traintastic-server-test test/main.cpp)
add_dependencies(traintastic-server-test traintastic-lang)
target_compile_definitions(traintastic-server-test PRIVATE -DTRAINTASTIC_TEST)
@@ -42,6 +44,7 @@ if(BUILD_TESTING)
target_include_directories(traintastic-server-test SYSTEM PRIVATE
../shared/thirdparty
thirdparty)
+ target_link_libraries(traintastic-server-test PRIVATE Catch2::Catch2WithMain)
endif()
file(GLOB SOURCES
@@ -217,6 +220,9 @@ if(LINUX)
if(BUILD_TESTING)
target_link_libraries(traintastic-server-test PRIVATE PkgConfig::LIBSYSTEMD)
endif()
+ else()
+ # Use inotify for monitoring serial ports:
+ list(APPEND SOURCES "src/os/linux/serialportlistimplinotify.hpp" "src/os/linux/serialportlistimplinotify.cpp")
endif()
else()
# socket CAN is only available on linux:
@@ -459,8 +465,7 @@ endif()
if(BUILD_TESTING)
include(Catch)
- target_include_directories(traintastic-server-test PRIVATE thirdparty/catch2)
- catch_discover_tests(traintastic-server-test)
+ catch_discover_tests(traintastic-server-test DISCOVERY_MODE PRE_TEST)
endif()
### Doxygen ###
diff --git a/server/cmake/Catch.cmake b/server/cmake/Catch.cmake
deleted file mode 100644
index a3885162..00000000
--- a/server/cmake/Catch.cmake
+++ /dev/null
@@ -1,206 +0,0 @@
-# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
-# file Copyright.txt or https://cmake.org/licensing for details.
-
-#[=======================================================================[.rst:
-Catch
------
-
-This module defines a function to help use the Catch test framework.
-
-The :command:`catch_discover_tests` discovers tests by asking the compiled test
-executable to enumerate its tests. This does not require CMake to be re-run
-when tests change. However, it may not work in a cross-compiling environment,
-and setting test properties is less convenient.
-
-This command is intended to replace use of :command:`add_test` to register
-tests, and will create a separate CTest test for each Catch test case. Note
-that this is in some cases less efficient, as common set-up and tear-down logic
-cannot be shared by multiple test cases executing in the same instance.
-However, it provides more fine-grained pass/fail information to CTest, which is
-usually considered as more beneficial. By default, the CTest test name is the
-same as the Catch name; see also ``TEST_PREFIX`` and ``TEST_SUFFIX``.
-
-.. command:: catch_discover_tests
-
- Automatically add tests with CTest by querying the compiled test executable
- for available tests::
-
- catch_discover_tests(target
- [TEST_SPEC arg1...]
- [EXTRA_ARGS arg1...]
- [WORKING_DIRECTORY dir]
- [TEST_PREFIX prefix]
- [TEST_SUFFIX suffix]
- [PROPERTIES name1 value1...]
- [TEST_LIST var]
- [REPORTER reporter]
- [OUTPUT_DIR dir]
- [OUTPUT_PREFIX prefix}
- [OUTPUT_SUFFIX suffix]
- )
-
- ``catch_discover_tests`` sets up a post-build command on the test executable
- that generates the list of tests by parsing the output from running the test
- with the ``--list-test-names-only`` argument. This ensures that the full
- list of tests is obtained. Since test discovery occurs at build time, it is
- not necessary to re-run CMake when the list of tests changes.
- However, it requires that :prop_tgt:`CROSSCOMPILING_EMULATOR` is properly set
- in order to function in a cross-compiling environment.
-
- Additionally, setting properties on tests is somewhat less convenient, since
- the tests are not available at CMake time. Additional test properties may be
- assigned to the set of tests as a whole using the ``PROPERTIES`` option. If
- more fine-grained test control is needed, custom content may be provided
- through an external CTest script using the :prop_dir:`TEST_INCLUDE_FILES`
- directory property. The set of discovered tests is made accessible to such a
- script via the ``_TESTS`` variable.
-
- The options are:
-
- ``target``
- Specifies the Catch executable, which must be a known CMake executable
- target. CMake will substitute the location of the built executable when
- running the test.
-
- ``TEST_SPEC arg1...``
- Specifies test cases, wildcarded test cases, tags and tag expressions to
- pass to the Catch executable with the ``--list-test-names-only`` argument.
-
- ``EXTRA_ARGS arg1...``
- Any extra arguments to pass on the command line to each test case.
-
- ``WORKING_DIRECTORY dir``
- Specifies the directory in which to run the discovered test cases. If this
- option is not provided, the current binary directory is used.
-
- ``TEST_PREFIX prefix``
- Specifies a ``prefix`` to be prepended to the name of each discovered test
- case. This can be useful when the same test executable is being used in
- multiple calls to ``catch_discover_tests()`` but with different
- ``TEST_SPEC`` or ``EXTRA_ARGS``.
-
- ``TEST_SUFFIX suffix``
- Similar to ``TEST_PREFIX`` except the ``suffix`` is appended to the name of
- every discovered test case. Both ``TEST_PREFIX`` and ``TEST_SUFFIX`` may
- be specified.
-
- ``PROPERTIES name1 value1...``
- Specifies additional properties to be set on all tests discovered by this
- invocation of ``catch_discover_tests``.
-
- ``TEST_LIST var``
- Make the list of tests available in the variable ``var``, rather than the
- default ``_TESTS``. This can be useful when the same test
- executable is being used in multiple calls to ``catch_discover_tests()``.
- Note that this variable is only available in CTest.
-
- ``REPORTER reporter``
- Use the specified reporter when running the test case. The reporter will
- be passed to the Catch executable as ``--reporter reporter``.
-
- ``OUTPUT_DIR dir``
- If specified, the parameter is passed along as
- ``--out dir/`` to Catch executable. The actual file name is the
- same as the test name. This should be used instead of
- ``EXTRA_ARGS --out foo`` to avoid race conditions writing the result output
- when using parallel test execution.
-
- ``OUTPUT_PREFIX prefix``
- May be used in conjunction with ``OUTPUT_DIR``.
- If specified, ``prefix`` is added to each output file name, like so
- ``--out dir/prefix``.
-
- ``OUTPUT_SUFFIX suffix``
- May be used in conjunction with ``OUTPUT_DIR``.
- If specified, ``suffix`` is added to each output file name, like so
- ``--out dir/suffix``. This can be used to add a file extension to
- the output e.g. ".xml".
-
-#]=======================================================================]
-
-#------------------------------------------------------------------------------
-function(catch_discover_tests TARGET)
- cmake_parse_arguments(
- ""
- ""
- "TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST;REPORTER;OUTPUT_DIR;OUTPUT_PREFIX;OUTPUT_SUFFIX"
- "TEST_SPEC;EXTRA_ARGS;PROPERTIES"
- ${ARGN}
- )
-
- if(NOT _WORKING_DIRECTORY)
- set(_WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
- endif()
- if(NOT _TEST_LIST)
- set(_TEST_LIST ${TARGET}_TESTS)
- endif()
-
- ## Generate a unique name based on the extra arguments
- string(SHA1 args_hash "${_TEST_SPEC} ${_EXTRA_ARGS} ${_REPORTER} ${_OUTPUT_DIR} ${_OUTPUT_PREFIX} ${_OUTPUT_SUFFIX}")
- string(SUBSTRING ${args_hash} 0 7 args_hash)
-
- # Define rule to generate test list for aforementioned test executable
- set(ctest_include_file "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_include-${args_hash}.cmake")
- set(ctest_tests_file "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_tests-${args_hash}.cmake")
- get_property(crosscompiling_emulator
- TARGET ${TARGET}
- PROPERTY CROSSCOMPILING_EMULATOR
- )
- add_custom_command(
- TARGET ${TARGET} POST_BUILD
- BYPRODUCTS "${ctest_tests_file}"
- COMMAND "${CMAKE_COMMAND}"
- -D "TEST_TARGET=${TARGET}"
- -D "TEST_EXECUTABLE=$"
- -D "TEST_EXECUTOR=${crosscompiling_emulator}"
- -D "TEST_WORKING_DIR=${_WORKING_DIRECTORY}"
- -D "TEST_SPEC=${_TEST_SPEC}"
- -D "TEST_EXTRA_ARGS=${_EXTRA_ARGS}"
- -D "TEST_PROPERTIES=${_PROPERTIES}"
- -D "TEST_PREFIX=${_TEST_PREFIX}"
- -D "TEST_SUFFIX=${_TEST_SUFFIX}"
- -D "TEST_LIST=${_TEST_LIST}"
- -D "TEST_REPORTER=${_REPORTER}"
- -D "TEST_OUTPUT_DIR=${_OUTPUT_DIR}"
- -D "TEST_OUTPUT_PREFIX=${_OUTPUT_PREFIX}"
- -D "TEST_OUTPUT_SUFFIX=${_OUTPUT_SUFFIX}"
- -D "CTEST_FILE=${ctest_tests_file}"
- -P "${_CATCH_DISCOVER_TESTS_SCRIPT}"
- VERBATIM
- )
-
- file(WRITE "${ctest_include_file}"
- "if(EXISTS \"${ctest_tests_file}\")\n"
- " include(\"${ctest_tests_file}\")\n"
- "else()\n"
- " add_test(${TARGET}_NOT_BUILT-${args_hash} ${TARGET}_NOT_BUILT-${args_hash})\n"
- "endif()\n"
- )
-
- if(NOT ${CMAKE_VERSION} VERSION_LESS "3.10.0")
- # Add discovered tests to directory TEST_INCLUDE_FILES
- set_property(DIRECTORY
- APPEND PROPERTY TEST_INCLUDE_FILES "${ctest_include_file}"
- )
- else()
- # Add discovered tests as directory TEST_INCLUDE_FILE if possible
- get_property(test_include_file_set DIRECTORY PROPERTY TEST_INCLUDE_FILE SET)
- if (NOT ${test_include_file_set})
- set_property(DIRECTORY
- PROPERTY TEST_INCLUDE_FILE "${ctest_include_file}"
- )
- else()
- message(FATAL_ERROR
- "Cannot set more than one TEST_INCLUDE_FILE"
- )
- endif()
- endif()
-
-endfunction()
-
-###############################################################################
-
-set(_CATCH_DISCOVER_TESTS_SCRIPT
- ${CMAKE_CURRENT_LIST_DIR}/CatchAddTests.cmake
- CACHE INTERNAL "Catch2 full path to CatchAddTests.cmake helper file"
-)
diff --git a/server/cmake/CatchAddTests.cmake b/server/cmake/CatchAddTests.cmake
deleted file mode 100644
index 18286b71..00000000
--- a/server/cmake/CatchAddTests.cmake
+++ /dev/null
@@ -1,132 +0,0 @@
-# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
-# file Copyright.txt or https://cmake.org/licensing for details.
-
-set(prefix "${TEST_PREFIX}")
-set(suffix "${TEST_SUFFIX}")
-set(spec ${TEST_SPEC})
-set(extra_args ${TEST_EXTRA_ARGS})
-set(properties ${TEST_PROPERTIES})
-set(reporter ${TEST_REPORTER})
-set(output_dir ${TEST_OUTPUT_DIR})
-set(output_prefix ${TEST_OUTPUT_PREFIX})
-set(output_suffix ${TEST_OUTPUT_SUFFIX})
-set(script)
-set(suite)
-set(tests)
-
-function(add_command NAME)
- set(_args "")
- foreach(_arg ${ARGN})
- if(_arg MATCHES "[^-./:a-zA-Z0-9_]")
- set(_args "${_args} [==[${_arg}]==]") # form a bracket_argument
- else()
- set(_args "${_args} ${_arg}")
- endif()
- endforeach()
- set(script "${script}${NAME}(${_args})\n" PARENT_SCOPE)
-endfunction()
-
-# Run test executable to get list of available tests
-if(NOT EXISTS "${TEST_EXECUTABLE}")
- message(FATAL_ERROR
- "Specified test executable '${TEST_EXECUTABLE}' does not exist"
- )
-endif()
-execute_process(
- COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" ${spec} --list-test-names-only
- OUTPUT_VARIABLE output
- RESULT_VARIABLE result
- WORKING_DIRECTORY "${TEST_WORKING_DIR}"
-)
-# Catch --list-test-names-only reports the number of tests, so 0 is... surprising
-if(${result} EQUAL 0)
- message(WARNING
- "Test executable '${TEST_EXECUTABLE}' contains no tests!\n"
- )
-elseif(${result} LESS 0)
- message(FATAL_ERROR
- "Error running test executable '${TEST_EXECUTABLE}':\n"
- " Result: ${result}\n"
- " Output: ${output}\n"
- )
-endif()
-
-string(REPLACE "\n" ";" output "${output}")
-
-# Run test executable to get list of available reporters
-execute_process(
- COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" ${spec} --list-reporters
- OUTPUT_VARIABLE reporters_output
- RESULT_VARIABLE reporters_result
- WORKING_DIRECTORY "${TEST_WORKING_DIR}"
-)
-if(${reporters_result} EQUAL 0)
- message(WARNING
- "Test executable '${TEST_EXECUTABLE}' contains no reporters!\n"
- )
-elseif(${reporters_result} LESS 0)
- message(FATAL_ERROR
- "Error running test executable '${TEST_EXECUTABLE}':\n"
- " Result: ${reporters_result}\n"
- " Output: ${reporters_output}\n"
- )
-endif()
-string(FIND "${reporters_output}" "${reporter}" reporter_is_valid)
-if(reporter AND ${reporter_is_valid} EQUAL -1)
- message(FATAL_ERROR
- "\"${reporter}\" is not a valid reporter!\n"
- )
-endif()
-
-# Prepare reporter
-if(reporter)
- set(reporter_arg "--reporter ${reporter}")
-endif()
-
-# Prepare output dir
-if(output_dir AND NOT IS_ABSOLUTE ${output_dir})
- set(output_dir "${TEST_WORKING_DIR}/${output_dir}")
- if(NOT EXISTS ${output_dir})
- file(MAKE_DIRECTORY ${output_dir})
- endif()
-endif()
-
-# Parse output
-foreach(line ${output})
- set(test ${line})
- # Escape characters in test case names that would be parsed by Catch2
- set(test_name ${test})
- foreach(char , [ ])
- string(REPLACE ${char} "\\${char}" test_name ${test_name})
- endforeach(char)
- # ...add output dir
- if(output_dir)
- string(REGEX REPLACE "[^A-Za-z0-9_]" "_" test_name_clean ${test_name})
- set(output_dir_arg "--out ${output_dir}/${output_prefix}${test_name_clean}${output_suffix}")
- endif()
-
- # ...and add to script
- add_command(add_test
- "${prefix}${test}${suffix}"
- ${TEST_EXECUTOR}
- "${TEST_EXECUTABLE}"
- "${test_name}"
- ${extra_args}
- "${reporter_arg}"
- "${output_dir_arg}"
- )
- add_command(set_tests_properties
- "${prefix}${test}${suffix}"
- PROPERTIES
- WORKING_DIRECTORY "${TEST_WORKING_DIR}"
- ${properties}
- )
- list(APPEND tests "${prefix}${test}${suffix}")
-endforeach()
-
-# Create a list of all discovered tests, which users may use to e.g. set
-# properties on the tests
-add_command(set ${TEST_LIST} ${tests})
-
-# Write CTest script
-file(WRITE "${CTEST_FILE}" "${script}")
diff --git a/server/src/board/tile/rail/turnout/turnoutrailtile.hpp b/server/src/board/tile/rail/turnout/turnoutrailtile.hpp
index 4e82d018..ce244fc7 100644
--- a/server/src/board/tile/rail/turnout/turnoutrailtile.hpp
+++ b/server/src/board/tile/rail/turnout/turnoutrailtile.hpp
@@ -28,7 +28,7 @@
#include "../../../map/node.hpp"
#include "../../../../core/objectproperty.hpp"
#include "../../../../core/method.hpp"
-#include "../../../../enum/turnoutposition.hpp"
+#include
#include "../../../../hardware/output/map/turnoutoutputmap.hpp"
class BlockPath;
diff --git a/server/src/core/attributes.hpp b/server/src/core/attributes.hpp
index 018fe590..0493e60a 100644
--- a/server/src/core/attributes.hpp
+++ b/server/src/core/attributes.hpp
@@ -80,7 +80,7 @@ struct Attributes
}
template
- static inline void addClassList(InterfaceItem& item, const std::array& classList)
+ static inline void addClassList(InterfaceItem& item, tcb::span classList)
{
item.addAttribute(AttributeName::ClassList, classList);
}
diff --git a/server/src/core/object.cpp b/server/src/core/object.cpp
index aab377c9..c78493e9 100644
--- a/server/src/core/object.cpp
+++ b/server/src/core/object.cpp
@@ -3,7 +3,7 @@
*
* This file is part of the traintastic source code.
*
- * Copyright (C) 2019-2021,2023 Reinder Feenstra
+ * Copyright (C) 2019-2021,2023-2024 Reinder Feenstra
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -23,6 +23,7 @@
#include "object.hpp"
#include "idobject.hpp"
#include "subobject.hpp"
+#include "abstractevent.hpp"
#include "abstractmethod.hpp"
#include "abstractproperty.hpp"
#include "abstractobjectproperty.hpp"
@@ -97,6 +98,16 @@ AbstractVectorProperty* Object::getVectorProperty(std::string_view name)
return dynamic_cast(getItem(name));
}
+const AbstractEvent* Object::getEvent(std::string_view name) const
+{
+ return dynamic_cast(getItem(name));
+}
+
+AbstractEvent* Object::getEvent(std::string_view name)
+{
+ return dynamic_cast(getItem(name));
+}
+
void Object::load(WorldLoader& loader, const nlohmann::json& data)
{
for(auto& [name, value] : data.items())
diff --git a/server/src/core/object.hpp b/server/src/core/object.hpp
index c04ceae7..a8d528c7 100644
--- a/server/src/core/object.hpp
+++ b/server/src/core/object.hpp
@@ -134,6 +134,8 @@ class Object : public std::enable_shared_from_this