mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2025-01-18 19:47:15 +01:00
Migrated the host module to C++ exceptions as well.
Also enabled the latest C++ revision in the project. Replaced the Random library with the one provided by C++11. Implemented a simple AES256 encryption class. Various other fixes and improvements.
This commit is contained in:
parent
3162221e7f
commit
70e5f0ba21
407
cbp/ModMMDB.cbp
Normal file
407
cbp/ModMMDB.cbp
Normal file
@ -0,0 +1,407 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<CodeBlocks_project_file>
|
||||
<FileVersion major="1" minor="6" />
|
||||
<Project>
|
||||
<Option title="Mod MMDB" />
|
||||
<Option pch_mode="2" />
|
||||
<Option compiler="gcc" />
|
||||
<Build>
|
||||
<Target title="Win32 Debug Dynamic">
|
||||
<Option output="../bin/win32-d/mod_mmdb32" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
|
||||
<Option working_dir="../bin/win32-d/" />
|
||||
<Option object_output="../obj/mingw32-d/" />
|
||||
<Option type="3" />
|
||||
<Option compiler="gcc" />
|
||||
<Compiler>
|
||||
<Add option="-m32" />
|
||||
<Add option="-g" />
|
||||
<Add option="-D_DEBUG" />
|
||||
<Add directory="../config/mingw32" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-m32" />
|
||||
<Add library="Ws2_32" />
|
||||
<Add directory="../lib/mingw32-d" />
|
||||
</Linker>
|
||||
<ExtraCommands>
|
||||
<Add after='cmd /c copy /Y "$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)" "$(PROJECT_DIR)..\bin\plugins\$(TARGET_OUTPUT_BASENAME).dll"' />
|
||||
</ExtraCommands>
|
||||
</Target>
|
||||
<Target title="Win32 Release Dynamic">
|
||||
<Option output="../bin/win32/mod_mmdb32" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
|
||||
<Option working_dir="../bin/win32/" />
|
||||
<Option object_output="../obj/mingw32/" />
|
||||
<Option type="3" />
|
||||
<Option compiler="gcc" />
|
||||
<Compiler>
|
||||
<Add option="-O3" />
|
||||
<Add option="-m32" />
|
||||
<Add option="-DNDEBUG" />
|
||||
<Add directory="../config/mingw32" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-s" />
|
||||
<Add option="-m32" />
|
||||
<Add library="Ws2_32" />
|
||||
<Add directory="../lib/mingw32" />
|
||||
</Linker>
|
||||
<ExtraCommands>
|
||||
<Add after='cmd /c copy /Y "$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)" "$(PROJECT_DIR)..\bin\plugins\$(TARGET_OUTPUT_BASENAME).dll"' />
|
||||
</ExtraCommands>
|
||||
</Target>
|
||||
<Target title="Win64 Debug Dynamic">
|
||||
<Option output="../bin/win64-d/mod_mmdb64" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
|
||||
<Option working_dir="../bin/win64-d/" />
|
||||
<Option object_output="../obj/mingw64-d/" />
|
||||
<Option type="3" />
|
||||
<Option compiler="gcc" />
|
||||
<Compiler>
|
||||
<Add option="-m64" />
|
||||
<Add option="-g" />
|
||||
<Add option="-D_DEBUG" />
|
||||
<Add option="-D_SQ64" />
|
||||
<Add directory="../config/mingw64" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-m64" />
|
||||
<Add library="Ws2_32" />
|
||||
<Add directory="../lib/mingw64-d" />
|
||||
</Linker>
|
||||
<ExtraCommands>
|
||||
<Add after='cmd /c copy /Y "$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)" "$(PROJECT_DIR)..\bin\plugins\$(TARGET_OUTPUT_BASENAME).dll"' />
|
||||
</ExtraCommands>
|
||||
</Target>
|
||||
<Target title="Win64 Release Dynamic">
|
||||
<Option output="../bin/win64/mod_mmdb64" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
|
||||
<Option working_dir="../bin/win64/" />
|
||||
<Option object_output="../obj/mingw64/" />
|
||||
<Option type="3" />
|
||||
<Option compiler="gcc" />
|
||||
<Compiler>
|
||||
<Add option="-O3" />
|
||||
<Add option="-m64" />
|
||||
<Add option="-DNDEBUG" />
|
||||
<Add option="-D_SQ64" />
|
||||
<Add directory="../config/mingw64" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-s" />
|
||||
<Add option="-m64" />
|
||||
<Add library="Ws2_32" />
|
||||
<Add directory="../lib/mingw64" />
|
||||
</Linker>
|
||||
<ExtraCommands>
|
||||
<Add after='cmd /c copy /Y "$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)" "$(PROJECT_DIR)..\bin\plugins\$(TARGET_OUTPUT_BASENAME).dll"' />
|
||||
</ExtraCommands>
|
||||
</Target>
|
||||
<Target title="Linux32 Debug Dynamic">
|
||||
<Option output="../bin/linux32-d/mod_mmdb32" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
|
||||
<Option working_dir="../bin/linux32-d/" />
|
||||
<Option object_output="../obj/gcc32-d/" />
|
||||
<Option type="3" />
|
||||
<Option compiler="gcc" />
|
||||
<Compiler>
|
||||
<Add option="-m32" />
|
||||
<Add option="-g" />
|
||||
<Add option="-fPIC" />
|
||||
<Add option="-D_DEBUG" />
|
||||
<Add directory="../config/gcc32" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-m32" />
|
||||
<Add directory="../lib/gcc32-d" />
|
||||
</Linker>
|
||||
</Target>
|
||||
<Target title="Linux32 Release Dynamic">
|
||||
<Option output="../bin/linux32/mod_mmdb32" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
|
||||
<Option working_dir="../bin/linux32/" />
|
||||
<Option object_output="../obj/gcc32/" />
|
||||
<Option type="3" />
|
||||
<Option compiler="gcc" />
|
||||
<Compiler>
|
||||
<Add option="-O3" />
|
||||
<Add option="-m32" />
|
||||
<Add option="-fPIC" />
|
||||
<Add option="-DNDEBUG" />
|
||||
<Add directory="../config/gcc32" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-s" />
|
||||
<Add option="-m32" />
|
||||
<Add directory="../lib/gcc32" />
|
||||
</Linker>
|
||||
</Target>
|
||||
<Target title="Linux64 Debug Dynamic">
|
||||
<Option output="../bin/linux64-d/mod_mmdb64" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
|
||||
<Option working_dir="../bin/linux64-d/" />
|
||||
<Option object_output="../obj/gcc64-d/" />
|
||||
<Option type="3" />
|
||||
<Option compiler="gcc" />
|
||||
<Compiler>
|
||||
<Add option="-m64" />
|
||||
<Add option="-g" />
|
||||
<Add option="-fPIC" />
|
||||
<Add option="-D_DEBUG" />
|
||||
<Add option="-D_SQ64" />
|
||||
<Add directory="../config/gcc64" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-m64" />
|
||||
<Add directory="../lib/gcc64-d" />
|
||||
</Linker>
|
||||
</Target>
|
||||
<Target title="Linux64 Release Dynamic">
|
||||
<Option output="../bin/linux64/mod_mmdb64" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
|
||||
<Option working_dir="../bin/linux64/" />
|
||||
<Option object_output="../obj/gcc64/" />
|
||||
<Option type="3" />
|
||||
<Option compiler="gcc" />
|
||||
<Compiler>
|
||||
<Add option="-O3" />
|
||||
<Add option="-m64" />
|
||||
<Add option="-fPIC" />
|
||||
<Add option="-DNDEBUG" />
|
||||
<Add option="-D_SQ64" />
|
||||
<Add directory="../config/gcc64" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-s" />
|
||||
<Add option="-m64" />
|
||||
<Add directory="../lib/gcc64" />
|
||||
</Linker>
|
||||
</Target>
|
||||
<Target title="Win32 Debug Standalone">
|
||||
<Option output="../bin/win32-d/mod_mmdb32" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
|
||||
<Option working_dir="../bin/win32-d/" />
|
||||
<Option object_output="../obj/mingw32-d/" />
|
||||
<Option type="3" />
|
||||
<Option compiler="gcc" />
|
||||
<Compiler>
|
||||
<Add option="-m32" />
|
||||
<Add option="-g" />
|
||||
<Add option="-static-libgcc" />
|
||||
<Add option="-static-libstdc++" />
|
||||
<Add option="-enable-static" />
|
||||
<Add option="-D_DEBUG" />
|
||||
<Add directory="../config/mingw32" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-m32" />
|
||||
<Add option="-static" />
|
||||
<Add library="Ws2_32" />
|
||||
<Add directory="../lib/mingw32-d" />
|
||||
</Linker>
|
||||
<ExtraCommands>
|
||||
<Add after='cmd /c copy /Y "$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)" "$(PROJECT_DIR)..\bin\plugins\$(TARGET_OUTPUT_BASENAME).dll"' />
|
||||
</ExtraCommands>
|
||||
</Target>
|
||||
<Target title="Win32 Release Standalone">
|
||||
<Option output="../bin/win32/mod_mmdb32" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
|
||||
<Option working_dir="../bin/win32/" />
|
||||
<Option object_output="../obj/mingw32/" />
|
||||
<Option type="3" />
|
||||
<Option compiler="gcc" />
|
||||
<Compiler>
|
||||
<Add option="-O3" />
|
||||
<Add option="-m32" />
|
||||
<Add option="-static-libgcc" />
|
||||
<Add option="-static-libstdc++" />
|
||||
<Add option="-enable-static" />
|
||||
<Add option="-DNDEBUG" />
|
||||
<Add directory="../config/mingw32" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-s" />
|
||||
<Add option="-m32" />
|
||||
<Add option="-static" />
|
||||
<Add library="Ws2_32" />
|
||||
<Add directory="../lib/mingw32" />
|
||||
</Linker>
|
||||
<ExtraCommands>
|
||||
<Add after='cmd /c copy /Y "$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)" "$(PROJECT_DIR)..\bin\plugins\$(TARGET_OUTPUT_BASENAME).dll"' />
|
||||
</ExtraCommands>
|
||||
</Target>
|
||||
<Target title="Win64 Debug Standalone">
|
||||
<Option output="../bin/win64-d/mod_mmdb64" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
|
||||
<Option working_dir="../bin/win64-d/" />
|
||||
<Option object_output="../obj/mingw64-d/" />
|
||||
<Option type="3" />
|
||||
<Option compiler="gcc" />
|
||||
<Compiler>
|
||||
<Add option="-m64" />
|
||||
<Add option="-g" />
|
||||
<Add option="-static-libgcc" />
|
||||
<Add option="-static-libstdc++" />
|
||||
<Add option="-enable-static" />
|
||||
<Add option="-D_DEBUG" />
|
||||
<Add option="-D_SQ64" />
|
||||
<Add directory="../config/mingw64" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-m64" />
|
||||
<Add option="-static" />
|
||||
<Add library="Ws2_32" />
|
||||
<Add directory="../lib/mingw64-d" />
|
||||
</Linker>
|
||||
<ExtraCommands>
|
||||
<Add after='cmd /c copy /Y "$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)" "$(PROJECT_DIR)..\bin\plugins\$(TARGET_OUTPUT_BASENAME).dll"' />
|
||||
</ExtraCommands>
|
||||
</Target>
|
||||
<Target title="Win64 Release Standalone">
|
||||
<Option output="../bin/win64/mod_mmdb64" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
|
||||
<Option working_dir="../bin/win64/" />
|
||||
<Option object_output="../obj/mingw64/" />
|
||||
<Option type="3" />
|
||||
<Option compiler="gcc" />
|
||||
<Compiler>
|
||||
<Add option="-O3" />
|
||||
<Add option="-m64" />
|
||||
<Add option="-static-libgcc" />
|
||||
<Add option="-static-libstdc++" />
|
||||
<Add option="-enable-static" />
|
||||
<Add option="-DNDEBUG" />
|
||||
<Add option="-D_SQ64" />
|
||||
<Add directory="../config/mingw64" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-s" />
|
||||
<Add option="-m64" />
|
||||
<Add option="-static" />
|
||||
<Add library="Ws2_32" />
|
||||
<Add directory="../lib/mingw64" />
|
||||
</Linker>
|
||||
<ExtraCommands>
|
||||
<Add after='cmd /c copy /Y "$(PROJECT_DIR)$(TARGET_OUTPUT_FILE)" "$(PROJECT_DIR)..\bin\plugins\$(TARGET_OUTPUT_BASENAME).dll"' />
|
||||
</ExtraCommands>
|
||||
</Target>
|
||||
<Target title="Linux32 Debug Standalone">
|
||||
<Option output="../bin/linux32-d/mod_mmdb32" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
|
||||
<Option working_dir="../bin/linux32-d/" />
|
||||
<Option object_output="../obj/gcc32-d/" />
|
||||
<Option type="3" />
|
||||
<Option compiler="gcc" />
|
||||
<Compiler>
|
||||
<Add option="-m32" />
|
||||
<Add option="-g" />
|
||||
<Add option="-static-libgcc" />
|
||||
<Add option="-static-libstdc++" />
|
||||
<Add option="-enable-static" />
|
||||
<Add option="-fPIC" />
|
||||
<Add option="-D_DEBUG" />
|
||||
<Add directory="../config/gcc32" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-m32" />
|
||||
<Add option="-Bstatic" />
|
||||
<Add directory="../lib/gcc32-d" />
|
||||
</Linker>
|
||||
</Target>
|
||||
<Target title="Linux32 Release Standalone">
|
||||
<Option output="../bin/linux32/mod_mmdb32" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
|
||||
<Option working_dir="../bin/linux32/" />
|
||||
<Option object_output="../obj/gcc32/" />
|
||||
<Option type="3" />
|
||||
<Option compiler="gcc" />
|
||||
<Compiler>
|
||||
<Add option="-O3" />
|
||||
<Add option="-m32" />
|
||||
<Add option="-static-libgcc" />
|
||||
<Add option="-static-libstdc++" />
|
||||
<Add option="-enable-static" />
|
||||
<Add option="-fPIC" />
|
||||
<Add option="-DNDEBUG" />
|
||||
<Add directory="../config/gcc32" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-s" />
|
||||
<Add option="-m32" />
|
||||
<Add option="-Bstatic" />
|
||||
<Add directory="../lib/gcc32" />
|
||||
</Linker>
|
||||
</Target>
|
||||
<Target title="Linux64 Debug Standalone">
|
||||
<Option output="../bin/linux64-d/mod_mmdb64" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
|
||||
<Option working_dir="../bin/linux64-d/" />
|
||||
<Option object_output="../obj/gcc64-d/" />
|
||||
<Option type="3" />
|
||||
<Option compiler="gcc" />
|
||||
<Compiler>
|
||||
<Add option="-m64" />
|
||||
<Add option="-g" />
|
||||
<Add option="-static-libgcc" />
|
||||
<Add option="-static-libstdc++" />
|
||||
<Add option="-enable-static" />
|
||||
<Add option="-fPIC" />
|
||||
<Add option="-D_DEBUG" />
|
||||
<Add option="-D_SQ64" />
|
||||
<Add directory="../config/gcc64" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-m64" />
|
||||
<Add option="-Bstatic" />
|
||||
<Add directory="../lib/gcc64-d" />
|
||||
</Linker>
|
||||
</Target>
|
||||
<Target title="Linux64 Release Standalone">
|
||||
<Option output="../bin/linux64/mod_mmdb64" imp_lib="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).a" def_file="$(TARGET_OUTPUT_DIR)$(TARGET_OUTPUT_BASENAME).def" prefix_auto="0" extension_auto="1" />
|
||||
<Option working_dir="../bin/linux64/" />
|
||||
<Option object_output="../obj/gcc64/" />
|
||||
<Option type="3" />
|
||||
<Option compiler="gcc" />
|
||||
<Compiler>
|
||||
<Add option="-O3" />
|
||||
<Add option="-m64" />
|
||||
<Add option="-static-libgcc" />
|
||||
<Add option="-static-libstdc++" />
|
||||
<Add option="-enable-static" />
|
||||
<Add option="-fPIC" />
|
||||
<Add option="-DNDEBUG" />
|
||||
<Add option="-D_SQ64" />
|
||||
<Add directory="../config/gcc64" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
<Add option="-s" />
|
||||
<Add option="-m64" />
|
||||
<Add option="-Bstatic" />
|
||||
<Add directory="../lib/gcc64" />
|
||||
</Linker>
|
||||
</Target>
|
||||
</Build>
|
||||
<Compiler>
|
||||
<Add option="-Wextra" />
|
||||
<Add option="-Wall" />
|
||||
<Add option="-std=c++14" />
|
||||
<Add option="-DSQMOD_PLUGIN_API" />
|
||||
<Add option="-DSCRAT_USE_EXCEPTIONS" />
|
||||
<Add option="-DSCRAT_USE_CXX11_OPTIMIZATIONS" />
|
||||
<Add directory="../modules/mmdb" />
|
||||
<Add directory="../shared" />
|
||||
<Add directory="../include" />
|
||||
<Add directory="../config/common" />
|
||||
<Add directory="../external/MaxmindDB" />
|
||||
</Compiler>
|
||||
<Unit filename="../external/MaxmindDB/maxminddb.c">
|
||||
<Option compilerVar="CC" />
|
||||
<Option compiler="gcc" use="1" buildCommand="$compiler -Wno-unused-parameter -Wno-sign-compare $options $includes -c $file -o $object" />
|
||||
</Unit>
|
||||
<Unit filename="../modules/mmdb/Common.cpp" />
|
||||
<Unit filename="../modules/mmdb/Common.hpp" />
|
||||
<Unit filename="../modules/mmdb/Database.cpp" />
|
||||
<Unit filename="../modules/mmdb/Database.hpp" />
|
||||
<Unit filename="../modules/mmdb/EntryDataList.cpp" />
|
||||
<Unit filename="../modules/mmdb/EntryDataList.hpp" />
|
||||
<Unit filename="../modules/mmdb/LookupResult.cpp" />
|
||||
<Unit filename="../modules/mmdb/LookupResult.hpp" />
|
||||
<Unit filename="../modules/mmdb/Module.cpp" />
|
||||
<Unit filename="../modules/mmdb/Module.hpp" />
|
||||
<Unit filename="../modules/mmdb/SockAddr.cpp" />
|
||||
<Unit filename="../modules/mmdb/SockAddr.hpp" />
|
||||
<Unit filename="../shared/SqMod.cpp" />
|
||||
<Extensions>
|
||||
<code_completion />
|
||||
<envvars />
|
||||
<debugger />
|
||||
<lib_finder disable_auto="1" />
|
||||
</Extensions>
|
||||
</Project>
|
||||
</CodeBlocks_project_file>
|
@ -362,6 +362,9 @@
|
||||
<Compiler>
|
||||
<Add option="-Wextra" />
|
||||
<Add option="-Wall" />
|
||||
<Add option="-std=c++14" />
|
||||
<Add option="-DSCRAT_USE_EXCEPTIONS" />
|
||||
<Add option="-DSCRAT_USE_CXX11_OPTIMIZATIONS" />
|
||||
<Add directory="../source" />
|
||||
<Add directory="../shared" />
|
||||
<Add directory="../include" />
|
||||
@ -372,6 +375,7 @@
|
||||
<Linker>
|
||||
<Add library="squirrel" />
|
||||
</Linker>
|
||||
<Unit filename="../external/Common/aes256.cpp" />
|
||||
<Unit filename="../external/Hash/crc32.cpp" />
|
||||
<Unit filename="../external/Hash/crc32.h" />
|
||||
<Unit filename="../external/Hash/digest.cpp" />
|
||||
@ -387,7 +391,6 @@
|
||||
<Unit filename="../external/Hash/sha256.h" />
|
||||
<Unit filename="../external/Hash/sha3.cpp" />
|
||||
<Unit filename="../external/Hash/sha3.h" />
|
||||
<Unit filename="../external/RandomLib/Random.cpp" />
|
||||
<Unit filename="../source/Base/AABB.cpp" />
|
||||
<Unit filename="../source/Base/AABB.hpp" />
|
||||
<Unit filename="../source/Base/Buffer.cpp" />
|
||||
@ -438,14 +441,14 @@
|
||||
<Unit filename="../source/Entity/Vehicle.cpp" />
|
||||
<Unit filename="../source/Entity/Vehicle.hpp" />
|
||||
<Unit filename="../source/Exports.cpp" />
|
||||
<Unit filename="../source/Library/Crypt.cpp" />
|
||||
<Unit filename="../source/Library/Crypt.hpp" />
|
||||
<Unit filename="../source/Library/Datetime.cpp" />
|
||||
<Unit filename="../source/Library/Datetime.hpp" />
|
||||
<Unit filename="../source/Library/FileIO.cpp" />
|
||||
<Unit filename="../source/Library/FileIO.hpp" />
|
||||
<Unit filename="../source/Library/Format.cpp" />
|
||||
<Unit filename="../source/Library/Format.hpp" />
|
||||
<Unit filename="../source/Library/Hashing.cpp" />
|
||||
<Unit filename="../source/Library/Hashing.hpp" />
|
||||
<Unit filename="../source/Library/Math.cpp" />
|
||||
<Unit filename="../source/Library/Math.hpp" />
|
||||
<Unit filename="../source/Library/Numeric.cpp" />
|
||||
|
@ -149,6 +149,7 @@
|
||||
</Build>
|
||||
<Compiler>
|
||||
<Add option="-Wall" />
|
||||
<Add option="-std=c++14" />
|
||||
<Add directory="../include" />
|
||||
<Add directory="../sandbox" />
|
||||
<Add directory="../source" />
|
||||
@ -160,6 +161,7 @@
|
||||
<Linker>
|
||||
<Add library="squirrel" />
|
||||
</Linker>
|
||||
<Unit filename="../external/Common/aes256.cpp" />
|
||||
<Unit filename="../sandbox/main.cpp" />
|
||||
<Extensions>
|
||||
<code_completion />
|
||||
|
@ -8,6 +8,7 @@
|
||||
<Project filename="ModIRC.cbp" />
|
||||
<Project filename="ModXML.cbp" />
|
||||
<Project filename="ModSQLite.cbp" />
|
||||
<Project filename="ModMMDB.cbp" />
|
||||
<Project filename="ModSample.cbp" />
|
||||
</Workspace>
|
||||
</CodeBlocks_workspace_file>
|
||||
|
193
config/mingw32/maxminddb_config.h
Normal file
193
config/mingw32/maxminddb_config.h
Normal file
@ -0,0 +1,193 @@
|
||||
/* include/maxminddb_config.h. Generated from maxminddb_config.h.in by configure. */
|
||||
#ifndef MAXMINDDB_CONFIG_H
|
||||
#define MAXMINDDB_CONFIG_H
|
||||
|
||||
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||
#define HAVE_ARPA_INET_H 1
|
||||
|
||||
/* Define to 1 if you have the <assert.h> header file. */
|
||||
#define HAVE_ASSERT_H 1
|
||||
|
||||
/* Define to 1 if the system has the type `boolean'. */
|
||||
/* #undef HAVE_BOOLEAN */
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#define HAVE_DLFCN_H 1
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H 1
|
||||
|
||||
/* Define to 1 if you have the `getpagesize' function. */
|
||||
#define HAVE_GETPAGESIZE 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <libgen.h> header file. */
|
||||
#define HAVE_LIBGEN_H 1
|
||||
|
||||
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
|
||||
to 0 otherwise. */
|
||||
#define HAVE_MALLOC 1
|
||||
|
||||
/* Define to 1 if you have the <math.h> header file. */
|
||||
#define HAVE_MATH_H 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have a working `mmap' system call. */
|
||||
#define HAVE_MMAP 1
|
||||
|
||||
/* Define to 1 if you have the <netdb.h> header file. */
|
||||
#define HAVE_NETDB_H 1
|
||||
|
||||
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||
#define HAVE_NETINET_IN_H 1
|
||||
|
||||
/* Has an open_memstream() function */
|
||||
#define HAVE_OPEN_MEMSTREAM 1
|
||||
|
||||
/* Define to 1 if you have the <stdarg.h> header file. */
|
||||
#define HAVE_STDARG_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdbool.h> header file. */
|
||||
#define HAVE_STDBOOL_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdio.h> header file. */
|
||||
#define HAVE_STDIO_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/mman.h> header file. */
|
||||
#define HAVE_SYS_MMAN_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||
#define HAVE_SYS_PARAM_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||
#define HAVE_SYS_SOCKET_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||
#define HAVE_SYS_TIME_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||
*/
|
||||
#define LT_OBJDIR ".libs/"
|
||||
|
||||
/* Missing the unsigned __int128 type */
|
||||
#define MMDB_UINT128_IS_BYTE_ARRAY 1
|
||||
|
||||
/* int128 types are available with __attribute__((mode(TI))) */
|
||||
/* #undef MMDB_UINT128_USING_MODE */
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "libmaxminddb"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT "support@maxmind.com"
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME "libmaxminddb"
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING "libmaxminddb 1.1.4"
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME "libmaxminddb"
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#define PACKAGE_URL ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION "1.1.4"
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "1.1.4"
|
||||
|
||||
/* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
|
||||
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
|
||||
#define below would cause a syntax error. */
|
||||
/* #undef _UINT32_T */
|
||||
|
||||
/* Define for Solaris 2.5.1 so the uint64_t typedef from <sys/synch.h>,
|
||||
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
|
||||
#define below would cause a syntax error. */
|
||||
/* #undef _UINT64_T */
|
||||
|
||||
/* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,
|
||||
<pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
|
||||
#define below would cause a syntax error. */
|
||||
/* #undef _UINT8_T */
|
||||
|
||||
/* Define to rpl_malloc if the replacement function should be used. */
|
||||
/* #undef malloc */
|
||||
|
||||
/* Define to `long int' if <sys/types.h> does not define. */
|
||||
/* #undef off_t */
|
||||
|
||||
/* Define to the equivalent of the C99 'restrict' keyword, or to
|
||||
nothing if this is not supported. Do not define if restrict is
|
||||
supported directly. */
|
||||
#define restrict __restrict
|
||||
/* Work around a bug in Sun C++: it does not support _Restrict or
|
||||
__restrict__, even though the corresponding Sun C compiler ends up with
|
||||
"#define restrict _Restrict" or "#define restrict __restrict__" in the
|
||||
previous line. Perhaps some future version of Sun C++ will work with
|
||||
restrict; if so, hopefully it defines __RESTRICT like Sun C does. */
|
||||
#if defined __SUNPRO_CC && !defined __RESTRICT
|
||||
# define _Restrict
|
||||
# define __restrict__
|
||||
#endif
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||
/* #undef size_t */
|
||||
|
||||
/* Define to `int' if <sys/types.h> does not define. */
|
||||
/* #undef ssize_t */
|
||||
|
||||
/* Define to the type of an unsigned integer type of width exactly 32 bits if
|
||||
such a type exists and the standard includes do not define it. */
|
||||
/* #undef uint32_t */
|
||||
|
||||
/* Define to the type of an unsigned integer type of width exactly 64 bits if
|
||||
such a type exists and the standard includes do not define it. */
|
||||
/* #undef uint64_t */
|
||||
|
||||
/* Define to the type of an unsigned integer type of width exactly 8 bits if
|
||||
such a type exists and the standard includes do not define it. */
|
||||
/* #undef uint8_t */
|
||||
|
||||
#ifndef MMDB_UINT128_USING_MODE
|
||||
/* Define as 1 if we we use unsigned int __atribute__ ((__mode__(TI))) for uint128 values */
|
||||
#define MMDB_UINT128_USING_MODE 0
|
||||
#endif
|
||||
|
||||
#ifndef MMDB_UINT128_IS_BYTE_ARRAY
|
||||
/* Define as 1 if we don't have an unsigned __int128 type */
|
||||
#define MMDB_UINT128_IS_BYTE_ARRAY 0
|
||||
#endif
|
||||
|
||||
#endif /* MAXMINDDB_CONFIG_H */
|
407
external/Common/aes256.cpp
vendored
Normal file
407
external/Common/aes256.cpp
vendored
Normal file
@ -0,0 +1,407 @@
|
||||
/*
|
||||
* Byte-oriented AES-256 implementation.
|
||||
* All lookup tables replaced with 'on the fly' calculations.
|
||||
*
|
||||
* Copyright (c) 2007-2011 Ilya O. Levin, http://www.literatecode.com
|
||||
* Other contributors: Hal Finney
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include "aes256.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define FD(x) (((x) >> 1) ^ (((x) & 1) ? 0x8d : 0))
|
||||
|
||||
#define BACK_TO_TABLES
|
||||
|
||||
static uint8_t rj_xtime(uint8_t);
|
||||
static void aes_subBytes(uint8_t *);
|
||||
static void aes_subBytes_inv(uint8_t *);
|
||||
static void aes_addRoundKey(uint8_t *, uint8_t *);
|
||||
static void aes_addRoundKey_cpy(uint8_t *, uint8_t *, uint8_t *);
|
||||
static void aes_shiftRows(uint8_t *);
|
||||
static void aes_shiftRows_inv(uint8_t *);
|
||||
static void aes_mixColumns(uint8_t *);
|
||||
static void aes_mixColumns_inv(uint8_t *);
|
||||
static void aes_expandEncKey(uint8_t *, uint8_t *);
|
||||
static void aes_expandDecKey(uint8_t *, uint8_t *);
|
||||
#ifndef BACK_TO_TABLES
|
||||
static uint8_t gf_alog(uint8_t);
|
||||
static uint8_t gf_log(uint8_t);
|
||||
static uint8_t gf_mulinv(uint8_t);
|
||||
static uint8_t rj_sbox(uint8_t);
|
||||
static uint8_t rj_sbox_inv(uint8_t);
|
||||
#endif
|
||||
|
||||
#ifdef BACK_TO_TABLES
|
||||
|
||||
static const uint8_t sbox[256] =
|
||||
{
|
||||
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
|
||||
0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
|
||||
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
|
||||
0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
|
||||
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
|
||||
0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
|
||||
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
|
||||
0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
|
||||
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
|
||||
0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
|
||||
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
|
||||
0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
|
||||
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
|
||||
0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
|
||||
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
|
||||
0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
|
||||
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
|
||||
0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
|
||||
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
|
||||
0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
|
||||
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
|
||||
0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
|
||||
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
|
||||
0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
|
||||
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
|
||||
0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
|
||||
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
|
||||
0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
|
||||
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
|
||||
0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
|
||||
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
|
||||
0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
|
||||
};
|
||||
static const uint8_t sboxinv[256] =
|
||||
{
|
||||
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
|
||||
0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
|
||||
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
|
||||
0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
|
||||
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
|
||||
0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
|
||||
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
|
||||
0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
|
||||
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
|
||||
0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
|
||||
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
|
||||
0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
|
||||
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
|
||||
0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
|
||||
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
|
||||
0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
|
||||
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
|
||||
0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
|
||||
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
|
||||
0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
|
||||
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
|
||||
0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
|
||||
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
|
||||
0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
|
||||
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
|
||||
0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
|
||||
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
|
||||
0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
|
||||
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
|
||||
0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
|
||||
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
|
||||
0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
|
||||
};
|
||||
|
||||
#define rj_sbox(x) sbox[(x)]
|
||||
#define rj_sbox_inv(x) sboxinv[(x)]
|
||||
|
||||
#else /* tableless subroutines */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
static uint8_t gf_alog(uint8_t x) // calculate anti-logarithm gen 3
|
||||
{
|
||||
uint8_t y = 1, i;
|
||||
|
||||
for (i = 0; i < x; i++) y ^= rj_xtime(y);
|
||||
|
||||
return y;
|
||||
} /* gf_alog */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
static uint8_t gf_log(uint8_t x) // calculate logarithm gen 3
|
||||
{
|
||||
uint8_t y, i = 0;
|
||||
|
||||
if (x)
|
||||
for (i = 1, y = 1; i > 0; i++ )
|
||||
{
|
||||
y ^= rj_xtime(y);
|
||||
if (y == x) break;
|
||||
}
|
||||
|
||||
return i;
|
||||
} /* gf_log */
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
static uint8_t gf_mulinv(uint8_t x) // calculate multiplicative inverse
|
||||
{
|
||||
return (x) ? gf_alog(255 - gf_log(x)) : 0;
|
||||
} /* gf_mulinv */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
static uint8_t rj_sbox(uint8_t x)
|
||||
{
|
||||
uint8_t y, sb;
|
||||
|
||||
sb = y = gf_mulinv(x);
|
||||
y = (uint8_t)(y << 1) | (y >> 7), sb ^= y;
|
||||
y = (uint8_t)(y << 1) | (y >> 7), sb ^= y;
|
||||
y = (uint8_t)(y << 1) | (y >> 7), sb ^= y;
|
||||
y = (uint8_t)(y << 1) | (y >> 7), sb ^= y;
|
||||
|
||||
return (sb ^ 0x63);
|
||||
} /* rj_sbox */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
static uint8_t rj_sbox_inv(uint8_t x)
|
||||
{
|
||||
uint8_t y, sb;
|
||||
|
||||
y = x ^ 0x63;
|
||||
sb = y = (uint8_t)(y << 1) | (y >> 7);
|
||||
y = (uint8_t)(y << 2) | (y >> 6);
|
||||
sb ^= y;
|
||||
y = (uint8_t)(y << 3) | (y >> 5);
|
||||
sb ^= y;
|
||||
|
||||
return gf_mulinv(sb);
|
||||
} /* rj_sbox_inv */
|
||||
|
||||
#endif
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
static uint8_t rj_xtime(uint8_t x)
|
||||
{
|
||||
uint8_t y = (uint8_t)(x << 1);
|
||||
return (x & 0x80) ? (y ^ 0x1b) : y;
|
||||
} /* rj_xtime */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
static void aes_subBytes(uint8_t *buf)
|
||||
{
|
||||
register uint8_t i = 16;
|
||||
|
||||
while (i--) buf[i] = rj_sbox(buf[i]);
|
||||
} /* aes_subBytes */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
static void aes_subBytes_inv(uint8_t *buf)
|
||||
{
|
||||
register uint8_t i = 16;
|
||||
|
||||
while (i--) buf[i] = rj_sbox_inv(buf[i]);
|
||||
} /* aes_subBytes_inv */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
static void aes_addRoundKey(uint8_t *buf, uint8_t *key)
|
||||
{
|
||||
register uint8_t i = 16;
|
||||
|
||||
while (i--) buf[i] ^= key[i];
|
||||
} /* aes_addRoundKey */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
static void aes_addRoundKey_cpy(uint8_t *buf, uint8_t *key, uint8_t *cpk)
|
||||
{
|
||||
register uint8_t i = 16;
|
||||
|
||||
while (i--) buf[i] ^= (cpk[i] = key[i]), cpk[16 + i] = key[16 + i];
|
||||
} /* aes_addRoundKey_cpy */
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
static void aes_shiftRows(uint8_t *buf)
|
||||
{
|
||||
register uint8_t i, j; /* to make it potentially parallelable :) */
|
||||
|
||||
i = buf[1], buf[1] = buf[5], buf[5] = buf[9], buf[9] = buf[13], buf[13] = i;
|
||||
i = buf[10], buf[10] = buf[2], buf[2] = i;
|
||||
j = buf[3], buf[3] = buf[15], buf[15] = buf[11], buf[11] = buf[7], buf[7] = j;
|
||||
j = buf[14], buf[14] = buf[6], buf[6] = j;
|
||||
|
||||
} /* aes_shiftRows */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
static void aes_shiftRows_inv(uint8_t *buf)
|
||||
{
|
||||
register uint8_t i, j; /* same as above :) */
|
||||
|
||||
i = buf[1], buf[1] = buf[13], buf[13] = buf[9], buf[9] = buf[5], buf[5] = i;
|
||||
i = buf[2], buf[2] = buf[10], buf[10] = i;
|
||||
j = buf[3], buf[3] = buf[7], buf[7] = buf[11], buf[11] = buf[15], buf[15] = j;
|
||||
j = buf[6], buf[6] = buf[14], buf[14] = j;
|
||||
|
||||
} /* aes_shiftRows_inv */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
static void aes_mixColumns(uint8_t *buf)
|
||||
{
|
||||
register uint8_t i, a, b, c, d, e;
|
||||
|
||||
for (i = 0; i < 16; i += 4)
|
||||
{
|
||||
a = buf[i];
|
||||
b = buf[i + 1];
|
||||
c = buf[i + 2];
|
||||
d = buf[i + 3];
|
||||
e = a ^ b ^ c ^ d;
|
||||
buf[i] ^= e ^ rj_xtime(a ^ b);
|
||||
buf[i + 1] ^= e ^ rj_xtime(b ^ c);
|
||||
buf[i + 2] ^= e ^ rj_xtime(c ^ d);
|
||||
buf[i + 3] ^= e ^ rj_xtime(d ^ a);
|
||||
}
|
||||
} /* aes_mixColumns */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
void aes_mixColumns_inv(uint8_t *buf)
|
||||
{
|
||||
register uint8_t i, a, b, c, d, e, x, y, z;
|
||||
|
||||
for (i = 0; i < 16; i += 4)
|
||||
{
|
||||
a = buf[i];
|
||||
b = buf[i + 1];
|
||||
c = buf[i + 2];
|
||||
d = buf[i + 3];
|
||||
e = a ^ b ^ c ^ d;
|
||||
z = rj_xtime(e);
|
||||
x = e ^ rj_xtime(rj_xtime(z ^ a ^ c));
|
||||
y = e ^ rj_xtime(rj_xtime(z ^ b ^ d));
|
||||
buf[i] ^= x ^ rj_xtime(a ^ b);
|
||||
buf[i + 1] ^= y ^ rj_xtime(b ^ c);
|
||||
buf[i + 2] ^= x ^ rj_xtime(c ^ d);
|
||||
buf[i + 3] ^= y ^ rj_xtime(d ^ a);
|
||||
}
|
||||
} /* aes_mixColumns_inv */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
static void aes_expandEncKey(uint8_t *k, uint8_t *rc)
|
||||
{
|
||||
register uint8_t i;
|
||||
|
||||
k[0] ^= rj_sbox(k[29]) ^ (*rc);
|
||||
k[1] ^= rj_sbox(k[30]);
|
||||
k[2] ^= rj_sbox(k[31]);
|
||||
k[3] ^= rj_sbox(k[28]);
|
||||
*rc = rj_xtime( *rc);
|
||||
|
||||
for(i = 4; i < 16; i += 4) k[i] ^= k[i - 4], k[i + 1] ^= k[i - 3],
|
||||
k[i + 2] ^= k[i - 2], k[i + 3] ^= k[i - 1];
|
||||
k[16] ^= rj_sbox(k[12]);
|
||||
k[17] ^= rj_sbox(k[13]);
|
||||
k[18] ^= rj_sbox(k[14]);
|
||||
k[19] ^= rj_sbox(k[15]);
|
||||
|
||||
for(i = 20; i < 32; i += 4) k[i] ^= k[i - 4], k[i + 1] ^= k[i - 3],
|
||||
k[i + 2] ^= k[i - 2], k[i + 3] ^= k[i - 1];
|
||||
|
||||
} /* aes_expandEncKey */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
void aes_expandDecKey(uint8_t *k, uint8_t *rc)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
for(i = 28; i > 16; i -= 4) k[i + 0] ^= k[i - 4], k[i + 1] ^= k[i - 3],
|
||||
k[i + 2] ^= k[i - 2], k[i + 3] ^= k[i - 1];
|
||||
|
||||
k[16] ^= rj_sbox(k[12]);
|
||||
k[17] ^= rj_sbox(k[13]);
|
||||
k[18] ^= rj_sbox(k[14]);
|
||||
k[19] ^= rj_sbox(k[15]);
|
||||
|
||||
for(i = 12; i > 0; i -= 4) k[i + 0] ^= k[i - 4], k[i + 1] ^= k[i - 3],
|
||||
k[i + 2] ^= k[i - 2], k[i + 3] ^= k[i - 1];
|
||||
|
||||
*rc = FD(*rc);
|
||||
k[0] ^= rj_sbox(k[29]) ^ (*rc);
|
||||
k[1] ^= rj_sbox(k[30]);
|
||||
k[2] ^= rj_sbox(k[31]);
|
||||
k[3] ^= rj_sbox(k[28]);
|
||||
} /* aes_expandDecKey */
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
void aes256_init(aes256_context *ctx, uint8_t *k)
|
||||
{
|
||||
uint8_t rcon = 1;
|
||||
register uint8_t i;
|
||||
|
||||
for (i = 0; i < sizeof(ctx->key); i++) ctx->enckey[i] = ctx->deckey[i] = k[i];
|
||||
for (i = 8; --i;) aes_expandEncKey(ctx->deckey, &rcon);
|
||||
} /* aes256_init */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
void aes256_done(aes256_context *ctx)
|
||||
{
|
||||
register uint8_t i;
|
||||
|
||||
for (i = 0; i < sizeof(ctx->key); i++)
|
||||
ctx->key[i] = ctx->enckey[i] = ctx->deckey[i] = 0;
|
||||
} /* aes256_done */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
void aes256_encrypt_ecb(aes256_context *ctx, uint8_t *buf)
|
||||
{
|
||||
uint8_t i, rcon;
|
||||
|
||||
aes_addRoundKey_cpy(buf, ctx->enckey, ctx->key);
|
||||
for(i = 1, rcon = 1; i < 14; ++i)
|
||||
{
|
||||
aes_subBytes(buf);
|
||||
aes_shiftRows(buf);
|
||||
aes_mixColumns(buf);
|
||||
if( i & 1 ) aes_addRoundKey( buf, &ctx->key[16]);
|
||||
else aes_expandEncKey(ctx->key, &rcon), aes_addRoundKey(buf, ctx->key);
|
||||
}
|
||||
aes_subBytes(buf);
|
||||
aes_shiftRows(buf);
|
||||
aes_expandEncKey(ctx->key, &rcon);
|
||||
aes_addRoundKey(buf, ctx->key);
|
||||
} /* aes256_encrypt */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
void aes256_decrypt_ecb(aes256_context *ctx, uint8_t *buf)
|
||||
{
|
||||
uint8_t i, rcon;
|
||||
|
||||
aes_addRoundKey_cpy(buf, ctx->deckey, ctx->key);
|
||||
aes_shiftRows_inv(buf);
|
||||
aes_subBytes_inv(buf);
|
||||
|
||||
for (i = 14, rcon = 0x80; --i;)
|
||||
{
|
||||
if( ( i & 1 ) )
|
||||
{
|
||||
aes_expandDecKey(ctx->key, &rcon);
|
||||
aes_addRoundKey(buf, &ctx->key[16]);
|
||||
}
|
||||
else aes_addRoundKey(buf, ctx->key);
|
||||
aes_mixColumns_inv(buf);
|
||||
aes_shiftRows_inv(buf);
|
||||
aes_subBytes_inv(buf);
|
||||
}
|
||||
aes_addRoundKey( buf, ctx->key);
|
||||
} /* aes256_decrypt */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
202
external/MaxmindDB/LICENSE
vendored
Normal file
202
external/MaxmindDB/LICENSE
vendored
Normal file
@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
167
external/MaxmindDB/maxminddb-compat-util.h
vendored
Normal file
167
external/MaxmindDB/maxminddb-compat-util.h
vendored
Normal file
@ -0,0 +1,167 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
|
||||
/* The memmem, strdup, and strndup functions were all copied from the
|
||||
* FreeBSD source, along with the relevant copyright notice.
|
||||
*
|
||||
* It'd be nicer to simply use the functions available on the system if they
|
||||
* exist, but there doesn't seem to be a good way to detect them without also
|
||||
* defining things like _GNU_SOURCE, which we want to avoid, because then we
|
||||
* end up _accidentally_ using GNU features without noticing, which then
|
||||
* breaks on systems like OSX.
|
||||
*
|
||||
* C is fun! */
|
||||
|
||||
/* Applies to memmem implementation */
|
||||
/*-
|
||||
* Copyright (c) 2005 Pascal Gloor <pascal.gloor@spale.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote
|
||||
* products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
static void *
|
||||
mmdb_memmem(const void *l, size_t l_len, const void *s, size_t s_len)
|
||||
{
|
||||
register char *cur, *last;
|
||||
const char *cl = (const char *)l;
|
||||
const char *cs = (const char *)s;
|
||||
|
||||
/* we need something to compare */
|
||||
if (l_len == 0 || s_len == 0)
|
||||
return NULL;
|
||||
|
||||
/* "s" must be smaller or equal to "l" */
|
||||
if (l_len < s_len)
|
||||
return NULL;
|
||||
|
||||
/* special case where s_len == 1 */
|
||||
if (s_len == 1)
|
||||
return memchr(l, (int)*cs, l_len);
|
||||
|
||||
/* the last position where its possible to find "s" in "l" */
|
||||
last = (char *)cl + l_len - s_len;
|
||||
|
||||
for (cur = (char *)cl; cur <= last; cur++)
|
||||
if (cur[0] == cs[0] && memcmp(cur, cs, s_len) == 0)
|
||||
return cur;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Applies to strnlen implementation */
|
||||
/*-
|
||||
* Copyright (c) 2009 David Schultz <das@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
static size_t
|
||||
mmdb_strnlen(const char *s, size_t maxlen)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
for (len = 0; len < maxlen; len++, s++) {
|
||||
if (!*s)
|
||||
break;
|
||||
}
|
||||
return (len);
|
||||
}
|
||||
|
||||
/* Applies to strdup and strndup implementation */
|
||||
/*
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
static char *
|
||||
mmdb_strdup(const char *str)
|
||||
{
|
||||
size_t len;
|
||||
char *copy;
|
||||
|
||||
len = strlen(str) + 1;
|
||||
if ((copy = malloc(len)) == NULL)
|
||||
return (NULL);
|
||||
memcpy(copy, str, len);
|
||||
return (copy);
|
||||
}
|
||||
|
||||
static char *
|
||||
mmdb_strndup(const char *str, size_t n)
|
||||
{
|
||||
size_t len;
|
||||
char *copy;
|
||||
|
||||
len = mmdb_strnlen(str, n);
|
||||
if ((copy = malloc(len + 1)) == NULL)
|
||||
return (NULL);
|
||||
memcpy(copy, str, len);
|
||||
copy[len] = '\0';
|
||||
return (copy);
|
||||
}
|
||||
/* *INDENT-ON* */
|
2045
external/MaxmindDB/maxminddb.c
vendored
Normal file
2045
external/MaxmindDB/maxminddb.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
23
external/RandomLib/LICENSE.txt
vendored
23
external/RandomLib/LICENSE.txt
vendored
@ -1,23 +0,0 @@
|
||||
This license applies to RandomLib, versions 1.2 and later.
|
||||
|
||||
Copyright (c) 2006-2013, Charles Karney
|
||||
|
||||
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.
|
1405
external/RandomLib/Random.cpp
vendored
1405
external/RandomLib/Random.cpp
vendored
File diff suppressed because it is too large
Load Diff
@ -1,13 +0,0 @@
|
||||
#define RANDOMLIB_VERSION_STRING "Unconfigured"
|
||||
#define RANDOMLIB_VERSION_MAJOR -1
|
||||
#define RANDOMLIB_VERSION_MINOR -1
|
||||
#define RANDOMLIB_VERSION_PATCH -1
|
||||
|
||||
// Define HAVE_SSE2 to be 1 if Intel/AMD CPU with SSE2 support
|
||||
/* #undef HAVE_SSE2 */
|
||||
|
||||
// Define HAVE_ALTIVEC to be 1 if Power PC CPU with AltiVec support
|
||||
/* #undef HAVE_ALTIVEC */
|
||||
|
||||
// Undefine HAVE_LONG_DOUBLE if this type is unknown to the compiler
|
||||
#define HAVE_LONG_DOUBLE 1
|
@ -1,432 +0,0 @@
|
||||
/**
|
||||
* \file DiscreteNormal.hpp
|
||||
* \brief Header for DiscreteNormal
|
||||
*
|
||||
* Sample exactly from the discrete normal distribution.
|
||||
*
|
||||
* Copyright (c) Charles Karney (2013) <charles@karney.com> and licensed
|
||||
* under the MIT/X11 License. For more information, see
|
||||
* http://randomlib.sourceforge.net/
|
||||
**********************************************************************/
|
||||
|
||||
#if !defined(RANDOMLIB_DISCRETENORMAL_HPP)
|
||||
#define RANDOMLIB_DISCRETENORMAL_HPP 1
|
||||
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
|
||||
namespace RandomLib {
|
||||
/**
|
||||
* \brief The discrete normal distribution.
|
||||
*
|
||||
* Sample integers \e i with probability proportional to
|
||||
* \f[
|
||||
* \exp\biggl[-\frac12\biggl(\frac{i-\mu}{\sigma}\biggr)^2\biggr],
|
||||
* \f]
|
||||
* where σ and μ are given as rationals (the ratio of two integers).
|
||||
* The sampling is exact (provided that the random generator is ideal). For
|
||||
* example
|
||||
* \code
|
||||
#include <iostream>
|
||||
#include <RandomLib/Random.hpp>
|
||||
#include <RandomLib/DiscreteNormal.hpp>
|
||||
|
||||
int main() {
|
||||
RandomLib::Random r; // Create r
|
||||
r.Reseed(); // and give it a unique seed
|
||||
int sigma_num = 7, sigma_den = 1, mu_num = 1, mu_den = 3;
|
||||
RandomLib::DiscreteNormal<int> d(sigma_num, sigma_den,
|
||||
mu_num, mu_den);
|
||||
for (int i = 0; i < 100; ++i)
|
||||
std::cout << d(r) << "\n";
|
||||
}
|
||||
\endcode
|
||||
* prints out 100 samples with σ = 7 and μ = 1/3.
|
||||
*
|
||||
* The algorithm is much the same as for ExactNormal; for details see
|
||||
* - C. F. F. Karney, <i>Sampling exactly from the normal distribution</i>,
|
||||
* http://arxiv.org/abs/1303.6257 (Mar. 2013).
|
||||
* .
|
||||
* That algorithm samples the integer part of the result \e k, samples \e x
|
||||
* in [0,1], and (unless rejected) returns <i>s</i>(\e k + \e x), where \e s
|
||||
* = ±1. For the discrete case, we sample \e x in [0,1) such that
|
||||
* \f[
|
||||
* s(k + x) = (i - \mu)/\sigma,
|
||||
* \f]
|
||||
* or
|
||||
* \f[
|
||||
* x = s(i - \mu)/\sigma - k
|
||||
* \f]
|
||||
* The value of \e i which results in the smallest \e x ≥ 0 is
|
||||
* \f[
|
||||
* i_0 = s\lceil k \sigma + s \mu\rceil
|
||||
* \f]
|
||||
* so sample
|
||||
* \f[
|
||||
* i = i_0 + sj
|
||||
* \f]
|
||||
* where \e j is uniformly distributed in [0, ⌈σ⌉). The
|
||||
* corresponding value of \e x is
|
||||
* \f[
|
||||
* \begin{aligned}
|
||||
* x &= \bigl(si_0 - (k\sigma + s\mu)\bigr)/\sigma + j/\sigma\\
|
||||
* &= x_0 + j/\sigma,\\
|
||||
* x_0 &= \bigl(\lceil k \sigma + s \mu\rceil -
|
||||
* (k \sigma + s \mu)\bigr)/\sigma.
|
||||
* \end{aligned}
|
||||
* \f]
|
||||
* After \e x is sampled in this way, it should be rejected if \e x ≥ 1
|
||||
* (this is counted with the next larger value of \e k) or if \e x = 0, \e k
|
||||
* = 0, and \e s = −1 (to avoid double counting the origin). If \e x
|
||||
* is accepted (in Step 4 of the ExactNormal algorithm), then return \e i.
|
||||
*
|
||||
* When σ and μ are given as rationals, all the arithmetic outlined
|
||||
* above can be carried out exactly. The basic rejection techniques used by
|
||||
* ExactNormal are exact. Thus the result of this discrete form of the
|
||||
* algorithm is also exact.
|
||||
*
|
||||
* RandomLib provides two classes to sample from this distribution:
|
||||
* - DiscreteNormal which is tuned for speed on a typical general purpose
|
||||
* computer. This assumes that random samples can be generated relatively
|
||||
* quickly.
|
||||
* - DiscreteNormalAlt, which is a prototype for what might be needed on a
|
||||
* small device used for cryptography which is using a hardware generator
|
||||
* for obtaining truly random bits. This assumption here is that the
|
||||
* random bits are relatively expensive to obtain.
|
||||
* .
|
||||
|
||||
* The basic algorithm is the same in the two cases. The main advantages of
|
||||
* this method are:
|
||||
* - exact sampling (provided that the source of random numbers is ideal),
|
||||
* - no need to cut off the tails of the distribution,
|
||||
* - a short program involving simple integer operations only,
|
||||
* - no dependence on external libraries (except to generate random bits),
|
||||
* - no large tables of constants needed,
|
||||
* - minimal time to set up for a new σ and μ (roughly comparable to
|
||||
* the time it takes to generate one sample),
|
||||
* - only about 5–20 times slower than standard routines to sample from
|
||||
* a normal distribution using plain double-precision arithmetic.
|
||||
* - DiscreteNormalAlt exhibits ideal scaling for the consumption of random
|
||||
* bits, namely a constant + log<sub>2</sub>σ, for large σ,
|
||||
* where the constant is about 31.
|
||||
* .
|
||||
* The possible drawbacks of this method are:
|
||||
* - σ and μ are restricted to rational numbers with sufficiently
|
||||
* small numerators and denominators to avoid overflow (this is unlikely to
|
||||
* be a severe restriction especially if the template parameter IntType is
|
||||
* set to <code>long long</code>),
|
||||
* - the running time is unbounded (but not in any practical sense),
|
||||
* - the memory consumption is unbounded (but not in any practical sense),
|
||||
* - the toll, about 30 bits, is considerably worse than that obtained using
|
||||
* the Knuth-Yao algorithm, for which the toll is no more than 2 (but this
|
||||
* requires a large table which is expensive to compute and requires a lot
|
||||
* of memory to store).
|
||||
*
|
||||
* This class uses a mutable private vector. So a single DiscreteNormal
|
||||
* object cannot safely be used by multiple threads. In a multi-processing
|
||||
* environment, each thread should use a thread-specific DiscreteNormal
|
||||
* object.
|
||||
*
|
||||
* Some timing results for IntType = int, μ = 0, and 10<sup>8</sup>
|
||||
* samples (time = time per sample, including setup time, rv = mean number of
|
||||
* random variables per sample)
|
||||
* - σ = 10, time = 219 ns, rv = 17.52
|
||||
* - σ = 32, time = 223 ns, rv = 17.82
|
||||
* - σ = 1000, time = 225 ns, rv = 17.95
|
||||
* - σ = 160000, time = 226 ns, rv = 17.95
|
||||
*
|
||||
* @tparam IntType the integer type to use (default int).
|
||||
**********************************************************************/
|
||||
template<typename IntType = int> class DiscreteNormal {
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param[in] sigma_num the numerator of σ.
|
||||
* @param[in] sigma_den the denominator of σ (default 1).
|
||||
* @param[in] mu_num the numerator of μ (default 0).
|
||||
* @param[in] mu_den the denominator of μ (default 1).
|
||||
*
|
||||
* The constructor creates a DiscreteNormal objects for sampling with
|
||||
* specific values of σ and μ. This may throw an exception if the
|
||||
* parameters are such that overflow is possible. Internally σ and
|
||||
* μ are expressed with a common denominator, so it may be possible to
|
||||
* avoid overflow by picking the fractions of these quantities so that \e
|
||||
* sigma_den and \e mu_den have many common factors.
|
||||
**********************************************************************/
|
||||
DiscreteNormal(IntType sigma_num, IntType sigma_den = 1,
|
||||
IntType mu_num = 0, IntType mu_den = 1);
|
||||
/**
|
||||
* Return a sample.
|
||||
*
|
||||
* @tparam Random the type of the random generator.
|
||||
* @param[in,out] r a random generator.
|
||||
* @return discrete normal integer.
|
||||
**********************************************************************/
|
||||
template<class Random>
|
||||
IntType operator()(Random& r) const;
|
||||
private:
|
||||
/**
|
||||
* sigma = _sig / _d, mu = _imu + _mu / _d, _isig = floor(sigma)
|
||||
**********************************************************************/
|
||||
IntType _sig, _mu, _d, _isig, _imu;
|
||||
typedef unsigned short word;
|
||||
/**
|
||||
* Holds as much of intermediate uniform deviates as needed.
|
||||
**********************************************************************/
|
||||
mutable std::vector<word> _v;
|
||||
mutable unsigned _m, _l;
|
||||
/**
|
||||
* Increment on size of _v.
|
||||
**********************************************************************/
|
||||
static const unsigned alloc_incr = 16;
|
||||
|
||||
// ceil(n/d) for d > 0
|
||||
static IntType iceil(IntType n, IntType d);
|
||||
// abs(n) needed because Visual Studio's std::abs has problems
|
||||
static IntType iabs(IntType n);
|
||||
static IntType gcd(IntType u, IntType v);
|
||||
|
||||
// After x = LeadingDigit(p), p/_sig = (x + p'/_sig)/b where p and p' are
|
||||
// in [0, _sig) and b = 1 + max(word).
|
||||
word LeadingDigit(IntType& p) const;
|
||||
|
||||
/**
|
||||
* Implement outcomes for choosing with prob (\e x + 2\e k) / (2\e k + 2);
|
||||
* return:
|
||||
* - 1 (succeed unconditionally) with prob (\e m − 2) / \e m,
|
||||
* - 0 (succeed with probability x) with prob 1 / \e m,
|
||||
* - −1 (fail unconditionally) with prob 1 / \e m.
|
||||
**********************************************************************/
|
||||
template<class Random> static int Choose(Random& r, int m);
|
||||
|
||||
// Compute v' < v. If true set v = v'.
|
||||
template<class Random> bool less_than(Random& r) const;
|
||||
|
||||
// Compute v < (x + p/_sig)/base (updating v)
|
||||
template<class Random> bool less_than(Random& r, word x, IntType p) const;
|
||||
|
||||
// true with prob (x + p/_sig)/base
|
||||
template<class Random> bool bernoulli(Random& r, word x, IntType p) const;
|
||||
|
||||
/**
|
||||
* Return true with probability exp(−1/2).
|
||||
**********************************************************************/
|
||||
template<class Random> bool ExpProbH(Random& r) const;
|
||||
|
||||
/**
|
||||
* Return true with probability exp(−<i>n</i>/2).
|
||||
**********************************************************************/
|
||||
template<class Random> bool ExpProb(Random& r, int n) const;
|
||||
|
||||
/**
|
||||
* Return \e n with probability exp(−<i>n</i>/2)
|
||||
* (1−exp(−1/2)).
|
||||
**********************************************************************/
|
||||
template<class Random> int ExpProbN(Random& r) const;
|
||||
|
||||
/**
|
||||
* Algorithm B: true with prob exp(-x * (2*k + x) / (2*k + 2)) where
|
||||
* x = (x0 + xn / _sig)/b.
|
||||
**********************************************************************/
|
||||
template<class Random>
|
||||
bool B(Random& r, int k, word x0, IntType xn) const;
|
||||
};
|
||||
|
||||
template<typename IntType> DiscreteNormal<IntType>::DiscreteNormal
|
||||
(IntType sigma_num, IntType sigma_den,
|
||||
IntType mu_num, IntType mu_den)
|
||||
: _v(std::vector<word>(alloc_incr)), _m(0), _l(alloc_incr) {
|
||||
STATIC_ASSERT(std::numeric_limits<IntType>::is_integer,
|
||||
"DiscreteNormal: invalid integer type IntType");
|
||||
STATIC_ASSERT(std::numeric_limits<IntType>::is_signed,
|
||||
"DiscreteNormal: IntType must be a signed type");
|
||||
STATIC_ASSERT(!std::numeric_limits<word>::is_signed,
|
||||
"DiscreteNormal: word must be an unsigned type");
|
||||
STATIC_ASSERT(std::numeric_limits<IntType>::digits + 1 >=
|
||||
std::numeric_limits<word>::digits,
|
||||
"DiscreteNormal: IntType must be at least as wide as word");
|
||||
if (!( sigma_num > 0 && sigma_den > 0 && mu_den > 0 ))
|
||||
throw RandomErr("DiscreteNormal: need sigma > 0");
|
||||
_imu = mu_num / mu_den;
|
||||
if (_imu == (std::numeric_limits<IntType>::min)())
|
||||
throw RandomErr("DiscreteNormal: abs(mu) too large");
|
||||
mu_num -= _imu * mu_den;
|
||||
IntType l;
|
||||
l = gcd(sigma_num, sigma_den); sigma_num /= l; sigma_den /= l;
|
||||
l = gcd(mu_num, mu_den); mu_num /= l; mu_den /= l;
|
||||
_isig = iceil(sigma_num, sigma_den);
|
||||
l = gcd(sigma_den, mu_den);
|
||||
_sig = sigma_num * (mu_den / l);
|
||||
_mu = mu_num * (sigma_den / l);
|
||||
_d = sigma_den * (mu_den / l);
|
||||
// The rest of the constructor tests for possible overflow
|
||||
// Check for overflow in computing member variables
|
||||
IntType maxint = (std::numeric_limits<IntType>::max)();
|
||||
if (!( mu_den / l <= maxint / sigma_num &&
|
||||
mu_num <= maxint / (sigma_den / l) &&
|
||||
mu_den / l <= maxint / sigma_den ))
|
||||
throw RandomErr("DiscreteNormal: sigma or mu overflow");
|
||||
// The probability that k = kmax is about 10^-543.
|
||||
int kmax = 50;
|
||||
// Check that max plausible result fits in an IntType, i.e.,
|
||||
// _isig * (kmax + 1) + abs(_imu) does not lead to overflow.
|
||||
if (!( kmax + 1 <= maxint / _isig &&
|
||||
_isig * (kmax + 1) <= maxint - iabs(_imu) ))
|
||||
throw RandomErr("DiscreteNormal: possible overflow a");
|
||||
// Check xn0 = _sig * k + s * _mu;
|
||||
if (!( kmax <= maxint / _sig &&
|
||||
_sig * kmax <= maxint - iabs(_mu) ))
|
||||
throw RandomErr("DiscreteNormal: possible overflow b");
|
||||
// Check for overflow in LeadingDigit
|
||||
// p << bits, p = _sig - 1, bits = 8
|
||||
if (!( _sig <= (maxint >> 8) ))
|
||||
throw RandomErr("DiscreteNormal: overflow in LeadingDigit");
|
||||
}
|
||||
|
||||
template<typename IntType> template<class Random>
|
||||
IntType DiscreteNormal<IntType>::operator()(Random& r) const {
|
||||
for (;;) {
|
||||
int k = ExpProbN(r);
|
||||
if (!ExpProb(r, k * (k - 1))) continue;
|
||||
IntType
|
||||
s = r.Boolean() ? -1 : 1,
|
||||
xn = _sig * IntType(k) + s * _mu,
|
||||
i = iceil(xn, _d) + r.template Integer<IntType>(_isig);
|
||||
xn = i * _d - xn;
|
||||
if (xn >= _sig || (k == 0 && s < 0 && xn <= 0)) continue;
|
||||
if (xn > 0) {
|
||||
word x0 = LeadingDigit(xn); // Find first digit in expansion in words
|
||||
int h = k + 1; while (h-- && B(r, k, x0, xn));
|
||||
if (!(h < 0)) continue;
|
||||
}
|
||||
return s * i + _imu;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename IntType>
|
||||
IntType DiscreteNormal<IntType>::iceil(IntType n, IntType d)
|
||||
{ IntType k = n / d; return k + (k * d < n ? 1 : 0); }
|
||||
|
||||
template<typename IntType> IntType DiscreteNormal<IntType>::iabs(IntType n)
|
||||
{ return n < 0 ? -n : n; }
|
||||
|
||||
template<typename IntType>
|
||||
IntType DiscreteNormal<IntType>::gcd(IntType u, IntType v) {
|
||||
// Knuth, TAOCP, vol 2, 4.5.2, Algorithm A
|
||||
u = iabs(u); v = iabs(v);
|
||||
while (v > 0) { IntType r = u % v; u = v; v = r; }
|
||||
return u;
|
||||
}
|
||||
|
||||
template<typename IntType> typename DiscreteNormal<IntType>::word
|
||||
DiscreteNormal<IntType>::LeadingDigit(IntType& p) const {
|
||||
static const unsigned bits = 8;
|
||||
static const unsigned num = std::numeric_limits<word>::digits / bits;
|
||||
STATIC_ASSERT(bits * num == std::numeric_limits<word>::digits,
|
||||
"Number of digits in word must be multiple of 8");
|
||||
word s = 0;
|
||||
for (unsigned c = num; c--;) {
|
||||
p <<= bits; s <<= bits;
|
||||
word d = word(p / _sig);
|
||||
s += d;
|
||||
p -= IntType(d) * _sig;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
template<typename IntType> template<class Random>
|
||||
int DiscreteNormal<IntType>::Choose(Random& r, int m) {
|
||||
int k = r.template Integer<int>(m);
|
||||
return k == 0 ? 0 : (k == 1 ? -1 : 1);
|
||||
}
|
||||
|
||||
template<typename IntType> template<class Random>
|
||||
bool DiscreteNormal<IntType>::less_than(Random& r) const {
|
||||
for (unsigned j = 0; ; ++j) {
|
||||
if (j == _m) {
|
||||
// Need more bits in the old V
|
||||
if (_l == _m) _v.resize(_l += alloc_incr);
|
||||
_v[_m++] = r.template Integer<word>();
|
||||
}
|
||||
word w = r.template Integer<word>();
|
||||
if (w > _v[j])
|
||||
return false; // New V is bigger, so exit
|
||||
else if (w < _v[j]) {
|
||||
_v[j] = w; // New V is smaller, update _v
|
||||
_m = j + 1; // adjusting its size
|
||||
return true; // and generate the next V
|
||||
}
|
||||
// Else w == _v[j] and we need to check the next word
|
||||
}
|
||||
}
|
||||
|
||||
template<typename IntType> template<class Random>
|
||||
bool DiscreteNormal<IntType>::less_than(Random& r, word x, IntType p) const {
|
||||
if (_m == 0) _v[_m++] = r.template Integer<word>();
|
||||
if (_v[0] != x) return _v[0] < x;
|
||||
for (unsigned j = 1; ; ++j) {
|
||||
if (p == 0) return false;
|
||||
if (j == _m) {
|
||||
if (_l == _m) _v.resize(_l += alloc_incr);
|
||||
_v[_m++] = r.template Integer<word>();
|
||||
}
|
||||
x = LeadingDigit(p);
|
||||
if (_v[j] != x) return _v[j] < x;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename IntType> template<class Random>
|
||||
bool DiscreteNormal<IntType>::bernoulli(Random& r, word x, IntType p) const {
|
||||
word w = r.template Integer<word>();
|
||||
if (w != x) return w < x;
|
||||
for (;;) {
|
||||
if (p == 0) return false;
|
||||
x = LeadingDigit(p);
|
||||
w = r.template Integer<word>();
|
||||
if (w != x) return w < x;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename IntType> template<class Random>
|
||||
bool DiscreteNormal<IntType>::ExpProbH(Random& r) const {
|
||||
static const word half = word(1) << (std::numeric_limits<word>::digits - 1);
|
||||
_m = 0;
|
||||
if ((_v[_m++] = r.template Integer<word>()) & half) return true;
|
||||
// Here _v < 1/2. Now loop finding decreasing V. Exit when first
|
||||
// increasing one is found.
|
||||
for (unsigned s = 0; ; s ^= 1) { // Parity of loop count
|
||||
if (!less_than(r)) return s != 0u;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename IntType> template<class Random>
|
||||
bool DiscreteNormal<IntType>::ExpProb(Random& r, int n) const {
|
||||
while (n-- > 0) { if (!ExpProbH(r)) return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename IntType> template<class Random>
|
||||
int DiscreteNormal<IntType>::ExpProbN(Random& r) const {
|
||||
int n = 0;
|
||||
while (ExpProbH(r)) ++n;
|
||||
return n;
|
||||
}
|
||||
|
||||
template<typename IntType> template<class Random>
|
||||
bool DiscreteNormal<IntType>::B(Random& r, int k, word x0, IntType xn)
|
||||
const {
|
||||
int n = 0, h = 2 * k + 2, f;
|
||||
_m = 0;
|
||||
for (;; ++n) {
|
||||
if ( ((f = k ? 0 : Choose(r, h)) < 0) ||
|
||||
!(n ? less_than(r) : less_than(r, x0, xn)) ||
|
||||
((f = k ? Choose(r, h) : f) < 0) ||
|
||||
(f == 0 && !bernoulli(r, x0, xn)) ) break;
|
||||
}
|
||||
return (n % 2) == 0;
|
||||
}
|
||||
|
||||
} // namespace RandomLib
|
||||
|
||||
#endif // RANDOMLIB_DISCRETENORMAL_HPP
|
@ -1,328 +0,0 @@
|
||||
/**
|
||||
* \file DiscreteNormalAlt.hpp
|
||||
* \brief Header for DiscreteNormalAlt
|
||||
*
|
||||
* Sample exactly from the discrete normal distribution (alternate version).
|
||||
*
|
||||
* Copyright (c) Charles Karney (2013) <charles@karney.com> and licensed
|
||||
* under the MIT/X11 License. For more information, see
|
||||
* http://randomlib.sourceforge.net/
|
||||
**********************************************************************/
|
||||
|
||||
#if !defined(RANDOMLIB_DISCRETENORMALALT_HPP)
|
||||
#define RANDOMLIB_DISCRETENORMALALT_HPP 1
|
||||
|
||||
#include <RandomLib/RandomNumber.hpp>
|
||||
#include <RandomLib/UniformInteger.hpp>
|
||||
#include <limits>
|
||||
|
||||
namespace RandomLib {
|
||||
/**
|
||||
* \brief The discrete normal distribution (alternate version).
|
||||
*
|
||||
* Sample integers \e i with probability proportional to
|
||||
* \f[
|
||||
* \exp\biggl[-\frac12\biggl(\frac{i-\mu}{\sigma}\biggr)^2\biggr],
|
||||
* \f]
|
||||
* where σ and μ are given as rationals (the ratio of two integers).
|
||||
* The sampling is exact (provided that the random generator is ideal). The
|
||||
* results of this class are UniformInteger objects which represent a
|
||||
* contiguous range which is a power of 2<sup>\e bits</sup>. This can be
|
||||
* narrowed down to a specific integer as follows
|
||||
* \code
|
||||
#include <iostream>
|
||||
#include <RandomLib/Random.hpp>
|
||||
#include <RandomLib/UniformInteger.hpp>
|
||||
#include <RandomLib/DiscreteNormalAlt.hpp>
|
||||
|
||||
int main() {
|
||||
RandomLib::Random r; // Create r
|
||||
r.Reseed(); // and give it a unique seed
|
||||
int sigma_num = 7, sigma_den = 1, mu_num = 1, mu_den = 3;
|
||||
RandomLib::DiscreteNormalAlt<int,1> d(sigma_num, sigma_den,
|
||||
mu_num, mu_den);
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
RandomLib::UniformInteger<int,1> u = d(r);
|
||||
std::cout << u << " = ";
|
||||
std::cout << u(r) << "\n";
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
* prints out 100 samples with σ = 7 and μ = 1/3; the samples are
|
||||
* first given as a range and then <code>u(r)</code> is used to obtain a
|
||||
* specific integer. In some applications, it might be possible to avoid
|
||||
* sampling all the additional digits to get to a specific integer. (An
|
||||
* example would be drawing a sample which satisfies an inequality.) This
|
||||
* version is slower (by a factor of about 4 for \e bits = 1) than
|
||||
* DiscreteNormal on a conventional computer, but may be faster when random
|
||||
* bits are generated by a slow hardware device.
|
||||
*
|
||||
* The basic algorithm is the same as for DiscreteNormal. However randomness
|
||||
* in metered out \e bits random bits at a time. The algorithm uses the
|
||||
* least random bits (and is slowest!) when \e bits = 1. This rationing of
|
||||
* random bits also applies to sampling \e j in the expression
|
||||
* \f[
|
||||
* x = x_0 + j/\sigma.
|
||||
* \f]
|
||||
* Rather than sampling a definite value for \e j, which then might be
|
||||
* rejected, \e j is sampled using UniformInteger. UniformInteger uses
|
||||
* Lumbroso's method from sampling an integer uniformly in [0, \e m) using at
|
||||
* most 2 + log<sub>2</sub>\e m bits on average (for \e bits = 1). However
|
||||
* when a UniformInteger object is first constructed it samples at most 3
|
||||
* bits (on average) to obtain a range for \e j which is power of 2. This
|
||||
* allows the algorithm to achieve ideal scaling in the limit of large
|
||||
* σ consuming constant + log<sub>2</sub>σ bits on average. In
|
||||
* addition it can deliver the resuls in the form of a UniformInteger
|
||||
* consuming a constant number of bits on average (and then about
|
||||
* log<sub>2</sub>σ additional bits are required to convert the
|
||||
* UniformInteger into an integer sample). The consumption of random bits
|
||||
* (for \e bits = 1) is summarized here \verbatim
|
||||
min mean max
|
||||
bits for UniformInteger result 30.4 34.3 35.7
|
||||
bits for integer result - log2(sigma) 28.8 31.2 32.5
|
||||
toll 26.8 29.1 30.4 \endverbatim
|
||||
* These results are averaged over many samples. The "min" results apply
|
||||
* when σ is a power of 2; the "max" results apply when σ is
|
||||
* slightly more than a power of two; the "mean" results are averaged over
|
||||
* σ. The toll is the excess number of bits over the entropy of the
|
||||
* distribution, which is log<sub>2</sub>(2π\e e)/2 +
|
||||
* log<sub>2</sub>σ (for σ large).
|
||||
*
|
||||
* The data for the first two lines in the table above are taken for the blue
|
||||
* and red lines in the figure below where the abscissa is the fractional
|
||||
* part of log<sub>2</sub>σ
|
||||
* \image html
|
||||
* discrete-bits.png "Random bits to sample from discrete normal distribution"
|
||||
*
|
||||
* This class uses a mutable RandomNumber objects. So a single
|
||||
* DiscreteNormalAlt object cannot safely be used by multiple threads. In a
|
||||
* multi-processing environment, each thread should use a thread-specific
|
||||
* DiscreteNormalAlt object.
|
||||
*
|
||||
* @tparam IntType the integer type to use (default int).
|
||||
**********************************************************************/
|
||||
template<typename IntType = int, int bits = 1> class DiscreteNormalAlt {
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param[in] sigma_num the numerator of σ.
|
||||
* @param[in] sigma_den the denominator of σ (default 1).
|
||||
* @param[in] mu_num the numerator of μ (default 0).
|
||||
* @param[in] mu_den the denominator of μ (default 1).
|
||||
*
|
||||
* This may throw an exception is the parameters are such that overflow is
|
||||
* possible.
|
||||
**********************************************************************/
|
||||
DiscreteNormalAlt(IntType sigma_num, IntType sigma_den = 1,
|
||||
IntType mu_num = 0, IntType mu_den = 1);
|
||||
/**
|
||||
* Return a sample.
|
||||
*
|
||||
* @tparam Random the type of the random generator.
|
||||
* @param[in,out] r a random generator.
|
||||
* @return discrete normal sample in the form of a UniformInteger object.
|
||||
**********************************************************************/
|
||||
template<class Random>
|
||||
UniformInteger<IntType, bits> operator()(Random& r) const;
|
||||
private:
|
||||
/**
|
||||
* sigma = _sig / _d, mu = _imu + _mu / _d, _isig = ceil(sigma)
|
||||
**********************************************************************/
|
||||
IntType _sig, _mu, _d, _isig, _imu;
|
||||
|
||||
mutable RandomNumber<bits> _p;
|
||||
mutable RandomNumber<bits> _q;
|
||||
|
||||
// ceil(n/d) for d > 0
|
||||
static IntType iceil(IntType n, IntType d);
|
||||
// abs(n) needed because Visual Studio's std::abs has problems
|
||||
static IntType iabs(IntType n);
|
||||
static IntType gcd(IntType u, IntType v);
|
||||
|
||||
/**
|
||||
* Implement outcomes for choosing with prob (\e x + 2\e k) / (2\e k + 2);
|
||||
* return:
|
||||
* - 1 (succeed unconditionally) with prob (\e m − 2) / \e m,
|
||||
* - 0 (succeed with probability x) with prob 1 / \e m,
|
||||
* - −1 (fail unconditionally) with prob 1 / \e m.
|
||||
**********************************************************************/
|
||||
template<class Random> static int Choose(Random& r, int m);
|
||||
|
||||
/**
|
||||
* Return true with probability exp(−1/2).
|
||||
**********************************************************************/
|
||||
template<class Random> bool ExpProbH(Random& r) const;
|
||||
|
||||
/**
|
||||
* Return true with probability exp(−<i>n</i>/2).
|
||||
**********************************************************************/
|
||||
template<class Random> bool ExpProb(Random& r, int n) const;
|
||||
|
||||
/**
|
||||
* Return \e n with probability exp(−<i>n</i>/2)
|
||||
* (1−exp(−1/2)).
|
||||
**********************************************************************/
|
||||
template<class Random> int ExpProbN(Random& r) const;
|
||||
|
||||
/**
|
||||
* Algorithm B: true with prob exp(-x * (2*k + x) / (2*k + 2)) where
|
||||
* x = (xn0 + _d * j) / _sig
|
||||
**********************************************************************/
|
||||
template<class Random>
|
||||
bool B(Random& r, int k, IntType xn0, UniformInteger<IntType, bits>& j)
|
||||
const;
|
||||
};
|
||||
|
||||
template<typename IntType, int bits>
|
||||
DiscreteNormalAlt<IntType, bits>::DiscreteNormalAlt
|
||||
(IntType sigma_num, IntType sigma_den, IntType mu_num, IntType mu_den) {
|
||||
STATIC_ASSERT(std::numeric_limits<IntType>::is_integer,
|
||||
"DiscreteNormalAlt: invalid integer type IntType");
|
||||
STATIC_ASSERT(std::numeric_limits<IntType>::is_signed,
|
||||
"DiscreteNormalAlt: IntType must be a signed type");
|
||||
if (!( sigma_num > 0 && sigma_den > 0 && mu_den > 0 ))
|
||||
throw RandomErr("DiscreteNormalAlt: need sigma > 0");
|
||||
_imu = mu_num / mu_den;
|
||||
if (_imu == (std::numeric_limits<IntType>::min)())
|
||||
throw RandomErr("DiscreteNormalAlt: abs(mu) too large");
|
||||
mu_num -= _imu * mu_den;
|
||||
IntType l;
|
||||
l = gcd(sigma_num, sigma_den); sigma_num /= l; sigma_den /= l;
|
||||
l = gcd(mu_num, mu_den); mu_num /= l; mu_den /= l;
|
||||
_isig = iceil(sigma_num, sigma_den);
|
||||
l = gcd(sigma_den, mu_den);
|
||||
_sig = sigma_num * (mu_den / l);
|
||||
_mu = mu_num * (sigma_den / l);
|
||||
_d = sigma_den * (mu_den / l);
|
||||
// The rest of the constructor tests for possible overflow
|
||||
// Check for overflow in computing member variables
|
||||
IntType maxint = (std::numeric_limits<IntType>::max)();
|
||||
if (!( mu_den / l <= maxint / sigma_num &&
|
||||
iabs(mu_num) <= maxint / (sigma_den / l) &&
|
||||
mu_den / l <= maxint / sigma_den ))
|
||||
throw RandomErr("DiscreteNormalAlt: sigma or mu overflow");
|
||||
if (!UniformInteger<IntType, bits>::Check(_isig, _d))
|
||||
throw RandomErr("DiscreteNormalAlt: overflow in UniformInteger");
|
||||
// The probability that k = kmax is about 10^-543.
|
||||
int kmax = 50;
|
||||
// Check that max plausible result fits in an IntType, i.e.,
|
||||
// _isig * (kmax + 1) + abs(_imu) does not lead to overflow.
|
||||
if (!( kmax + 1 <= maxint / _isig &&
|
||||
_isig * (kmax + 1) <= maxint - iabs(_imu) ))
|
||||
throw RandomErr("DiscreteNormalAlt: possible overflow a");
|
||||
// Check xn0 = _sig * k + s * _mu;
|
||||
if (!( kmax <= maxint / _sig &&
|
||||
_sig * kmax <= maxint - iabs(_mu) ))
|
||||
throw RandomErr("DiscreteNormalAlt: possible overflow b");
|
||||
// Check for overflow in RandomNumber::LessThan(..., UniformInteger& j)
|
||||
// p0 * b, p0 = arg2 = xn0 = _d - 1
|
||||
// c *= b, c = arg3 = _d
|
||||
// digit(D, k) * q, digit(D, k) = b - 1, q = arg4 = _sig
|
||||
if (!( _d <= maxint >> bits ))
|
||||
throw std::runtime_error("DiscreteNormalAlt: overflow in RandomNumber a");
|
||||
if (!( (IntType(1) << bits) - 1 <= maxint / _sig ))
|
||||
throw std::runtime_error("DiscreteNormalAlt: overflow in RandomNumber b");
|
||||
}
|
||||
|
||||
template<typename IntType, int bits> template<class Random>
|
||||
UniformInteger<IntType, bits>
|
||||
DiscreteNormalAlt<IntType, bits>::operator()(Random& r) const {
|
||||
for (;;) {
|
||||
int k = ExpProbN(r);
|
||||
if (!ExpProb(r, k * (k - 1))) continue;
|
||||
UniformInteger<IntType, bits> j(r, _isig);
|
||||
IntType
|
||||
s = r.Boolean() ? -1 : 1,
|
||||
xn0 = _sig * IntType(k) + s * _mu,
|
||||
i0 = iceil(xn0, _d); // i = i0 + j
|
||||
xn0 = i0 * _d - xn0; // xn = xn0 + _d * j
|
||||
if (!j.LessThan(r, _sig - xn0, _d) ||
|
||||
(k == 0 && s < 0 && !j.GreaterThan(r, -xn0, _d))) continue;
|
||||
int h = k + 1; while (h-- && B(r, k, xn0, j));
|
||||
if (!(h < 0)) continue;
|
||||
j.Add(i0 + s * _imu);
|
||||
if (s < 0) j.Negate();
|
||||
return j;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename IntType, int bits>
|
||||
IntType DiscreteNormalAlt<IntType, bits>::iceil(IntType n, IntType d)
|
||||
{ IntType k = n / d; return k + (k * d < n ? 1 : 0); }
|
||||
|
||||
template<typename IntType, int bits>
|
||||
IntType DiscreteNormalAlt<IntType, bits>::iabs(IntType n)
|
||||
{ return n < 0 ? -n : n; }
|
||||
|
||||
template<typename IntType, int bits>
|
||||
IntType DiscreteNormalAlt<IntType, bits>::gcd(IntType u, IntType v) {
|
||||
// Knuth, TAOCP, vol 2, 4.5.2, Algorithm A
|
||||
u = iabs(u); v = iabs(v);
|
||||
while (v > 0) { IntType r = u % v; u = v; v = r; }
|
||||
return u;
|
||||
}
|
||||
|
||||
template<typename IntType, int bits> template<class Random>
|
||||
int DiscreteNormalAlt<IntType, bits>::Choose(Random& r, int m) {
|
||||
// Limit base to 2^15 to avoid integer overflow
|
||||
const int b = bits > 15 ? 15 : bits;
|
||||
const unsigned mask = (1u << b) - 1;
|
||||
int n1 = m - 2, n2 = m - 1;
|
||||
// Evaluate u < n/m where u is a random real number in [0,1). Write u =
|
||||
// (d + u') / 2^b where d is a random integer in [0,2^b) and u' is in
|
||||
// [0,1). Then u < n/m becomes u' < n'/m where n' = 2^b * n - d * m and
|
||||
// exit if n' <= 0 (false) or n' >= m (true).
|
||||
for (;;) {
|
||||
int d = (mask & RandomNumber<bits>::RandomDigit(r)) * m;
|
||||
n1 = (std::max)((n1 << b) - d, 0);
|
||||
if (n1 >= m) return 1;
|
||||
n2 = (std::min)((n2 << b) - d, m);
|
||||
if (n2 <= 0) return -1;
|
||||
if (n1 == 0 && n2 == m) return 0;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename IntType, int bits> template<class Random>
|
||||
bool DiscreteNormalAlt<IntType, bits>::ExpProbH(Random& r) const {
|
||||
_p.Init();
|
||||
if (_p.Digit(r, 0) >> (bits - 1)) return true;
|
||||
for (;;) {
|
||||
_q.Init(); if (!_q.LessThan(r, _p)) return false;
|
||||
_p.Init(); if (!_p.LessThan(r, _q)) return true;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename IntType, int bits> template<class Random>
|
||||
bool DiscreteNormalAlt<IntType, bits>::ExpProb(Random& r, int n) const {
|
||||
while (n-- > 0) { if (!ExpProbH(r)) return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename IntType, int bits> template<class Random>
|
||||
int DiscreteNormalAlt<IntType, bits>::ExpProbN(Random& r) const {
|
||||
int n = 0;
|
||||
while (ExpProbH(r)) ++n;
|
||||
return n;
|
||||
}
|
||||
|
||||
template<typename IntType, int bits> template<class Random> bool
|
||||
DiscreteNormalAlt<IntType, bits>::B(Random& r, int k, IntType xn0,
|
||||
UniformInteger<IntType, bits>& j)
|
||||
const {
|
||||
int n = 0, m = 2 * k + 2, f;
|
||||
for (;; ++n) {
|
||||
if ( ((f = k ? 0 : Choose(r, m)) < 0) ||
|
||||
(_q.Init(),
|
||||
!(n ? _q.LessThan(r, _p) : _q.LessThan(r, xn0, _d, _sig, j))) ||
|
||||
((f = k ? Choose(r, m) : f) < 0) ||
|
||||
(f == 0 && (_p.Init(), !_p.LessThan(r, xn0, _d, _sig, j))) )
|
||||
break;
|
||||
_p.swap(_q); // an efficient way of doing p = q
|
||||
}
|
||||
return (n % 2) == 0;
|
||||
}
|
||||
|
||||
} // namespace RandomLib
|
||||
|
||||
#endif // RANDOMLIB_DISCRETENORMALALT_HPP
|
@ -1,241 +0,0 @@
|
||||
/**
|
||||
* \file ExactExponential.hpp
|
||||
* \brief Header for ExactExponential
|
||||
*
|
||||
* Sample exactly from an exponential distribution.
|
||||
*
|
||||
* Copyright (c) Charles Karney (2006-2012) <charles@karney.com> and licensed
|
||||
* under the MIT/X11 License. For more information, see
|
||||
* http://randomlib.sourceforge.net/
|
||||
**********************************************************************/
|
||||
|
||||
#if !defined(RANDOMLIB_EXACTEXPONENTIAL_HPP)
|
||||
#define RANDOMLIB_EXACTEXPONENTIAL_HPP 1
|
||||
|
||||
#include <RandomLib/RandomNumber.hpp>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
// Squelch warnings about constant conditional expressions
|
||||
# pragma warning (push)
|
||||
# pragma warning (disable: 4127)
|
||||
#endif
|
||||
|
||||
namespace RandomLib {
|
||||
/**
|
||||
* \brief Sample exactly from an exponential distribution.
|
||||
*
|
||||
* Sample \e x ≥ 0 from exp(−\e x). See:
|
||||
* - J. von Neumann, Various Techniques used in Connection with Random
|
||||
* Digits, J. Res. Nat. Bur. Stand., Appl. Math. Ser. 12, 36--38
|
||||
* (1951), reprinted in Collected Works, Vol. 5, 768--770 (Pergammon,
|
||||
* 1963).
|
||||
* - M. Abramowitz and I. A. Stegun, Handbook of Mathematical Functions
|
||||
* (National Bureau of Standards, 1964), Sec. 26.8.6.c(2).
|
||||
* - G. E. Forsythe, Von Neumann's Comparison Method for Random Sampling from
|
||||
* Normal and Other Distributions, Math. Comp. 26, 817--826 (1972).
|
||||
* - D. E. Knuth, TAOCP, Vol 2, Sec 3.4.1.C.3.
|
||||
* - D. E. Knuth and A. C. Yao, The Complexity of Nonuniform Random Number
|
||||
* Generation, in "Algorithms and Complexity" (Academic Press, 1976),
|
||||
* pp. 357--428.
|
||||
* - P. Flajolet and N. Saheb, The Complexity of Generating an
|
||||
* Exponentially Distributed Variate, J. Algorithms 7, 463--488 (1986).
|
||||
*
|
||||
* The following code illustrates the basic method given by von Neumann:
|
||||
* \code
|
||||
// Return a random number x >= 0 distributed with probability exp(-x).
|
||||
double ExpDist(RandomLib::Random& r) {
|
||||
for (unsigned k = 0; ; ++k) {
|
||||
double x = r.Fixed(), // executed 1/(1-exp(-1)) times on average
|
||||
p = x, q;
|
||||
do {
|
||||
q = r.Fixed(); // executed exp(x)*cosh(x) times on average
|
||||
if (!(q < p)) return k + x;
|
||||
p = r.Fixed(); // executed exp(x)*sinh(x) times on average
|
||||
} while (p < q);
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
* This returns a result consuming exp(1)/(1 − exp(-1)) = 4.30 random
|
||||
* numbers on average. (Von Neumann incorrectly states that the method takes
|
||||
* (1 + exp(1))/(1 − exp(-1)) = 5.88 random numbers on average.)
|
||||
* Because of the finite precision of Random::Fixed(), the code snippet above
|
||||
* only approximates exp(−\e x). Instead, it returns \e x with
|
||||
* probability \e h(1 − \e h)<sup><i>x</i>/<i>h</i></sup> for \e x = \e
|
||||
* ih, \e h = 2<sup>−53</sup>, and integer \e i ≥ 0.
|
||||
*
|
||||
* The above is precisely von Neumann's method. Abramowitz and Stegun
|
||||
* consider a variant: sample uniform variants until the first is less than
|
||||
* the sum of the rest. Forsythe converts the < ranking for the runs to ≤
|
||||
* which makes the analysis of the discrete case more difficult. He also
|
||||
* drops the "trick" by which the integer part of the deviate is given by the
|
||||
* number of rejections when finding the fractional part.
|
||||
*
|
||||
* Von Neumann says of his method: "The machine has in effect computed a
|
||||
* logarithm by performing only discriminations on the relative magnitude of
|
||||
* numbers in (0,1). It is a sad fact of life, however, that under the
|
||||
* particular conditions of the Eniac it was slightly quicker to use a
|
||||
* truncated power series for log(1−\e T) than to carry out all the
|
||||
* discriminations."
|
||||
*
|
||||
* Here the code is modified to make it more efficient:
|
||||
* \code
|
||||
// Return a random number x >= 0 distributed with probability exp(-x).
|
||||
double ExpDist(RandomLib::Random& r) {
|
||||
for (unsigned k = 0; ; ++k) {
|
||||
double x = r.Fixed(); // executed 1/(1-exp(-1/2)) times on average
|
||||
if (x >= 0.5) continue;
|
||||
double p = x, q;
|
||||
do {
|
||||
q = r.Fixed(); // executed exp(x)*cosh(x) times on average
|
||||
if (!(q < p)) return 0.5 * k + x;
|
||||
p = r.Fixed(); // executed exp(x)*sinh(x) times on average
|
||||
} while (p < q);
|
||||
}
|
||||
}
|
||||
\endcode
|
||||
* In addition, the method is extended to use infinite precision uniform
|
||||
* deviates implemented by RandomNumber and returning \e exact results for
|
||||
* the exponential distribution. This is possible because only comparisons
|
||||
* are done in the method. The template parameter \e bits specifies the
|
||||
* number of bits in the base used for RandomNumber (i.e., base =
|
||||
* 2<sup><i>bits</i></sup>).
|
||||
*
|
||||
* For example the following samples from an exponential distribution and
|
||||
* prints various representations of the result.
|
||||
* \code
|
||||
#include <RandomLib/RandomNumber.hpp>
|
||||
#include <RandomLib/ExactExponential.hpp>
|
||||
|
||||
RandomLib::Random r;
|
||||
const int bits = 1;
|
||||
RandomLib::ExactExponential<bits> edist;
|
||||
for (size_t i = 0; i < 10; ++i) {
|
||||
RandomLib::RandomNumber<bits> x = edist(r); // Sample
|
||||
std::pair<double, double> z = x.Range();
|
||||
std::cout << x << " = " // Print in binary with ellipsis
|
||||
<< "(" << z.first << "," << z.second << ")"; // Print range
|
||||
double v = x.Value<double>(r); // Round exactly to nearest double
|
||||
std::cout << " = " << v << "\n";
|
||||
}
|
||||
\endcode
|
||||
* Here's a possible result: \verbatim
|
||||
0.0111... = (0.4375,0.5) = 0.474126
|
||||
10.000... = (2,2.125) = 2.05196
|
||||
1.00... = (1,1.25) = 1.05766
|
||||
0.010... = (0.25,0.375) = 0.318289
|
||||
10.1... = (2.5,3) = 2.8732
|
||||
0.0... = (0,0.5) = 0.30753
|
||||
0.101... = (0.625,0.75) = 0.697654
|
||||
0.00... = (0,0.25) = 0.0969214
|
||||
0.0... = (0,0.5) = 0.194053
|
||||
0.11... = (0.75,1) = 0.867946 \endverbatim
|
||||
* First number is in binary with ... indicating an infinite sequence of
|
||||
* random bits. Second number gives the corresponding interval. Third
|
||||
* number is the result of filling in the missing bits and rounding exactly
|
||||
* to the nearest representable double.
|
||||
*
|
||||
* This class uses some mutable RandomNumber objects. So a single
|
||||
* ExactExponential object cannot safely be used by multiple threads. In a
|
||||
* multi-processing environment, each thread should use a thread-specific
|
||||
* ExactExponential object. In addition, these should be invoked with
|
||||
* thread-specific random generator objects.
|
||||
*
|
||||
* @tparam bits the number of bits in each digit.
|
||||
**********************************************************************/
|
||||
template<int bits = 1> class ExactExponential {
|
||||
public:
|
||||
/**
|
||||
* Return a random deviate with an exponential distribution, exp(−\e
|
||||
* x) for \e x ≥ 0. Requires 7.232 bits per invocation for \e bits = 1.
|
||||
* The average number of bits in the fraction = 1.743. The relative
|
||||
* frequency of the results for the fractional part with \e bits = 1 is
|
||||
* shown by the histogram
|
||||
* \image html exphist.png
|
||||
* The base of each rectangle gives the range represented by the
|
||||
* corresponding binary number and the area is proportional to its
|
||||
* frequency. A PDF version of this figure is given
|
||||
* <a href="exphist.pdf">here</a>. This allows the figure to be magnified
|
||||
* to show the rectangles for all binary numbers up to 9 bits. Note that
|
||||
* this histogram was generated using an earlier version of
|
||||
* ExactExponential (thru version 1.3) that implements von Neumann's
|
||||
* original method. The histogram generated with the current version of
|
||||
* ExactExponential is the same as this figure for \e u in [0, 1/2]. The
|
||||
* histogram for \e u in [1/2, 1] is obtained by shifting and scaling the
|
||||
* part for \e u in [0, 1/2] to fit under the exponential curve.
|
||||
*
|
||||
* Another way of assessing the efficiency of the algorithm is thru the
|
||||
* mean value of the balance = (number of random bits consumed) −
|
||||
* (number of bits in the result). If we code the result in mixed Knuth
|
||||
* and Yao's unary-binary notation (integer is given in unary, followed by
|
||||
* "0" as a separator, followed by the fraction in binary), then the mean
|
||||
* balance is 3.906. (Flajolet and Saheb analyzed the algorithm based on
|
||||
* the original von Neumann method and showed that the balance is 5.680 in
|
||||
* that case.)
|
||||
*
|
||||
* For \e bits large, the mean number of random digits is exp(1/2)/(1
|
||||
* − exp(−1/2)) = 4.19 (versus 4.30 digits for the original
|
||||
* method).
|
||||
*
|
||||
* @tparam Random the type of the random generator.
|
||||
* @param[in,out] r a random generator.
|
||||
* @return the random sample.
|
||||
**********************************************************************/
|
||||
template<class Random> RandomNumber<bits> operator()(Random& r) const;
|
||||
private:
|
||||
/**
|
||||
* Return true with probability exp(−\e p) for \e p in (0,1/2).
|
||||
**********************************************************************/
|
||||
template<class Random> bool
|
||||
ExpFraction(Random& r, RandomNumber<bits>& p) const;
|
||||
mutable RandomNumber<bits> _x;
|
||||
mutable RandomNumber<bits> _v;
|
||||
mutable RandomNumber<bits> _w;
|
||||
};
|
||||
|
||||
template<int bits> template<class Random> RandomNumber<bits>
|
||||
ExactExponential<bits>::operator()(Random& r) const {
|
||||
// A simple rejection method gives the 1/2 fractional part. The number of
|
||||
// rejections gives the multiples of 1/2.
|
||||
//
|
||||
// bits: used fract un-bin balance double
|
||||
// original stats: 9.31615 2.05429 3.63628 5.67987 61.59456
|
||||
// new stats: 7.23226 1.74305 3.32500 3.90725 59.82198
|
||||
//
|
||||
// The difference between un-bin and fract is exp(1)/(exp(1)-1) = 1.58198
|
||||
_x.Init();
|
||||
int k = 0;
|
||||
while (!ExpFraction(r, _x)) { // Executed 1/(1 - exp(-1/2)) on average
|
||||
++k;
|
||||
_x.Init();
|
||||
}
|
||||
if (k & 1) _x.RawDigit(0) += 1U << (bits - 1);
|
||||
_x.AddInteger(k >> 1);
|
||||
return _x;
|
||||
}
|
||||
|
||||
template<int bits> template<class Random> bool
|
||||
ExactExponential<bits>::ExpFraction(Random& r, RandomNumber<bits>& p)
|
||||
const {
|
||||
// The early bale out
|
||||
if (p.Digit(r, 0) >> (bits - 1)) return false;
|
||||
// Implement the von Neumann algorithm
|
||||
_w.Init();
|
||||
if (!_w.LessThan(r, p)) // if (w < p)
|
||||
return true;
|
||||
while (true) { // Unroll loop to avoid copying RandomNumber
|
||||
_v.Init(); // v = r.Fixed();
|
||||
if (!_v.LessThan(r, _w)) // if (v < w)
|
||||
return false;
|
||||
_w.Init(); // w = r.Fixed();
|
||||
if (!_w.LessThan(r, _v)) // if (w < v)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace RandomLib
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning (pop)
|
||||
#endif
|
||||
|
||||
#endif // RANDOMLIB_EXACTEXPONENTIAL_HPP
|
@ -1,417 +0,0 @@
|
||||
/**
|
||||
* \file ExactNormal.hpp
|
||||
* \brief Header for ExactNormal
|
||||
*
|
||||
* Sample exactly from a normal distribution.
|
||||
*
|
||||
* Copyright (c) Charles Karney (2011-2012) <charles@karney.com> and licensed
|
||||
* under the MIT/X11 License. For more information, see
|
||||
* http://randomlib.sourceforge.net/
|
||||
**********************************************************************/
|
||||
|
||||
#if !defined(RANDOMLIB_EXACTNORMAL_HPP)
|
||||
#define RANDOMLIB_EXACTNORMAL_HPP 1
|
||||
|
||||
#include <RandomLib/RandomNumber.hpp>
|
||||
#include <algorithm> // for max/min
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
// Squelch warnings about constant conditional expressions
|
||||
# pragma warning (push)
|
||||
# pragma warning (disable: 4127)
|
||||
#endif
|
||||
|
||||
namespace RandomLib {
|
||||
/**
|
||||
* \brief Sample exactly from a normal distribution.
|
||||
*
|
||||
* Sample \e x from exp(−<i>x</i><sup>2</sup>/2) / sqrt(2π). For
|
||||
* background, see:
|
||||
* - J. von Neumann, Various Techniques used in Connection with Random
|
||||
* Digits, J. Res. Nat. Bur. Stand., Appl. Math. Ser. 12, 36--38
|
||||
* (1951), reprinted in Collected Works, Vol. 5, 768--770 (Pergammon,
|
||||
* 1963).
|
||||
* - D. E. Knuth and A. C. Yao, The Complexity of Nonuniform Random Number
|
||||
* Generation, in "Algorithms and Complexity" (Academic Press, 1976),
|
||||
* pp. 357--428.
|
||||
* - P. Flajolet and N. Saheb, The Complexity of Generating an Exponentially
|
||||
* Distributed Variate, J. Algorithms 7, 463--488 (1986).
|
||||
*
|
||||
* The algorithm is given in
|
||||
* - C. F. F. Karney, <i>Sampling exactly from the normal distribution</i>,
|
||||
* http://arxiv.org/abs/1303.6257 (Mar. 2013).
|
||||
* .
|
||||
* In brief, the algorithm is:
|
||||
* -# Select an integer \e k ≥ 0 with probability
|
||||
* exp(−<i>k</i>/2) (1−exp(−1/2)).
|
||||
* -# Accept with probability
|
||||
* exp(− \e k (\e k − 1) / 2); otherwise, reject and start
|
||||
* over at step 1.
|
||||
* -# Sample a random number \e x uniformly from [0,1).
|
||||
* -# Accept with probability exp(− \e x (\e x + 2\e k) / 2);
|
||||
* otherwise, reject and start over at step 1.
|
||||
* -# Set \e x = \e k + \e x.
|
||||
* -# With probability 1/2, negate \e x.
|
||||
* -# Return \e x.
|
||||
* .
|
||||
* It is easy to show that this algorithm returns samples from the normal
|
||||
* distribution with zero mean and unit variance. Futhermore, all these
|
||||
* steps can be carried out exactly as follows:
|
||||
* - Step 1:
|
||||
* - \e k = 0;
|
||||
* - while (ExpProb(−1/2)) increment \e k by 1.
|
||||
* - Step 2:
|
||||
* - \e n = \e k (\e k − 1) / 2;
|
||||
* - while (\e n > 0)
|
||||
* { if (!ExpProb(−1/2)) go to step 1; decrement \e n by 1; }
|
||||
* - Step 4:
|
||||
* - repeat \e k + 1 times:
|
||||
* if (!ExpProb(− \e x (\e x + 2\e k) / (2\e k + 2))) go to step 1.
|
||||
* .
|
||||
* Here, ExpProb(−\e p) returns true with probability exp(−\e p).
|
||||
* With \e p = 1/2 (steps 1 and 2), this is implemented with von Neumann's
|
||||
* rejection technique:
|
||||
* - Generate a sequence of random numbers <i>U</i><sub><i>i</i></sub> and
|
||||
* find the greatest \e n such that 1/2 > <i>U</i><sub>1</sub> >
|
||||
* <i>U</i><sub>2</sub> > . . . > <i>U</i><sub><i>n</i></sub>. (The
|
||||
* resulting value of \e n may be 0.)
|
||||
* - If \e n is even, accept and return true; otherwise (\e n odd), reject
|
||||
* and return false.
|
||||
* .
|
||||
* For \e p = \e x (\e x + 2\e k) / (2\e k + 2) (step 4), we generalize von
|
||||
* Neumann's procedure as follows:
|
||||
* - Generate two sequences of random numbers <i>U</i><sub><i>i</i></sub>
|
||||
* and <i>V</i><sub><i>i</i></sub> and find the greatest \e n such that
|
||||
* both the following conditions hold
|
||||
* - \e x > <i>U</i><sub>1</sub> > <i>U</i><sub>2</sub> > . . . >
|
||||
* <i>U</i><sub><i>n</i></sub>;
|
||||
* - <i>V</i><sub><i>i</i></sub> < (\e x + 2 \e k) / (2 \e k + 2) for
|
||||
* all \e i in [1, \e n].
|
||||
* .
|
||||
* (The resulting value of \e n may be 0.)
|
||||
* - If \e n is even, accept (return true); otherwise (\e n odd), reject
|
||||
* (return false).
|
||||
* .
|
||||
* Here, instead of testing <i>V</i><sub><i>i</i></sub> < (\e x + 2 \e k)
|
||||
* / (2 \e k + 2), we carry out the following tests:
|
||||
* - return true, with probability 2 \e k / (2 \e k + 2);
|
||||
* - return false, with probability 1 / (2 \e k + 2);
|
||||
* - otherwise (also with probability 1 / (2 \e k + 2)),
|
||||
* return \e x > <i>V</i><sub><i>i</i></sub>.
|
||||
* .
|
||||
* The resulting method now entails evaluation of simple fractional
|
||||
* probabilities (e.g., 1 / (2 \e k + 2)), or comparing random numbers (e.g.,
|
||||
* <i>U</i><sub>1</sub> > <i>U</i><sub>2</sub>). These may be carried out
|
||||
* exactly with a finite mean running time.
|
||||
*
|
||||
* With \e bits = 1, this consumes 30.1 digits on average and the result has
|
||||
* 1.19 digits in the fraction. It takes about 676 ns to generate a result
|
||||
* (1460 ns, including the time to round it to a double). With bits = 32, it
|
||||
* takes 437 ns to generate a result (621 ns, including the time to round it
|
||||
* to a double). In contrast, NormalDistribution takes about 44 ns to
|
||||
* generate a double result.
|
||||
*
|
||||
* Another way of assessing the efficiency of the algorithm is thru the mean
|
||||
* value of the balance = (number of random bits consumed) − (number of
|
||||
* bits in the result). If we code the result in Knuth & Yao's unary-binary
|
||||
* notation, then the mean balance is 26.6.
|
||||
*
|
||||
* For example the following samples from a normal exponential distribution
|
||||
* and prints various representations of the result.
|
||||
* \code
|
||||
#include <RandomLib/RandomNumber.hpp>
|
||||
#include <RandomLib/ExactNormal.hpp>
|
||||
|
||||
RandomLib::Random r;
|
||||
const int bits = 1;
|
||||
RandomLib::ExactNormal<bits> ndist;
|
||||
for (size_t i = 0; i < 10; ++i) {
|
||||
RandomLib::RandomNumber<bits> x = ndist(r); // Sample
|
||||
std::pair<double, double> z = x.Range();
|
||||
std::cout << x << " = " // Print in binary with ellipsis
|
||||
<< "(" << z.first << "," << z.second << ")"; // Print range
|
||||
double v = x.Value<double>(r); // Round exactly to nearest double
|
||||
std::cout << " = " << v << "\n";
|
||||
}
|
||||
\endcode
|
||||
* Here's a possible result: \verbatim
|
||||
-1.00... = (-1.25,-1) = -1.02142
|
||||
-0.... = (-1,0) = -0.319708
|
||||
0.... = (0,1) = 0.618735
|
||||
-0.0... = (-0.5,0) = -0.396591
|
||||
0.0... = (0,0.5) = 0.20362
|
||||
0.0... = (0,0.5) = 0.375662
|
||||
-1.111... = (-2,-1.875) = -1.88295
|
||||
-1.10... = (-1.75,-1.5) = -1.68088
|
||||
-0.... = (-1,0) = -0.577547
|
||||
-0.... = (-1,0) = -0.890553
|
||||
\endverbatim
|
||||
* First number is in binary with ... indicating an infinite sequence of
|
||||
* random bits. Second number gives the corresponding interval. Third
|
||||
* number is the result of filling in the missing bits and rounding exactly
|
||||
* to the nearest representable double.
|
||||
*
|
||||
* This class uses some mutable RandomNumber objects. So a single
|
||||
* ExactNormal object cannot safely be used by multiple threads. In a
|
||||
* multi-processing environment, each thread should use a thread-specific
|
||||
* ExactNormal object. In addition, these should be invoked with
|
||||
* thread-specific random generator objects.
|
||||
*
|
||||
* @tparam bits the number of bits in each digit.
|
||||
**********************************************************************/
|
||||
template<int bits = 1> class ExactNormal {
|
||||
public:
|
||||
/**
|
||||
* Return a random deviate with a normal distribution of mean 0 and
|
||||
* variance 1.
|
||||
*
|
||||
* @tparam Random the type of the random generator.
|
||||
* @param[in,out] r a random generator.
|
||||
* @return the random sample.
|
||||
**********************************************************************/
|
||||
template<class Random> RandomNumber<bits> operator()(Random& r) const;
|
||||
private:
|
||||
/**
|
||||
* Return true with probability exp(−1/2). For \e bits = 1, this
|
||||
* consumes, on average, \e t = 2.846 random digits. We have \e t = \e a
|
||||
* (1−exp(−1/2)) + \e b exp(−1/2), where \e a is the mean
|
||||
* bit count for false result = 3.786 and \e b is the mean bit count for
|
||||
* true result = 2.236.
|
||||
**********************************************************************/
|
||||
template<class Random> bool ExpProbH(Random& r) const;
|
||||
|
||||
/**
|
||||
* Return true with probability exp(−<i>n</i>/2). For \e bits = 1,
|
||||
* this consumes, on average, \e t
|
||||
* (1−exp(−<i>n</i>/2))/(1−exp(−1/2)) random
|
||||
* digits. A true result uses \e n \e b random digits. A false result
|
||||
* uses \e a + \e b [exp(−1/2)/(1−exp(−1/2)) −
|
||||
* <i>n</i> exp(−<i>n</i>/2)/(1−exp(−<i>n</i>/2))] random
|
||||
* digits.
|
||||
**********************************************************************/
|
||||
template<class Random> bool ExpProb(Random& r, unsigned n) const;
|
||||
|
||||
/**
|
||||
* Return \e n with probability exp(−<i>n</i>/2)
|
||||
* (1−exp(−1/2)). For \e bits = 1, this consumes \e n \e a +
|
||||
* \e b random digits if the result is \e n. Averaging over \e n this
|
||||
* becomes (\e b − (\e b − \e a) exp(−1/2))/(1 −
|
||||
* exp(−1/2)) digits.
|
||||
**********************************************************************/
|
||||
template<class Random> unsigned ExpProbN(Random& r) const;
|
||||
|
||||
/**
|
||||
* Return true with probability 1/2. This is similar to r.Boolean() but
|
||||
* forces all the random results to come thru RandomNumber::RandomDigit.
|
||||
**********************************************************************/
|
||||
template<class Random> static bool Boolean(Random& r) {
|
||||
// A more general implementation which deals with the case where the base
|
||||
// might be negative is:
|
||||
//
|
||||
// const unsigned base = 1u << bits;
|
||||
// unsigned b;
|
||||
// do
|
||||
// b = RandomNumber<bits>::RandomDigit(r);
|
||||
// while (b == (base / 2) * 2);
|
||||
// return b & 1u;
|
||||
return RandomNumber<bits>::RandomDigit(r) & 1u;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement outcomes for choosing with prob (\e x + 2\e k) / (2\e k + 2);
|
||||
* return:
|
||||
* - 1 (succeed unconditionally) with prob (2\e k) / (2\e k + 2),
|
||||
* - 0 (succeed with probability x) with prob 1 / (2\e k + 2),
|
||||
* - −1 (fail unconditionally) with prob 1 / (2\e k + 2).
|
||||
* .
|
||||
* This simulates \code
|
||||
double x = r.Fixed(); // Uniform in [0,1)
|
||||
x *= (2 * k + 2);
|
||||
return x < 2 * k ? 1 : (x < 2 * k + 1 ? 0 : -1);
|
||||
\endcode
|
||||
**********************************************************************/
|
||||
template<class Random> static int Choose(Random& r, int k) {
|
||||
// Limit base to 2^15 to avoid integer overflow
|
||||
const int b = bits > 15 ? 15 : bits;
|
||||
const unsigned mask = (1u << b) - 1;
|
||||
const int m = 2 * k + 2;
|
||||
int n1 = m - 2, n2 = m - 1;
|
||||
// Evaluate u < n/m where u is a random real number in [0,1). Write u =
|
||||
// (d + u') / 2^b where d is a random integer in [0,2^b) and u' is in
|
||||
// [0,1). Then u < n/m becomes u' < n'/m where n' = 2^b * n - d * m and
|
||||
// exit if n' <= 0 (false) or n' >= m (true).
|
||||
while (true) {
|
||||
int d = (mask & RandomNumber<bits>::RandomDigit(r)) * m;
|
||||
n1 = (std::max)((n1 << b) - d, 0);
|
||||
if (n1 >= m) return 1;
|
||||
n2 = (std::min)((n2 << b) - d, m);
|
||||
if (n2 <= 0) return -1;
|
||||
if (n1 == 0 && n2 == m) return 0;
|
||||
}
|
||||
}
|
||||
|
||||
mutable RandomNumber<bits> _x;
|
||||
mutable RandomNumber<bits> _p;
|
||||
mutable RandomNumber<bits> _q;
|
||||
};
|
||||
|
||||
template<int bits> template<class Random>
|
||||
bool ExactNormal<bits>::ExpProbH(Random& r) const {
|
||||
// Bit counts
|
||||
// ExpProbH: 2.846 = 3.786 * (1-exp(-1/2)) + 2.236 * exp(-1/2)
|
||||
// t = a * (1-exp(-1/2)) + b * exp(-1/2)
|
||||
// t = mean bit count for result = 2.846
|
||||
// a = mean bit count for false result = 3.786
|
||||
// b = mean bit count for true result = 2.236
|
||||
//
|
||||
// for bits large
|
||||
// t = exp(1/2) = 1.6487
|
||||
// a = exp(1/2)/(2*(1-exp(-1/2))) = 2.0951
|
||||
// b = exp(1/2)/(2*exp(-1/2)) = 1.3591
|
||||
//
|
||||
// Results for Prob(exp(-1)), omitting first test
|
||||
// total = 5.889, false = 5.347, true = 6.826
|
||||
//
|
||||
// Results for Prob(exp(-1)) using ExpProbH(r) && ExpProbH(r),
|
||||
// total = 4.572 = (1 - exp(-1)) * a + (1 + exp(-1/2)) * exp(-1/2) * b
|
||||
// false = 4.630 = a + b * exp(-1/2)/(1 + exp(-1/2)),
|
||||
// true = 4.472 = 2 * b
|
||||
_p.Init();
|
||||
if (_p.Digit(r, 0) >> (bits - 1)) return true;
|
||||
while (true) {
|
||||
_q.Init(); if (!_q.LessThan(r, _p)) return false;
|
||||
_p.Init(); if (!_p.LessThan(r, _q)) return true;
|
||||
}
|
||||
}
|
||||
|
||||
template<int bits> template<class Random>
|
||||
bool ExactNormal<bits>::ExpProb(Random& r, unsigned n) const {
|
||||
// Bit counts
|
||||
// ExpProb(n): t * (1-exp(-n/2))/(1-exp(-1/2))
|
||||
// ExpProb(n) = true: n * b
|
||||
// ExpProb(n) = false: a +
|
||||
// b * (exp(-1/2)/(1-exp(-1/2)) - n*exp(-n/2)/(1-exp(-n/2)))
|
||||
while (n--) { if (!ExpProbH(r)) return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
template<int bits> template<class Random>
|
||||
unsigned ExactNormal<bits>::ExpProbN(Random& r) const {
|
||||
// Bit counts
|
||||
// ExpProbN() = n: n * a + b
|
||||
unsigned n = 0;
|
||||
while (ExpProbH(r)) ++n;
|
||||
return n;
|
||||
}
|
||||
|
||||
template<int bits> template<class Random> RandomNumber<bits>
|
||||
ExactNormal<bits>::operator()(Random& r) const {
|
||||
// With bits = 1,
|
||||
// - mean number of bits used = 30.10434
|
||||
// - mean number of bits in fraction = 1.18700
|
||||
// - mean number of bits in result = 3.55257 (unary-binary)
|
||||
// - mean balance = 30.10434 - 3.55257 = 26.55177
|
||||
// - mean number of bits to generate a double = 83.33398
|
||||
// .
|
||||
// Note
|
||||
// - unary-binary notation (Knuth + Yao, 1976): write x = n + y, with n =
|
||||
// integer and y in [0,1). If n >=0, then write (n+1) 1's followed by a
|
||||
// 0; otherwise (n < 0), write (-n) 0's followed by a 1. Write y as a
|
||||
// binary fraction.
|
||||
// - (bits in result) - (bits in fraction) = 2 (for encoding overhead for
|
||||
// the integer part) + 0.36557, where 0.36557 = (bits used for integer
|
||||
// part) = sum(k*int(sqrt(2/pi)*exp(-x^2/2), x=k..k+1), k=0..inf)
|
||||
// - (bits for double) approx (bits used) - (bits in fraction) + 1 (for
|
||||
// guard bit) + 53.41664 where 53.41664 = (bits in fraction of double) =
|
||||
// sum((52-l)*int(sqrt(2/pi)*exp(-x^2/2), x=2^l,2^(l+1)), l=-inf..inf)
|
||||
// This is approximate because it doesn't account for the minimum
|
||||
// exponent, denormalized numbers, and rounding changing the exponent.
|
||||
//
|
||||
while (true) {
|
||||
// Executed sqrt(2/pi)/(1-exp(-1/2)) = 2.027818889827955 times on
|
||||
// average.
|
||||
unsigned k = ExpProbN(r); // the integer part of the result.
|
||||
if (ExpProb(r, (k - 1) * k)) {
|
||||
// Probability that this test succeeds is
|
||||
// (1 - exp(-1/2)) * sum(exp(-k/2) * exp(-(k-1)*k/2), k=0..inf))
|
||||
// = (1 - exp(-1/2)) * G = 0.689875359564630
|
||||
// where G = sum(exp(-k^2/2, k=0..inf) = 1.75331414402145
|
||||
// For k == 0, sample from exp(-x^2/2) for x in [0,1]. This succeeds
|
||||
// with probability int(exp(-x^2/2),x=0..1).
|
||||
//
|
||||
// For general k, substitute x' = x + k in exp(-x'^2/2), and obtain
|
||||
// exp(-k^2/2) * exp(-x*(x+2*k)/2). So sample from exp(-x*(x+2*k)/2).
|
||||
// This succeeds with probability int(exp(-x*(x+2*k)/2),x=0..1) =
|
||||
// int(exp(-x^2/2),x=k..k+1)*exp(k^2/2) =
|
||||
//
|
||||
// 0.8556243918921 for k = 0
|
||||
// 0.5616593588061 for k = 1
|
||||
// 0.3963669350376 for k = 2
|
||||
// 0.2974440159655 for k = 3
|
||||
// 0.2345104783458 for k = 4
|
||||
// 0.1921445042826 for k = 5
|
||||
//
|
||||
// Returns a result with prob sqrt(pi/2) / G = 0.714825772431666;
|
||||
// otherwise another trip through the outer loop is taken.
|
||||
_x.Init();
|
||||
unsigned s = 1;
|
||||
for (unsigned j = 0; j <= k; ++j) { // execute k + 1 times
|
||||
bool first;
|
||||
for (s = 1, first = true; ; s ^= 1, first = false) {
|
||||
// A simpler algorithm is indicated by ALT, results in
|
||||
// - mean number of bits used = 29.99968
|
||||
// - mean number of bits in fraction = 1.55580
|
||||
// - mean number of bits in result = 3.92137 (unary-binary)
|
||||
// - mean balance = 29.99968 - 3.92137 = 26.07831
|
||||
// - mean number of bits to generate a double = 82.86049
|
||||
// .
|
||||
// This has a smaller balance (by 0.47 bits). However the number
|
||||
// of bits in the fraction is larger by 0.37
|
||||
if (first) { // ALT: if (false) {
|
||||
// This implements the success prob (x + 2*k) / (2*k + 2).
|
||||
int y = Choose(r, k);
|
||||
if (y < 0) break; // the y test fails
|
||||
_q.Init();
|
||||
if (y > 0) { // the y test succeeds just test q < x
|
||||
if (!_q.LessThan(r, _x)) break;
|
||||
} else { // the y test is ambiguous
|
||||
// Test max(q, p) < x. List _q before _p since it ends up with
|
||||
// slightly more digits generated (and these will be used
|
||||
// subsequently). (_p's digits are immediately thrown away.)
|
||||
_p.Init(); if (!_x.GreaterPair(r, _q, _p)) break;
|
||||
}
|
||||
} else {
|
||||
// Split off the failure test for k == 0, i.e., factor the prob
|
||||
// x/2 test into the product: 1/2 (here) times x (in assignment
|
||||
// of y).
|
||||
if (k == 0 && Boolean(r)) break;
|
||||
// ALT: _q.Init(); if (!_q.LessThan(r, first ? _x : _p)) break;
|
||||
_q.Init(); if (!_q.LessThan(r, _p)) break;
|
||||
// succeed with prob k == 0 ? x : (x + 2*k) / (2*k + 2)
|
||||
int y = k == 0 ? 0 : Choose(r, k);
|
||||
if (y < 0)
|
||||
break;
|
||||
else if (y == 0) {
|
||||
_p.Init(); if (!_p.LessThan(r, _x)) break;
|
||||
}
|
||||
}
|
||||
_p.swap(_q); // a fast way of doing p = q
|
||||
}
|
||||
if (s == 0) break;
|
||||
}
|
||||
if (s != 0) {
|
||||
_x.AddInteger(k);
|
||||
if (Boolean(r)) _x.Negate(); // half of the numbers are negative
|
||||
return _x;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace RandomLib
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning (pop)
|
||||
#endif
|
||||
|
||||
#endif // RANDOMLIB_EXACTNORMAL_HPP
|
@ -1,100 +0,0 @@
|
||||
/**
|
||||
* \file ExactPower.hpp
|
||||
* \brief Header for ExactPower
|
||||
*
|
||||
* Sample exactly from a power distribution.
|
||||
*
|
||||
* Copyright (c) Charles Karney (2006-2011) <charles@karney.com> and licensed
|
||||
* under the MIT/X11 License. For more information, see
|
||||
* http://randomlib.sourceforge.net/
|
||||
**********************************************************************/
|
||||
|
||||
#if !defined(RANDOMLIB_EXACTPOWER_HPP)
|
||||
#define RANDOMLIB_EXACTPOWER_HPP 1
|
||||
|
||||
#include <RandomLib/RandomNumber.hpp>
|
||||
|
||||
namespace RandomLib {
|
||||
/**
|
||||
* \brief Sample exactly from a power distribution.
|
||||
*
|
||||
* Sample exactly from power distribution (<i>n</i> + 1)
|
||||
* <i>x</i><sup><i>n</i></sup> for \e x in (0,1) and integer \e n ≥ 0 using
|
||||
* infinite precision. The template parameter \e bits specifies the number
|
||||
* of bits in the base used for RandomNumber (i.e., base =
|
||||
* 2<sup><i>bits</i></sup>).
|
||||
*
|
||||
* This class uses some mutable RandomNumber objects. So a single ExactPower
|
||||
* object cannot safely be used by multiple threads. In a multi-processing
|
||||
* environment, each thread should use a thread-specific ExactPower object.
|
||||
* In addition, these should be invoked with thread-specific random generator
|
||||
* objects.
|
||||
*
|
||||
* @tparam bits the number of bits in each digit.
|
||||
**********************************************************************/
|
||||
template<int bits = 1> class ExactPower {
|
||||
public:
|
||||
/**
|
||||
* Return the random deviate with a power distribution, (<i>n</i> + 1)
|
||||
* <i>x</i><sup><i>n</i></sup> for \e x in (0,1) and integer \e n ≥ 0.
|
||||
* Returned result is a RandomNumber with base 2<sup><i>bits</i></sup>.
|
||||
* For \e bits = 1, the number of random bits in the result and consumed
|
||||
* are as follows: \verbatim
|
||||
n random bits
|
||||
result consumed
|
||||
0 0 0
|
||||
1 2 4
|
||||
2 2.33 6.67
|
||||
3 2.67 9.24
|
||||
4 2.96 11.71
|
||||
5 3.20 14.11
|
||||
6 3.41 16.45
|
||||
7 3.59 18.75
|
||||
8 3.75 21.01
|
||||
9 3.89 23.25
|
||||
10 4.02 25.47
|
||||
\endverbatim
|
||||
* The relative frequency of the results with \e bits = 1 and \e n = 2 can
|
||||
* be is shown by the histogram
|
||||
* \image html powerhist.png
|
||||
* The base of each rectangle gives the range represented by the
|
||||
* corresponding binary number and the area is proportional to its
|
||||
* frequency. A PDF version of this figure
|
||||
* <a href="powerhist.pdf">here</a>. This allows the figure to be
|
||||
* magnified to show the rectangles for all binary numbers up to 9 bits.
|
||||
*
|
||||
* @tparam Random the type of the random generator.
|
||||
* @param[in,out] r a random generator.
|
||||
* @param[in] n the power.
|
||||
* @return the random sample.
|
||||
**********************************************************************/
|
||||
template<class Random>
|
||||
RandomNumber<bits> operator()(Random& r, unsigned n) const;
|
||||
private:
|
||||
mutable RandomNumber<bits> _x;
|
||||
mutable RandomNumber<bits> _y;
|
||||
};
|
||||
|
||||
template<int bits> template<class Random> RandomNumber<bits>
|
||||
ExactPower<bits>::operator()(Random& r, unsigned n) const {
|
||||
// Return max(u_0, u_1, u_2, ..., u_n). Equivalent to taking the
|
||||
// (n+1)th root of u_0.
|
||||
_x.Init();
|
||||
for (; n--;) {
|
||||
_y.Init();
|
||||
// For bits = 1, we can save 1 bit on the first iteration by using a
|
||||
// technique suggested by Knuth and Yao (1976). When comparing the
|
||||
// digits of x and y, use 1 bit to determine if the digits are the same.
|
||||
// If they are, then use another bit for the value of the digit. If they
|
||||
// are not, then the next bit of the maximum must be 1 (avoiding using a
|
||||
// second bit). Applying this optimization to subsequent iterations
|
||||
// (when x already is filled with some bits) gets trickier.
|
||||
if (_x.LessThan(r, _y))
|
||||
_x.swap(_y); // x = y;
|
||||
}
|
||||
return _x;
|
||||
}
|
||||
|
||||
} // namespace RandomLib
|
||||
|
||||
#endif // RANDOMLIB_EXACTPOWER_HPP
|
@ -1,69 +0,0 @@
|
||||
/**
|
||||
* \file ExponentialDistribution.hpp
|
||||
* \brief Header for ExponentialDistribution
|
||||
*
|
||||
* Sample from an exponential distribution.
|
||||
*
|
||||
* Copyright (c) Charles Karney (2006-2011) <charles@karney.com> and licensed
|
||||
* under the MIT/X11 License. For more information, see
|
||||
* http://randomlib.sourceforge.net/
|
||||
**********************************************************************/
|
||||
|
||||
#if !defined(RANDOMLIB_EXPONENTIALDISTRIBUTION_HPP)
|
||||
#define RANDOMLIB_EXPONENTIALDISTRIBUTION_HPP 1
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace RandomLib {
|
||||
/**
|
||||
* \brief The exponential distribution.
|
||||
*
|
||||
* Sample from the distribution exp(−<i>x</i>/μ) for \e x ≥ 0.
|
||||
* This uses the logarithm method, see Knuth, TAOCP, Vol 2, Sec 3.4.1.D.
|
||||
* Example \code
|
||||
#include <RandomLib/ExponentialDistribution.hpp>
|
||||
|
||||
RandomLib::Random r;
|
||||
std::cout << "Seed set to " << r.SeedString() << "\n";
|
||||
RandomLib::ExponentialDistribution<double> expdist;
|
||||
std::cout << "Select from exponential distribution:";
|
||||
for (size_t i = 0; i < 10; ++i)
|
||||
std::cout << " " << expdist(r);
|
||||
std::cout << "\n";
|
||||
\endcode
|
||||
*
|
||||
* @tparam RealType the real type of the results (default double).
|
||||
**********************************************************************/
|
||||
template<typename RealType = double> class ExponentialDistribution {
|
||||
public:
|
||||
/**
|
||||
* The type returned by ExponentialDistribution::operator()(Random&)
|
||||
**********************************************************************/
|
||||
typedef RealType result_type;
|
||||
/**
|
||||
* Return a sample of type RealType from the exponential distribution and
|
||||
* mean μ. This uses Random::FloatU() which avoids taking log(0) and
|
||||
* allows rare large values to be returned. If μ = 1, minimum returned
|
||||
* value = 0 with prob 1/2<sup><i>p</i></sup>; maximum returned value =
|
||||
* log(2)(\e p + \e e) with prob 1/2<sup><i>p</i> + <i>e</i></sup>. Here
|
||||
* \e p is the precision of real type RealType and \e e is the exponent
|
||||
* range.
|
||||
*
|
||||
* @tparam Random the type of RandomCanonical generator.
|
||||
* @param[in,out] r the RandomCanonical generator.
|
||||
* @param[in] mu the mean value of the exponential distribution (default 1).
|
||||
* @return the random sample.
|
||||
**********************************************************************/
|
||||
template<class Random>
|
||||
RealType operator()(Random& r, RealType mu = RealType(1)) const throw();
|
||||
};
|
||||
|
||||
template<typename RealType> template<class Random> inline RealType
|
||||
ExponentialDistribution<RealType>::operator()(Random& r, RealType mu) const
|
||||
throw() {
|
||||
return -mu * std::log(r.template FloatU<RealType>());
|
||||
}
|
||||
|
||||
} // namespace RandomLib
|
||||
|
||||
#endif // RANDOMLIB_EXPONENTIALDISTRIBUTION_HPP
|
@ -1,166 +0,0 @@
|
||||
/**
|
||||
* \file ExponentialProb.hpp
|
||||
* \brief Header for ExponentialProb
|
||||
*
|
||||
* Return true with probabililty exp(-\e p).
|
||||
*
|
||||
* Copyright (c) Charles Karney (2006-2012) <charles@karney.com> and licensed
|
||||
* under the MIT/X11 License. For more information, see
|
||||
* http://randomlib.sourceforge.net/
|
||||
**********************************************************************/
|
||||
|
||||
#if !defined(RANDOMLIB_EXPONENTIALPROB_HPP)
|
||||
#define RANDOMLIB_EXPONENTIALPROB_HPP 1
|
||||
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
// Squelch warnings about constant conditional expressions
|
||||
# pragma warning (push)
|
||||
# pragma warning (disable: 4127)
|
||||
#endif
|
||||
|
||||
namespace RandomLib {
|
||||
/**
|
||||
* \brief The exponential probability.
|
||||
*
|
||||
* Return true with probability exp(−\e p). Basic method taken from:\n
|
||||
* J. von Neumann,\n Various Techniques used in Connection with Random
|
||||
* Digits,\n J. Res. Nat. Bur. Stand., Appl. Math. Ser. 12, 36--38
|
||||
* (1951),\n reprinted in Collected Works, Vol. 5, 768--770 (Pergammon,
|
||||
* 1963).\n See also the references given for the ExactExponential class.
|
||||
*
|
||||
* Here the method is extended to be exact by generating sufficient bits in
|
||||
* the random numbers in the algorithm to allow the unambiguous comparisons
|
||||
* to be made.
|
||||
*
|
||||
* Here's one way of sampling from a normal distribution with zero mean and
|
||||
* unit variance in the interval [−1,1] with reasonable accuracy:
|
||||
* \code
|
||||
#include <RandomLib/Random.hpp>
|
||||
#include <RandomLib/ExponentialProb.hpp>
|
||||
|
||||
double Normal(RandomLib::Random& r) {
|
||||
double x;
|
||||
RandomLib::ExponentialProb e;
|
||||
do
|
||||
x = r.FloatW();
|
||||
while ( !e(r, - 0.5 * x * x) );
|
||||
return x;
|
||||
}
|
||||
\endcode
|
||||
* (Note that the ExactNormal class samples from the normal distribution
|
||||
* exactly.)
|
||||
*
|
||||
* This class uses a mutable private vector. So a single ExponentialProb
|
||||
* object cannot safely be used by multiple threads. In a multi-processing
|
||||
* environment, each thread should use a thread-specific ExponentialProb
|
||||
* object.
|
||||
**********************************************************************/
|
||||
class ExponentialProb {
|
||||
private:
|
||||
typedef unsigned word;
|
||||
public:
|
||||
|
||||
ExponentialProb() : _v(std::vector<word>(alloc_incr)) {}
|
||||
/**
|
||||
* Return true with probability exp(−\e p). Returns false if \e p
|
||||
* ≤ 0. For in \e p (0,1], it requires about exp(\e p) random deviates.
|
||||
* For \e p large, it requires about exp(1)/(1 − exp(−1))
|
||||
* random deviates.
|
||||
*
|
||||
* @tparam RealType the real type of the argument.
|
||||
* @tparam Random the type of the random generator.
|
||||
* @param[in,out] r a random generator.
|
||||
* @param[in] p the probability.
|
||||
* @return true with probability \e p.
|
||||
**********************************************************************/
|
||||
template<typename RealType, class Random>
|
||||
bool operator()(Random& r, RealType p) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Return true with probability exp(−\e p) for \e p in [0,1].
|
||||
**********************************************************************/
|
||||
template<typename RealType, class Random>
|
||||
bool ExpFraction(Random& r, RealType p) const;
|
||||
/**
|
||||
* Holds as much of intermediate uniform deviates as needed.
|
||||
**********************************************************************/
|
||||
mutable std::vector<word> _v;
|
||||
/**
|
||||
* Increment on size of _v.
|
||||
**********************************************************************/
|
||||
static const unsigned alloc_incr = 16;
|
||||
};
|
||||
|
||||
template<typename RealType, class Random>
|
||||
bool ExponentialProb::operator()(Random& r, RealType p) const {
|
||||
STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer,
|
||||
"ExponentialProb(): invalid real type RealType");
|
||||
return p <= 0 || // True if p <=0
|
||||
// Ensure p - 1 < p. Also deal with IsNaN(p)
|
||||
( p < RealType(1)/std::numeric_limits<RealType>::epsilon() &&
|
||||
// exp(a+b) = exp(a) * exp(b)
|
||||
ExpFraction(r, p < RealType(1) ? p : RealType(1)) &&
|
||||
( p <= RealType(1) || operator()(r, p - RealType(1)) ) );
|
||||
}
|
||||
|
||||
template<typename RealType, class Random>
|
||||
bool ExponentialProb::ExpFraction(Random& r, RealType p) const {
|
||||
// Base of _v is 2^c. Adjust so that word(p) doesn't lose precision.
|
||||
static const int c = // The Intel compiler needs this to be static??
|
||||
std::numeric_limits<word>::digits <
|
||||
std::numeric_limits<RealType>::digits ?
|
||||
std::numeric_limits<word>::digits :
|
||||
std::numeric_limits<RealType>::digits;
|
||||
// m gives number of valid words in _v
|
||||
unsigned m = 0, l = unsigned(_v.size());
|
||||
if (p < RealType(1))
|
||||
while (true) {
|
||||
if (p <= RealType(0))
|
||||
return true;
|
||||
// p in (0, 1)
|
||||
if (l == m)
|
||||
_v.resize(l += alloc_incr);
|
||||
_v[m++] = r.template Integer<word, c>();
|
||||
p *= std::pow(RealType(2), c); // p in (0, 2^c)
|
||||
word w = word(p); // w in [0, 2^c)
|
||||
if (_v[m - 1] > w)
|
||||
return true;
|
||||
else if (_v[m - 1] < w)
|
||||
break;
|
||||
else // _v[m - 1] == w
|
||||
p -= RealType(w); // p in [0, 1)
|
||||
}
|
||||
// Here _v < p. Now loop finding decreasing V. Exit when first increasing
|
||||
// one is found.
|
||||
for (unsigned s = 0; ; s ^= 1) { // Parity of loop count
|
||||
for (unsigned j = 0; ; ++j) {
|
||||
if (j == m) {
|
||||
// Need more bits in the old V
|
||||
if (l == m)
|
||||
_v.resize(l += alloc_incr);
|
||||
_v[m++] = r.template Integer<word, c>();
|
||||
}
|
||||
word w = r.template Integer<word, c>();
|
||||
if (w > _v[j])
|
||||
return s != 0u; // New V is bigger, so exit
|
||||
else if (w < _v[j]) {
|
||||
_v[j] = w; // New V is smaller, update _v
|
||||
m = j + 1; // adjusting its size
|
||||
break; // and generate the next V
|
||||
}
|
||||
// Else w == _v[j] and we need to check the next c bits
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace RandomLib
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning (pop)
|
||||
#endif
|
||||
|
||||
#endif // RANDOMLIB_EXPONENTIALPROB_HPP
|
@ -1,67 +0,0 @@
|
||||
/**
|
||||
* \file InverseEProb.hpp
|
||||
* \brief Header for InverseEProb
|
||||
*
|
||||
* Return true with probabililty 1/\e e.
|
||||
*
|
||||
* Copyright (c) Charles Karney (2012) <charles@karney.com> and licensed under
|
||||
* the MIT/X11 License. For more information, see
|
||||
* http://randomlib.sourceforge.net/
|
||||
**********************************************************************/
|
||||
|
||||
#if !defined(RANDOMLIB_INVERSEEPROB_HPP)
|
||||
#define RANDOMLIB_INVERSEEPROB_HPP 1
|
||||
|
||||
#include <vector>
|
||||
#include <RandomLib/Random.hpp>
|
||||
|
||||
namespace RandomLib {
|
||||
|
||||
/**
|
||||
* \brief Return true with probability 1/\e e = exp(−1).
|
||||
*
|
||||
* InverseEProb p; p(Random& r) returns true with prob 1/\e e using von
|
||||
* Neumann's rejection method. It consumes 4.572 bits per call on average.
|
||||
*
|
||||
* This class illustrates how to return an exact result using coin tosses
|
||||
* only. A more efficient way of returning an exact result would be to use
|
||||
* ExponentialProb p; p(r, 1.0f);
|
||||
**********************************************************************/
|
||||
class InverseEProb {
|
||||
private:
|
||||
mutable std::vector<bool> _p;
|
||||
template<class Random> bool exph(Random& r) {
|
||||
// Return true with prob 1/sqrt(e).
|
||||
if (r.Boolean()) return true;
|
||||
_p.clear(); // vector of bits in p
|
||||
_p.push_back(false);
|
||||
for (bool s = false; ; s = !s) { // s is a parity
|
||||
for (size_t i = 0; ; ++i) { // Compare bits of p and q
|
||||
if (i == _p.size())
|
||||
_p.push_back(r.Boolean()); // Generate next bit of p if necessary
|
||||
if (r.Boolean()) { // Half the time the bits differ
|
||||
if (_p[i]) { // p's bit is 1, so q is smaller, update p
|
||||
_p[i] = false; // Last bit of q 0
|
||||
if (++i < _p.size()) _p.resize(i); // p = q
|
||||
break;
|
||||
} else
|
||||
return s; // p's bit is 0, so q is bigger, return parity
|
||||
} // The other half of the time the bits match, so go to next bit
|
||||
}
|
||||
}
|
||||
}
|
||||
public:
|
||||
/**
|
||||
* Return true with probability 1/\e e.
|
||||
*
|
||||
* @tparam Random the type of the random generator.
|
||||
* @param[in,out] r a random generator.
|
||||
* @return true with probability 1/\e e.
|
||||
**********************************************************************/
|
||||
template<class Random> bool operator()(Random& r)
|
||||
{ return exph(r) && exph(r); }
|
||||
};
|
||||
|
||||
} // namespace RandomLib
|
||||
|
||||
#endif // RANDOMLIB_INVERSEEPROB_HPP
|
@ -1,150 +0,0 @@
|
||||
/**
|
||||
* \file InversePiProb.hpp
|
||||
* \brief Header for InversePiProb
|
||||
*
|
||||
* Return true with probabililty 1/π.
|
||||
*
|
||||
* Copyright (c) Charles Karney (2012) <charles@karney.com> and licensed
|
||||
* under the MIT/X11 License. For more information, see
|
||||
* http://randomlib.sourceforge.net/
|
||||
**********************************************************************/
|
||||
|
||||
#if !defined(RANDOMLIB_INVERSEPIPROB_HPP)
|
||||
#define RANDOMLIB_INVERSEPIPROB_HPP 1
|
||||
|
||||
#include <cstdlib> // for abs(int)
|
||||
#include <RandomLib/Random.hpp>
|
||||
|
||||
namespace RandomLib {
|
||||
|
||||
/**
|
||||
* \brief Return true with probability 1/π.
|
||||
*
|
||||
* InversePiProb p; p(Random& r) returns true with prob 1/π using the
|
||||
* method of Flajolet et al. It consumes 9.6365 bits per call on average.
|
||||
*
|
||||
* The method is given in Section 3.3 of
|
||||
* - P. Flajolet, M. Pelletier, and M. Soria,<br>
|
||||
* On Buffon Machines and Numbers,<br> Proc. 22nd ACM-SIAM Symposium on
|
||||
* Discrete Algorithms (SODA), Jan. 2011.<br>
|
||||
* http://www.siam.org/proceedings/soda/2011/SODA11_015_flajoletp.pdf <br>
|
||||
* .
|
||||
* using the identity
|
||||
* \f[ \frac 1\pi = \sum_{n=0}^\infty
|
||||
* {{2n}\choose n}^3 \frac{6n+1}{2^{8n+2}} \f]
|
||||
*
|
||||
* It is based on the expression for 1/π given by Eq. (28) of<br>
|
||||
* - S. Ramanujan,<br>
|
||||
* Modular Equations and Approximations to π,<br>
|
||||
* Quart. J. Pure App. Math. 45, 350--372 (1914);<br>
|
||||
* In Collected Papers, edited by G. H. Hardy, P. V. Seshu Aiyar,
|
||||
* B. M. Wilson (Cambridge Univ. Press, 1927; reprinted AMS, 2000).<br>
|
||||
* http://books.google.com/books?id=oSioAM4wORMC&pg=PA36 <br>
|
||||
* .
|
||||
* \f[\frac4\pi = 1 + \frac74 \biggl(\frac 12 \biggr)^3
|
||||
* + \frac{13}{4^2} \biggl(\frac {1\cdot3}{2\cdot4} \biggr)^3
|
||||
* + \frac{19}{4^3} \biggl(\frac {1\cdot3\cdot5}{2\cdot4\cdot6} \biggr)^3
|
||||
* + \ldots \f]
|
||||
*
|
||||
* The following is a description of how to carry out the algorithm "by hand"
|
||||
* with a real coin, together with a worked example:
|
||||
* -# Perform three coin tossing experiments in which you toss a coin until
|
||||
* you get tails, e.g., <tt>HHHHT</tt>; <tt>HHHT</tt>; <tt>HHT</tt>. Let
|
||||
* <i>h</i><sub>1</sub> = 4, <i>h</i><sub>2</sub> = 3,
|
||||
* <i>h</i><sub>3</sub> = 2 be the numbers of heads tossed in each
|
||||
* experiment.
|
||||
* -# Compute <i>n</i> = ⌊<i>h</i><sub>1</sub>/2⌋ +
|
||||
* ⌊<i>h</i><sub>2</sub>/2⌋ +
|
||||
* mod(⌊(<i>h</i><sub>3</sub> − 1)/3⌋, 2) = 2 + 1 + 0
|
||||
* = 3. Here is a table of the 3 contributions to <i>n</i>:\verbatim
|
||||
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 h
|
||||
0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 floor(h1/2)
|
||||
0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 floor(h2/2)
|
||||
1 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 1 1 mod(floor((h3-1)/3), 2)
|
||||
\endverbatim
|
||||
* -# Perform three additional coin tossing experiments in each of which you
|
||||
* toss a coin 2<i>n</i> = 6 times, e.g., <tt>TTHHTH</tt>;
|
||||
* <tt>HHTHH|H</tt>; <tt>THHHHH</tt>. Are the number of heads and tails
|
||||
* equal in each experiment? <b>yes</b> and <b>no</b> and <b>no</b> →
|
||||
* <b>false</b>. (Here, you can give up at the |.)
|
||||
* .
|
||||
* The final result in this example is <b>false</b>. The most common way a
|
||||
* <b>true</b> result is obtained is with <i>n</i> = 0, in which case the
|
||||
* last step vacuously returns <b>true</b>.
|
||||
*
|
||||
* Proof of the algorithm: Flajolet et al. rearrange Ramanujan's identity as
|
||||
* \f[ \frac 1\pi = \sum_{n=0}^\infty
|
||||
* \biggl[{2n\choose n} \frac1{2^{2n}} \biggr]^3
|
||||
* \frac{6n+1}{2^{2n+2}}. \f]
|
||||
* Noticing that
|
||||
* \f[ \sum_{n=0}^\infty
|
||||
* \frac{6n+1}{2^{2n+2}} = 1, \f]
|
||||
* the algorithm becomes:
|
||||
* -# pick <i>n</i> ≥ 0 with prob (6<i>n</i>+1) / 2<sup>2<i>n</i>+2</sup>
|
||||
* (mean <i>n</i> = 11/9);
|
||||
* -# return <b>true</b> with prob (binomial(2<i>n</i>, <i>n</i>) /
|
||||
* 2<sup>2<i>n</i></sup>)<sup>3</sup>.
|
||||
*
|
||||
* Implement (1) as
|
||||
* - geom4(r) + geom4(r) returns <i>n</i> with probability 9(<i>n</i> +
|
||||
* 1) / 2<sup>2<i>n</i>+4</sup>;
|
||||
* - geom4(r) + geom4(r) + 1 returns <i>n</i> with probability
|
||||
* 36<i>n</i> / 2<sup>2<i>n</i>+4</sup>;
|
||||
* - combine these with probabilities [4/9, 5/9] to yield (6<i>n</i> +
|
||||
* 1) / 2<sup>2<i>n</i>+2</sup>, as required.
|
||||
* .
|
||||
* Implement (2) as the outcome of 3 coin tossing experiments of 2<i>n</i>
|
||||
* tosses with success defined as equal numbers of heads and tails in each
|
||||
* trial.
|
||||
*
|
||||
* This class illustrates how to return an exact result using coin tosses
|
||||
* only. A more efficient implementation (which is still exact) would
|
||||
* replace prob59 by r.Prob(5,9) and geom4 by LeadingZeros z; z(r)/2.
|
||||
**********************************************************************/
|
||||
class InversePiProb {
|
||||
private:
|
||||
template<class Random> bool prob59(Random& r) {
|
||||
// true with prob 5/9 = 0.1 000 111 000 111 000 111 ... (binary expansion)
|
||||
if (r.Boolean()) return true;
|
||||
for (bool res = false; ; res = !res)
|
||||
for (int i = 3; i--; ) if (r.Boolean()) return res;
|
||||
}
|
||||
|
||||
template<class Random> int geom4(Random& r) { // Geom(1/4)
|
||||
int sum = 0;
|
||||
while (r.Boolean() && r.Boolean()) ++sum;
|
||||
return sum;
|
||||
}
|
||||
|
||||
template<class Random> bool binom(Random& r, int n) {
|
||||
// Probability of equal heads and tails on 2*n tosses
|
||||
// = binomial(2*n, n) / 2^(2*n)
|
||||
int d = 0;
|
||||
for (int k = n; k--; ) d += r.Boolean() ? 1 : -1;
|
||||
for (int k = n; k--; ) {
|
||||
d += r.Boolean() ? 1 : -1;
|
||||
// This optimization saves 0.1686 bit per call to operator() on average.
|
||||
if (std::abs(d) > k) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
* Return true with probability 1/π.
|
||||
*
|
||||
* @tparam Random the type of the random generator.
|
||||
* @param[in,out] r a random generator.
|
||||
* @return true with probability 1/π.
|
||||
**********************************************************************/
|
||||
template<class Random> bool operator()(Random& r) {
|
||||
// Return true with prob 1/pi.
|
||||
int n = geom4(r) + geom4(r) + (prob59(r) ? 1 : 0);
|
||||
for (int j = 3; j--; ) if (!binom(r, n)) return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace RandomLib
|
||||
|
||||
#endif // RANDOMLIB_INVERSEPIPROB_HPP
|
@ -1,84 +0,0 @@
|
||||
/**
|
||||
* \file LeadingZeros.hpp
|
||||
* \brief Header for LeadingZeros
|
||||
*
|
||||
* Count the leading zeros in a real number.
|
||||
*
|
||||
* Copyright (c) Charles Karney (2006-2011) <charles@karney.com> and licensed
|
||||
* under the MIT/X11 License. For more information, see
|
||||
* http://randomlib.sourceforge.net/
|
||||
**********************************************************************/
|
||||
|
||||
#if !defined(RANDOMLIB_LEADINGZEROS_HPP)
|
||||
#define RANDOMLIB_LEADINGZEROS_HPP 1
|
||||
|
||||
namespace RandomLib {
|
||||
/**
|
||||
* \brief Count of leading zeros.
|
||||
*
|
||||
* Count of leading zero bits after the binary point in a real number
|
||||
* uniformly distributed in (0,1). (This is equivalent to the geometric
|
||||
* distribution with probability 1/2.) For example
|
||||
* \code
|
||||
#include <RandomLib/LeadingZeros.hpp>
|
||||
|
||||
RandomLib::Random r; // A RandomGenerator works here too
|
||||
std::cout << "Seed set to " << r.SeedString() << "\n";
|
||||
LeadingZeros zeros;
|
||||
std::cout << "Count of leading zeros:";
|
||||
for (size_t i = 0; i < 20; ++i)
|
||||
std::cout << " " << zeros(r);
|
||||
std::cout << "\n";
|
||||
\endcode
|
||||
**********************************************************************/
|
||||
class LeadingZeros {
|
||||
public:
|
||||
/**
|
||||
* Return the number of zero bits after the binary point in a real number
|
||||
* uniformly distributed in (0,1). Thus \e k is returned with probability
|
||||
* 1/2<sup><i>k</i>+1</sup>. Because MT19937 is \e not a perfect random
|
||||
* number generator, this always returns a result in [0, 19937).
|
||||
*
|
||||
* @tparam Random the type of the random generator.
|
||||
* @param[in,out] r a random generator.
|
||||
* @return the random sample.
|
||||
**********************************************************************/
|
||||
template<class Random> unsigned operator()(Random& r) const throw();
|
||||
};
|
||||
|
||||
template<class Random>
|
||||
unsigned LeadingZeros::operator()(Random& r) const throw() {
|
||||
// It's simpler to count the number of trailing ones in each w-bit block
|
||||
// stopping when we get to a zero bit.
|
||||
//
|
||||
// Process a word in chunks of size m. The algorithm here can deal with
|
||||
// any m assuming that z is modified accordingly. m = 4 is an approximate
|
||||
// optimum.
|
||||
//
|
||||
// Can also adapt this routine to use RandomNumber::highest_bit_idx
|
||||
// instead. However the result is considerably slower.
|
||||
const int m = 4;
|
||||
STATIC_ASSERT(m <= Random::width, "LeadingZeros: m too large");
|
||||
// mask with m low bits set
|
||||
const typename Random::result_type mask = ~(Random::max << m);
|
||||
// Number of trailing 1 bits in [0, 1<<m). However, correct results are
|
||||
// also obtained with any permutation of this array. This particular
|
||||
// permutation is useful since the initial 1/2, 1/4, etc. can be used for
|
||||
// m-1, m-2, etc. To generate the array for the next higher m, append a
|
||||
// duplicate of the array and increment the last entry by one.
|
||||
const unsigned z[1 << m] =
|
||||
{ 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, };
|
||||
typename Random::result_type x = r();
|
||||
for (unsigned b = m, n = 0; b < Random::width; b += m) {
|
||||
n += z[x & mask]; // count trailing 1s in chunk
|
||||
if (n < b) // chunk contains a 0
|
||||
return n;
|
||||
x >>= m; // shift out the chunk we've processed
|
||||
}
|
||||
// x is all ones (prob 1/2^w); process the next word.
|
||||
return Random::width + operator()(r);
|
||||
}
|
||||
|
||||
} // namespace RandomLib
|
||||
|
||||
#endif // RANDOMLIB_LEADINGZEROS_HPP
|
@ -1,92 +0,0 @@
|
||||
/**
|
||||
* \file MPFRExponential.hpp
|
||||
* \brief Header for MPFRExponential
|
||||
*
|
||||
* Sampling exactly from the normal distribution for MPFR.
|
||||
*
|
||||
* Copyright (c) Charles Karney (2012) <charles@karney.com> and licensed under
|
||||
* the MIT/X11 License. For more information, see
|
||||
* http://randomlib.sourceforge.net/
|
||||
**********************************************************************/
|
||||
|
||||
#if !defined(RANDOMLIB_MPFREXPONENTIAL_HPP)
|
||||
#define RANDOMLIB_MPFREXPONENTIAL_HPP 1
|
||||
|
||||
#include <RandomLib/MPFRRandom.hpp>
|
||||
|
||||
#if HAVE_MPFR || defined(DOXYGEN)
|
||||
|
||||
namespace RandomLib {
|
||||
|
||||
/**
|
||||
* \brief The exponential distribution for MPFR.
|
||||
*
|
||||
* This is a transcription of ExactExponential (version 1.4) for use with
|
||||
* MPFR.
|
||||
*
|
||||
* This class uses mutable private objects. So a single MPFRExponential
|
||||
* object cannot safely be used by multiple threads. In a multi-processing
|
||||
* environment, each thread should use a thread-specific MPFRExponential
|
||||
* object.
|
||||
*
|
||||
* @tparam bits the number of bits in each digit.
|
||||
**********************************************************************/
|
||||
template<int bits = 32> class MPFRExponential {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Initialize the MPFRExponential object.
|
||||
**********************************************************************/
|
||||
MPFRExponential() {};
|
||||
/**
|
||||
* Sample from the exponential distribution with mean 1 returning a
|
||||
* MPFRRandom.
|
||||
*
|
||||
* @param[out] t the MPFRRandom result.
|
||||
* @param[in,out] r a GMP random generator.
|
||||
**********************************************************************/
|
||||
void operator()(MPFRRandom<bits>& t, gmp_randstate_t r) const
|
||||
{ Compute(r); _x.swap(t); }
|
||||
/**
|
||||
* Sample from the exponential distribution with mean 1.
|
||||
*
|
||||
* @param[out] val the sample from the exponential distribution
|
||||
* @param[in,out] r a GMP random generator.
|
||||
* @param[in] round the rounding direction.
|
||||
* @return the MPFR ternary result (± if val is larger/smaller than
|
||||
* the exact sample).
|
||||
**********************************************************************/
|
||||
int operator()(mpfr_t val, gmp_randstate_t r, mpfr_rnd_t round) const
|
||||
{ Compute(r); return _x(val, r, round); }
|
||||
private:
|
||||
// Disable copy constructor and assignment operator
|
||||
MPFRExponential(const MPFRExponential&);
|
||||
MPFRExponential& operator=(const MPFRExponential&);
|
||||
int ExpFraction(gmp_randstate_t r, MPFRRandom<bits>& p) const {
|
||||
// The early bale out
|
||||
if (p.TestHighBit(r)) return 0;
|
||||
// Implement the von Neumann algorithm
|
||||
_w.Init();
|
||||
if (!_w.LessThan(r, p)) return 1;
|
||||
while (true) {
|
||||
_v.Init(); if (!_v.LessThan(r, _w)) return 0;
|
||||
_w.Init(); if (!_w.LessThan(r, _v)) return 1;
|
||||
}
|
||||
}
|
||||
void Compute(gmp_randstate_t r) const {
|
||||
_x.Init();
|
||||
unsigned k = 0;
|
||||
while (!ExpFraction(r, _x)) { ++k; _x.Init(); }
|
||||
if (k & 1) _x.SetHighBit(r);
|
||||
_x.AddInteger(k >> 1);
|
||||
return;
|
||||
}
|
||||
mutable MPFRRandom<bits> _x;
|
||||
mutable MPFRRandom<bits> _v;
|
||||
mutable MPFRRandom<bits> _w;
|
||||
};
|
||||
|
||||
} // namespace RandomLib
|
||||
|
||||
#endif // HAVE_MPFR
|
||||
#endif // RANDOMLIB_MPFREXPONENTIAL_HPP
|
@ -1,123 +0,0 @@
|
||||
/**
|
||||
* \file MPFRExponentialL.hpp
|
||||
* \brief Header for MPFRExponentialL
|
||||
*
|
||||
* Sampling exactly from the exponential distribution for MPFR using the
|
||||
* traditional method.
|
||||
*
|
||||
* Copyright (c) Charles Karney (2012) <charles@karney.com> and licensed under
|
||||
* the MIT/X11 License. For more information, see
|
||||
* http://randomlib.sourceforge.net/
|
||||
**********************************************************************/
|
||||
|
||||
#if !defined(RANDOMLIB_MPFREXPONENTIALL_HPP)
|
||||
#define RANDOMLIB_MPFREXPONENTIALL_HPP 1
|
||||
|
||||
#include <cmath> // for log
|
||||
#include <mpfr.h>
|
||||
|
||||
#define HAVE_MPFR (MPFR_VERSION_MAJOR >= 3)
|
||||
|
||||
#if HAVE_MPFR || defined(DOXYGEN)
|
||||
|
||||
namespace RandomLib {
|
||||
|
||||
/**
|
||||
* \brief The exponential distribution for MPFR (the log method).
|
||||
*
|
||||
* This class is <b>DEPRECATED</b>. It is included for illustrative purposes
|
||||
* only. The MPFRExponential class provides a much more efficient method for
|
||||
* sampling from the exponential distribution.
|
||||
*
|
||||
* This is an adaption of ExponentialDistribution to MPFR. The changes are
|
||||
* - Use MPFR's random number generator
|
||||
* - Use sufficient precision internally to ensure that a correctly rounded
|
||||
* result is returned.
|
||||
*
|
||||
* This class uses mutable private objects. So a single MPFRExponentialL
|
||||
* object cannot safely be used by multiple threads. In a multi-processing
|
||||
* environment, each thread should use a thread-specific MPFRExponentialL
|
||||
* object.
|
||||
**********************************************************************/
|
||||
class MPFRExponentialL {
|
||||
private:
|
||||
// The number of bits of randomness to add at a time.
|
||||
static const long chunk_ = 32;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Initialize the MPFRExponentialL object.
|
||||
**********************************************************************/
|
||||
MPFRExponentialL() {
|
||||
mpz_init(_vi);
|
||||
mpfr_init2(_eps, chunk_);
|
||||
mpfr_init2(_v1, chunk_);
|
||||
mpfr_init2(_v2, chunk_);
|
||||
}
|
||||
/**
|
||||
* Destroy the MPFRExponentialL object.
|
||||
**********************************************************************/
|
||||
~MPFRExponentialL() {
|
||||
mpfr_clear(_v2);
|
||||
mpfr_clear(_v1);
|
||||
mpfr_clear(_eps);
|
||||
mpz_clear(_vi);
|
||||
}
|
||||
/**
|
||||
* Sample from the exponential distribution with mean 1.
|
||||
*
|
||||
* @param[out] val the sample from the exponential distribution
|
||||
* @param[in,out] r a GMP random generator.
|
||||
* @param[in] round the rounding direction.
|
||||
* @return the MPFR ternary result (± if val is larger/smaller than
|
||||
* the exact sample).
|
||||
**********************************************************************/
|
||||
int operator()(mpfr_t val, gmp_randstate_t r, mpfr_rnd_t round) const {
|
||||
|
||||
mpfr_prec_t prec0 = mpfr_get_prec (val);
|
||||
mpfr_prec_t prec = prec0 + 10; // A rough optimum
|
||||
mpz_urandomb(_vi, r, prec);
|
||||
mpfr_set_ui_2exp(_eps, 1u, -prec, MPFR_RNDN);
|
||||
mpfr_set_prec(_v1, prec);
|
||||
mpfr_set_z_2exp(_v1, _vi, -prec, MPFR_RNDN);
|
||||
mpfr_set_prec(_v2, prec);
|
||||
mpfr_add(_v2, _v1, _eps, MPFR_RNDN);
|
||||
while (true) {
|
||||
int f2 = mpfr_log(val, _v2, round); // val = log(upper bound)
|
||||
mpfr_set_prec(_v2, prec0);
|
||||
int f1 = mpfr_log(_v2, _v1, round); // v2 = log(lower bound)
|
||||
if (f1 == f2 && mpfr_equal_p(val, _v2)) {
|
||||
mpfr_neg(val, val, MPFR_RNDN);
|
||||
return -f1;
|
||||
}
|
||||
prec = Refine(r, prec);
|
||||
}
|
||||
}
|
||||
private:
|
||||
// disable copy constructor and assignment operator
|
||||
MPFRExponentialL(const MPFRExponentialL&);
|
||||
MPFRExponentialL& operator=(const MPFRExponentialL&);
|
||||
// Refine the random interval
|
||||
mpfr_prec_t Refine(gmp_randstate_t r, mpfr_prec_t prec)
|
||||
const {
|
||||
prec += chunk_;
|
||||
mpfr_div_2ui(_eps, _eps, chunk_, MPFR_RNDN);
|
||||
mpz_urandomb(_vi, r, chunk_);
|
||||
mpfr_set_prec(_v2, prec);
|
||||
mpfr_set_z_2exp(_v2, _vi, -prec, MPFR_RNDN);
|
||||
mpfr_add(_v2, _v1, _v2, MPFR_RNDN);
|
||||
mpfr_swap(_v1, _v2); // v1 = v2;
|
||||
mpfr_set_prec(_v2, prec);
|
||||
mpfr_add(_v2, _v1, _eps, MPFR_RNDN);
|
||||
return prec;
|
||||
}
|
||||
mutable mpz_t _vi;
|
||||
mutable mpfr_t _eps;
|
||||
mutable mpfr_t _v1;
|
||||
mutable mpfr_t _v2;
|
||||
};
|
||||
|
||||
} // namespace RandomLib
|
||||
|
||||
#endif // HAVE_MPFR
|
||||
#endif // RANDOMLIB_MPFREXPONENTIALL_HPP
|
@ -1,144 +0,0 @@
|
||||
/**
|
||||
* \file MPFRNormal.hpp
|
||||
* \brief Header for MPFRNormal
|
||||
*
|
||||
* Sampling exactly from the normal distribution for MPFR.
|
||||
*
|
||||
* Copyright (c) Charles Karney (2012) <charles@karney.com> and licensed under
|
||||
* the MIT/X11 License. For more information, see
|
||||
* http://randomlib.sourceforge.net/
|
||||
**********************************************************************/
|
||||
|
||||
#if !defined(RANDOMLIB_MPFRNORMAL_HPP)
|
||||
#define RANDOMLIB_MPFRNORMAL_HPP 1
|
||||
|
||||
#include <algorithm> // for max/min
|
||||
#include <RandomLib/MPFRRandom.hpp>
|
||||
|
||||
#if HAVE_MPFR || defined(DOXYGEN)
|
||||
|
||||
namespace RandomLib {
|
||||
|
||||
/**
|
||||
* \brief The normal distribution for MPFR.
|
||||
*
|
||||
* This is a transcription of ExactNormal (version 1.3) for use with MPFR.
|
||||
*
|
||||
* This class uses mutable private objects. So a single MPFRNormal object
|
||||
* cannot safely be used by multiple threads. In a multi-processing
|
||||
* environment, each thread should use a thread-specific MPFRNormal object.
|
||||
*
|
||||
* @tparam bits the number of bits in each digit.
|
||||
**********************************************************************/
|
||||
template<int bits = 32> class MPFRNormal {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Initialize the MPFRNormal object.
|
||||
**********************************************************************/
|
||||
MPFRNormal() { mpz_init(_tt); }
|
||||
/**
|
||||
* Destroy the MPFRNormal object.
|
||||
**********************************************************************/
|
||||
~MPFRNormal() { mpz_clear(_tt); }
|
||||
/**
|
||||
* Sample from the normal distribution with mean 0 and variance 1 returning
|
||||
* a MPFRRandom.
|
||||
*
|
||||
* @param[out] t the MPFRRandom result.
|
||||
* @param[in,out] r a GMP random generator.
|
||||
**********************************************************************/
|
||||
void operator()(MPFRRandom<bits>& t,gmp_randstate_t r) const
|
||||
{ Compute(r); return _x.swap(t); }
|
||||
/**
|
||||
* Sample from the normal distribution with mean 0 and variance 1.
|
||||
*
|
||||
* @param[out] val the sample from the normal distribution
|
||||
* @param[in,out] r a GMP random generator.
|
||||
* @param[in] round the rounding direction.
|
||||
* @return the MPFR ternary result (±1 if val is larger/smaller than
|
||||
* the exact sample).
|
||||
**********************************************************************/
|
||||
int operator()(mpfr_t val, gmp_randstate_t r, mpfr_rnd_t round) const
|
||||
{ Compute(r); return _x(val, r, round); }
|
||||
private:
|
||||
// Disable copy constructor and assignment operator
|
||||
MPFRNormal(const MPFRNormal&);
|
||||
MPFRNormal& operator=(const MPFRNormal&);
|
||||
// True with prob exp(-1/2)
|
||||
int ExpProbH(gmp_randstate_t r) const {
|
||||
_p.Init(); if (_p.TestHighBit(r)) return 1;
|
||||
// von Neumann rejection
|
||||
while (true) {
|
||||
_q.Init(); if (!_q.LessThan(r, _p)) return 0;
|
||||
_p.Init(); if (!_p.LessThan(r, _q)) return 1;
|
||||
}
|
||||
}
|
||||
// True with prob exp(-n/2)
|
||||
int ExpProb(gmp_randstate_t r, unsigned n) const {
|
||||
while (n--) { if (!ExpProbH(r)) return 0; }
|
||||
return 1;
|
||||
}
|
||||
// n with prob (1-exp(-1/2)) * exp(-n/2)
|
||||
unsigned ExpProbN(gmp_randstate_t r) const {
|
||||
unsigned n = 0;
|
||||
while (ExpProbH(r)) ++n;
|
||||
return n;
|
||||
}
|
||||
// Return:
|
||||
// 1 with prob 2k/(2k + 2)
|
||||
// 0 with prob 1/(2k + 2)
|
||||
// -1 with prob 1/(2k + 2)
|
||||
int Choose(gmp_randstate_t r, int k) const {
|
||||
const int b = 15; // To avoid integer overflow on multiplication
|
||||
const int m = 2 * k + 2;
|
||||
int n1 = m - 2, n2 = m - 1;
|
||||
while (true) {
|
||||
mpz_urandomb(_tt, r, b);
|
||||
int d = int( mpz_get_ui(_tt) ) * m;
|
||||
n1 = (std::max)((n1 << b) - d, 0);
|
||||
if (n1 >= m) return 1;
|
||||
n2 = (std::min)((n2 << b) - d, m);
|
||||
if (n2 <= 0) return -1;
|
||||
if (n1 == 0 && n2 == m) return 0;
|
||||
}
|
||||
}
|
||||
void Compute(gmp_randstate_t r) const {
|
||||
while (true) {
|
||||
unsigned k = ExpProbN(r); // the integer part of the result.
|
||||
if (ExpProb(r, (k - 1) * k)) {
|
||||
_x.Init();
|
||||
unsigned s = 1;
|
||||
for (unsigned j = 0; j <= k; ++j) { // execute k + 1 times
|
||||
bool first;
|
||||
for (s = 1, first = true; ; s ^= 1, first = false) {
|
||||
if (k == 0 && _x.Boolean(r)) break;
|
||||
_q.Init(); if (!_q.LessThan(r, first ? _x : _p)) break;
|
||||
int y = k == 0 ? 0 : Choose(r, k);
|
||||
if (y < 0)
|
||||
break;
|
||||
else if (y == 0) {
|
||||
_p.Init(); if (!_p.LessThan(r, _x)) break;
|
||||
}
|
||||
_p.swap(_q); // a fast way of doing p = q
|
||||
}
|
||||
if (s == 0) break;
|
||||
}
|
||||
if (s != 0) {
|
||||
_x.AddInteger(k);
|
||||
if (_x.Boolean(r)) _x.Negate();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mutable mpz_t _tt; // A temporary
|
||||
mutable MPFRRandom<bits> _x;
|
||||
mutable MPFRRandom<bits> _p;
|
||||
mutable MPFRRandom<bits> _q;
|
||||
};
|
||||
|
||||
} // namespace RandomLib
|
||||
|
||||
#endif // HAVE_MPFR
|
||||
#endif // RANDOMLIB_MPFRNORMAL_HPP
|
@ -1,138 +0,0 @@
|
||||
/**
|
||||
* \file MPFRNormalK.hpp
|
||||
* \brief Header for MPFRNormalK
|
||||
*
|
||||
* Sampling exactly from the normal distribution for MPFR.
|
||||
*
|
||||
* Copyright (c) Charles Karney (2012) <charles@karney.com> and licensed under
|
||||
* the MIT/X11 License. For more information, see
|
||||
* http://randomlib.sourceforge.net/
|
||||
**********************************************************************/
|
||||
|
||||
#if !defined(RANDOMLIB_MPFRNORMALK_HPP)
|
||||
#define RANDOMLIB_MPFRNORMALK_HPP 1
|
||||
|
||||
#include <algorithm> // for max
|
||||
#include <RandomLib/MPFRRandom.hpp>
|
||||
#include <RandomLib/MPFRExponential.hpp>
|
||||
|
||||
#if HAVE_MPFR || defined(DOXYGEN)
|
||||
|
||||
namespace RandomLib {
|
||||
|
||||
/**
|
||||
* \brief The normal distribution for MPFR (Kahn algorithm).
|
||||
*
|
||||
* This class is <b>DEPRECATED</b>. It is included for illustrative purposes
|
||||
* only. The MPFRNormal class provides a somewhat more efficient method for
|
||||
* sampling from the normal distribution.
|
||||
*
|
||||
* Refs:
|
||||
* - H. Kahn, Rand Report RM-1237-AEC, p. 41 (1954).
|
||||
* - M. Abramowitz and I. A. Stegun, p. 953, Sec. 26.8.6.a(4) (1964).
|
||||
* .
|
||||
* N.B. Damien Stehle' drew my attention to this algorithm as a useful way to
|
||||
* compute normal deviates exactly.
|
||||
*
|
||||
* This class uses mutable private objects. So a single MPFRNormalK object
|
||||
* cannot safely be used by multiple threads. In a multi-processing
|
||||
* environment, each thread should use a thread-specific MPFRNormalK object.
|
||||
*
|
||||
* @tparam bits the number of bits in each digit.
|
||||
**********************************************************************/
|
||||
template<int bits = 32> class MPFRNormalK {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Initialize the MPFRNormalK object.
|
||||
**********************************************************************/
|
||||
MPFRNormalK()
|
||||
{ mpfr_init2(_xf, MPFR_PREC_MIN); mpfr_init2(_zf, MPFR_PREC_MIN); }
|
||||
/**
|
||||
* Destroy the MPFRNormalK object.
|
||||
**********************************************************************/
|
||||
~MPFRNormalK()
|
||||
{ mpfr_clear(_zf); mpfr_clear(_xf); }
|
||||
/**
|
||||
* Sample from the normal distribution with mean 0 and variance 1 returning
|
||||
* a MPFRRandom.
|
||||
*
|
||||
* @param[out] t the MPFRRandom result.
|
||||
* @param[in,out] r a GMP random generator.
|
||||
**********************************************************************/
|
||||
void operator()(MPFRRandom<bits>& t, gmp_randstate_t r) const
|
||||
{ Compute(r); _x.swap(t); }
|
||||
/**
|
||||
* Sample from the normal distribution with mean 0 and variance 1.
|
||||
*
|
||||
* @param[out] val the sample from the normal distribution
|
||||
* @param[in,out] r a GMP random generator.
|
||||
* @param[in] round the rounding direction.
|
||||
* @return the MPFR ternary result (±1 if val is larger/smaller than
|
||||
* the exact sample).
|
||||
**********************************************************************/
|
||||
int operator()(mpfr_t val, gmp_randstate_t r, mpfr_rnd_t round) const
|
||||
{ Compute(r); return _x(val, r, round); }
|
||||
private:
|
||||
// disable copy constructor and assignment operator
|
||||
MPFRNormalK(const MPFRNormalK&);
|
||||
MPFRNormalK& operator=(const MPFRNormalK&);
|
||||
void Compute(gmp_randstate_t r) const {
|
||||
// The algorithm is sample x and z from the exponential distribution; if
|
||||
// (x-1)^2 < 2*z, return (random sign)*x; otherwise repeat. Probability
|
||||
// of acceptance is sqrt(pi/2) * exp(-1/2) = 0.7602.
|
||||
while (true) {
|
||||
_edist(_x, r);
|
||||
_edist(_z, r);
|
||||
for (mp_size_t k = 1; ; ++k) {
|
||||
_x.ExpandTo(r, k - 1);
|
||||
_z.ExpandTo(r, k - 1);
|
||||
mpfr_prec_t prec = (std::max)(mpfr_prec_t(MPFR_PREC_MIN), k * bits);
|
||||
mpfr_set_prec(_xf, prec);
|
||||
mpfr_set_prec(_zf, prec);
|
||||
// Try for acceptance first; so compute upper limit on (y-1)^2 and
|
||||
// lower limit on 2*z.
|
||||
if (_x.UInteger() == 0) {
|
||||
_x(_xf, MPFR_RNDD);
|
||||
mpfr_ui_sub(_xf, 1u, _xf, MPFR_RNDU);
|
||||
} else {
|
||||
_x(_xf, MPFR_RNDU);
|
||||
mpfr_sub_ui(_xf, _xf, 1u, MPFR_RNDU);
|
||||
}
|
||||
mpfr_sqr(_xf, _xf, MPFR_RNDU);
|
||||
_z(_zf, MPFR_RNDD);
|
||||
mpfr_mul_2ui(_zf, _zf, 1u, MPFR_RNDD);
|
||||
if (mpfr_cmp(_xf, _zf) < 0) { // (y-1)^2 < 2*z, so accept
|
||||
if (_x.Boolean(r)) _x.Negate(); // include a random sign
|
||||
return;
|
||||
}
|
||||
// Try for rejection; so compute lower limit on (y-1)^2 and upper
|
||||
// limit on 2*z.
|
||||
if (_x.UInteger() == 0) {
|
||||
_x(_xf, MPFR_RNDU);
|
||||
mpfr_ui_sub(_xf, 1u, _xf, MPFR_RNDD);
|
||||
} else {
|
||||
_x(_xf, MPFR_RNDD);
|
||||
mpfr_sub_ui(_xf, _xf, 1u, MPFR_RNDD);
|
||||
}
|
||||
mpfr_sqr(_xf, _xf, MPFR_RNDD);
|
||||
_z(_zf, MPFR_RNDU);
|
||||
mpfr_mul_2ui(_zf, _zf, 1u, MPFR_RNDU);
|
||||
if (mpfr_cmp(_xf, _zf) > 0) // (y-1)^2 > 2*z, so reject
|
||||
break;
|
||||
// Otherwise repeat with more precision
|
||||
}
|
||||
// Reject and start over with a new y and z
|
||||
}
|
||||
}
|
||||
mutable MPFRRandom<bits> _x;
|
||||
mutable MPFRRandom<bits> _z;
|
||||
mutable mpfr_t _xf;
|
||||
mutable mpfr_t _zf;
|
||||
const MPFRExponential<bits> _edist;
|
||||
};
|
||||
|
||||
} // namespace RandomLib
|
||||
|
||||
#endif // HAVE_MPFR
|
||||
#endif // RANDOMLIB_MPFRNORMALK_HPP
|
@ -1,255 +0,0 @@
|
||||
/**
|
||||
* \file MPFRNormalR.hpp
|
||||
* \brief Header for MPFRNormalR
|
||||
*
|
||||
* Sampling exactly from the normal distribution for MPFR using the ratio
|
||||
* method.
|
||||
*
|
||||
* Copyright (c) Charles Karney (2012) <charles@karney.com> and licensed under
|
||||
* the MIT/X11 License. For more information, see
|
||||
* http://randomlib.sourceforge.net/
|
||||
**********************************************************************/
|
||||
|
||||
#if !defined(RANDOMLIB_MPFRNORMALR_HPP)
|
||||
#define RANDOMLIB_MPFRNORMALR_HPP 1
|
||||
|
||||
#include <algorithm> // for max/min
|
||||
#include <cmath> // for pow
|
||||
#include <mpfr.h>
|
||||
|
||||
#define HAVE_MPFR (MPFR_VERSION_MAJOR >= 3)
|
||||
|
||||
#if HAVE_MPFR || defined(DOXYGEN)
|
||||
|
||||
namespace RandomLib {
|
||||
|
||||
/**
|
||||
* \brief The normal distribution for MPFR (ratio method).
|
||||
*
|
||||
* This class is <b>DEPRECATED</b>. It is included for illustrative purposes
|
||||
* only. The MPFRNormal class provides a much more efficient method for
|
||||
* sampling from the normal distribution.
|
||||
*
|
||||
* This is an adaption of NormalDistribution to MPFR. The changes are
|
||||
* - Use MPFR's random number generator
|
||||
* - Use sufficient precision internally to ensure that a correctly rounded
|
||||
* result is returned.
|
||||
*
|
||||
* This class uses a mutable private object. So a single MPFRNormalR
|
||||
* object cannot safely be used by multiple threads. In a multi-processing
|
||||
* environment, each thread should use a thread-specific MPFRNormalR
|
||||
* object.
|
||||
**********************************************************************/
|
||||
class MPFRNormalR {
|
||||
private:
|
||||
// The number of bits of randomness to add at a time. Require that Leva's
|
||||
// bounds "work" at a precision of 2^-chunk and that an unsigned long can
|
||||
// hold this many bits.
|
||||
static const long chunk_ = 32;
|
||||
static const unsigned long m = 3684067834; // ceil(2^chunk*sqrt(2/e))
|
||||
|
||||
public:
|
||||
/**
|
||||
* Initialize the MPFRNormalR object.
|
||||
**********************************************************************/
|
||||
MPFRNormalR() {
|
||||
mpz_init(_ui);
|
||||
mpz_init(_vi);
|
||||
mpfr_init2(_eps, chunk_);
|
||||
mpfr_init2(_u, chunk_);
|
||||
mpfr_init2(_v, chunk_);
|
||||
mpfr_init2(_up, chunk_);
|
||||
mpfr_init2(_vp, chunk_);
|
||||
mpfr_init2(_vx, chunk_);
|
||||
mpfr_init2(_x1, chunk_);
|
||||
mpfr_init2(_x2, chunk_);
|
||||
}
|
||||
/**
|
||||
* Destroy the MPFRNormalR object.
|
||||
**********************************************************************/
|
||||
~MPFRNormalR() {
|
||||
mpfr_clear(_x2);
|
||||
mpfr_clear(_x1);
|
||||
mpfr_clear(_vx);
|
||||
mpfr_clear(_vp);
|
||||
mpfr_clear(_up);
|
||||
mpfr_clear(_v);
|
||||
mpfr_clear(_u);
|
||||
mpfr_clear(_eps);
|
||||
mpz_clear(_vi);
|
||||
mpz_clear(_ui);
|
||||
}
|
||||
/**
|
||||
* Sample from the normal distribution with mean 0 and variance 1.
|
||||
*
|
||||
* @param[out] val the sample from the normal distribution
|
||||
* @param[in,out] r a GMP random generator.
|
||||
* @param[in] round the rounding direction.
|
||||
* @return the MPFR ternary result (±1 if val is larger/smaller than
|
||||
* the exact sample).
|
||||
**********************************************************************/
|
||||
int operator()(mpfr_t val, gmp_randstate_t r, mpfr_rnd_t round) const {
|
||||
const double
|
||||
s = 0.449871, // Constants from Leva
|
||||
t = -0.386595,
|
||||
a = 0.19600 ,
|
||||
b = 0.25472 ,
|
||||
r1 = 0.27597 ,
|
||||
r2 = 0.27846 ,
|
||||
u1 = 0.606530, // sqrt(1/e) rounded down and up
|
||||
u2 = 0.606531,
|
||||
scale = std::pow(2.0, -chunk_); // for turning randoms into doubles
|
||||
|
||||
while (true) {
|
||||
mpz_urandomb(_vi, r, chunk_);
|
||||
if (mpz_cmp_ui(_vi, m) >= 0) continue; // Very early reject
|
||||
double vf = (mpz_get_ui(_vi) + 0.5) * scale;
|
||||
mpz_urandomb(_ui, r, chunk_);
|
||||
double uf = (mpz_get_ui(_ui) + 0.5) * scale;
|
||||
double
|
||||
x = uf - s,
|
||||
y = vf - t,
|
||||
Q = x*x + y * (a*y - b*x);
|
||||
if (Q >= r2) continue; // Early reject
|
||||
mpfr_set_ui_2exp(_eps, 1u, -chunk_, MPFR_RNDN);
|
||||
mpfr_prec_t prec = chunk_;
|
||||
mpfr_set_prec(_u, prec);
|
||||
mpfr_set_prec(_v, prec);
|
||||
// (u,v) = sw corner of range
|
||||
mpfr_set_z_2exp(_u, _ui, -prec, MPFR_RNDN);
|
||||
mpfr_set_z_2exp(_v, _vi, -prec, MPFR_RNDN);
|
||||
mpfr_set_prec(_up, prec);
|
||||
mpfr_set_prec(_vp, prec);
|
||||
// (up,vp) = ne corner of range
|
||||
mpfr_add(_up, _u, _eps, MPFR_RNDN);
|
||||
mpfr_add(_vp, _v, _eps, MPFR_RNDN);
|
||||
// Estimate how many extra bits will be needed to achieve the desired
|
||||
// precision.
|
||||
mpfr_prec_t prec_guard = 3 + chunk_ -
|
||||
(std::max)(mpz_sizeinbase(_ui, 2), mpz_sizeinbase(_vi, 2));
|
||||
if (Q > r1) {
|
||||
int reject;
|
||||
while (true) {
|
||||
// Rejection curve v^2 + 4 * u^2 * log(u) < 0 has a peak at u =
|
||||
// exp(-1/2) = 0.60653066. So treat uf in (0.606530, 0.606531) =
|
||||
// (u1, u2) specially
|
||||
|
||||
// Try for rejection first
|
||||
if (uf <= u1)
|
||||
reject = Reject(_u, _vp, prec, MPFR_RNDU);
|
||||
else if (uf >= u2)
|
||||
reject = Reject(_up, _vp, prec, MPFR_RNDU);
|
||||
else { // u in (u1, u2)
|
||||
mpfr_set_prec(_vx, prec);
|
||||
mpfr_add(_vx, _vp, _eps, MPFR_RNDN);
|
||||
reject = Reject(_u, _vx, prec, MPFR_RNDU); // Could use _up too
|
||||
}
|
||||
if (reject < 0) break; // tried to reject but failed, so accept
|
||||
|
||||
// Try for acceptance
|
||||
if (uf <= u1)
|
||||
reject = Reject(_up, _v, prec, MPFR_RNDD);
|
||||
else if (uf >= u2)
|
||||
reject = Reject(_u, _v, prec, MPFR_RNDD);
|
||||
else { // u in (u2, u2)
|
||||
mpfr_sub(_vx, _v, _eps, MPFR_RNDN);
|
||||
reject = Reject(_u, _vx, prec, MPFR_RNDD); // Could use _up too
|
||||
}
|
||||
if (reject > 0) break; // tried to accept but failed, so reject
|
||||
|
||||
prec = Refine(r, prec); // still can't decide, to refine
|
||||
}
|
||||
if (reject > 0) continue; // reject, back to outer loop
|
||||
}
|
||||
// Now evaluate v/u to the necessary precision
|
||||
mpfr_prec_t prec0 = mpfr_get_prec (val);
|
||||
// while (prec < prec0 + prec_guard) prec = Refine(r, prec);
|
||||
if (prec < prec0 + prec_guard)
|
||||
prec = Refine(r, prec,
|
||||
(prec0 + prec_guard - prec + chunk_ - 1) / chunk_);
|
||||
mpfr_set_prec(_x1, prec0);
|
||||
mpfr_set_prec(_x2, prec0);
|
||||
int flag;
|
||||
while (true) {
|
||||
int
|
||||
f1 = mpfr_div(_x1, _v, _up, round), // min slope
|
||||
f2 = mpfr_div(_x2, _vp, _u, round); // max slope
|
||||
if (f1 == f2 && mpfr_equal_p(_x1, _x2)) {
|
||||
flag = f1;
|
||||
break;
|
||||
}
|
||||
prec = Refine(r, prec);
|
||||
}
|
||||
mpz_urandomb(_ui, r, 1);
|
||||
if (mpz_tstbit(_ui, 0)) {
|
||||
flag = -flag;
|
||||
mpfr_neg(val, _x1, MPFR_RNDN);
|
||||
} else
|
||||
mpfr_set(val, _x1, MPFR_RNDN);
|
||||
// std::cerr << uf << " " << vf << " " << Q << "\n";
|
||||
return flag;
|
||||
}
|
||||
}
|
||||
private:
|
||||
// disable copy constructor and assignment operator
|
||||
MPFRNormalR(const MPFRNormalR&);
|
||||
MPFRNormalR& operator=(const MPFRNormalR&);
|
||||
// Refine the random square
|
||||
mpfr_prec_t Refine(gmp_randstate_t r, mpfr_prec_t prec, long num = 1)
|
||||
const {
|
||||
if (num <= 0) return prec;
|
||||
// Use _vx as scratch
|
||||
prec += num * chunk_;
|
||||
mpfr_div_2ui(_eps, _eps, num * chunk_, MPFR_RNDN);
|
||||
|
||||
mpz_urandomb(_ui, r, num * chunk_);
|
||||
mpfr_set_prec(_up, prec);
|
||||
mpfr_set_z_2exp(_up, _ui, -prec, MPFR_RNDN);
|
||||
mpfr_set_prec(_vx, prec);
|
||||
mpfr_add(_vx, _u, _up, MPFR_RNDN);
|
||||
mpfr_swap(_u, _vx); // u = vx
|
||||
mpfr_add(_up, _u, _eps, MPFR_RNDN);
|
||||
|
||||
mpz_urandomb(_vi, r, num * chunk_);
|
||||
mpfr_set_prec(_vp, prec);
|
||||
mpfr_set_z_2exp(_vp, _vi, -prec, MPFR_RNDN);
|
||||
mpfr_set_prec(_vx, prec);
|
||||
mpfr_add(_vx, _v, _vp, MPFR_RNDN);
|
||||
mpfr_swap(_v, _vx); // v = vx
|
||||
mpfr_add(_vp, _v, _eps, MPFR_RNDN);
|
||||
|
||||
return prec;
|
||||
}
|
||||
// Evaluate the sign of the rejection condition v^2 + 4*u^2*log(u)
|
||||
int Reject(mpfr_t u, mpfr_t v, mpfr_prec_t prec, mpfr_rnd_t round) const {
|
||||
// Use x1, x2 as scratch
|
||||
mpfr_set_prec(_x1, prec);
|
||||
|
||||
mpfr_log(_x1, u, round);
|
||||
mpfr_mul(_x1, _x1, u, round); // Important to do the multiplications in
|
||||
mpfr_mul(_x1, _x1, u, round); // this order so that rounding works right.
|
||||
mpfr_mul_2ui(_x1, _x1, 2u, round); // 4*u^2*log(u)
|
||||
|
||||
mpfr_set_prec(_x2, prec);
|
||||
mpfr_mul(_x2, v, v, round); // v^2
|
||||
|
||||
mpfr_add(_x1, _x1, _x2, round); // v^2 + 4*u^2*log(u)
|
||||
|
||||
return mpfr_sgn(_x1);
|
||||
}
|
||||
mutable mpz_t _ui;
|
||||
mutable mpz_t _vi;
|
||||
mutable mpfr_t _eps;
|
||||
mutable mpfr_t _u;
|
||||
mutable mpfr_t _v;
|
||||
mutable mpfr_t _up;
|
||||
mutable mpfr_t _vp;
|
||||
mutable mpfr_t _vx;
|
||||
mutable mpfr_t _x1;
|
||||
mutable mpfr_t _x2;
|
||||
};
|
||||
|
||||
} // namespace RandomLib
|
||||
|
||||
#endif // HAVE_MPFR
|
||||
#endif // RANDOMLIB_MPFRNORMALR_HPP
|
@ -1,383 +0,0 @@
|
||||
/**
|
||||
* \file MPFRRandom.hpp
|
||||
* \brief Header for MPFRRandom
|
||||
*
|
||||
* Utility class for MPFRUniform, MPFRExponential, and MPFRNormal.
|
||||
*
|
||||
* Copyright (c) Charles Karney (2012) <charles@karney.com> and licensed under
|
||||
* the MIT/X11 License. For more information, see
|
||||
* http://randomlib.sourceforge.net/
|
||||
**********************************************************************/
|
||||
|
||||
#if !defined(RANDOMLIB_MPFRRANDOM_HPP)
|
||||
#define RANDOMLIB_MPFRRANDOM_HPP 1
|
||||
|
||||
#include <algorithm> // for swap
|
||||
#include <mpfr.h>
|
||||
|
||||
#define HAVE_MPFR (MPFR_VERSION_MAJOR >= 3)
|
||||
|
||||
#if HAVE_MPFR || defined(DOXYGEN)
|
||||
|
||||
/**
|
||||
* A compile-time assert. Use C++11 static_assert, if available.
|
||||
**********************************************************************/
|
||||
#if !defined(STATIC_ASSERT)
|
||||
# if defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# define STATIC_ASSERT static_assert
|
||||
# elif defined(_MSC_VER) && _MSC_VER >= 1600
|
||||
# define STATIC_ASSERT static_assert
|
||||
# else
|
||||
# define STATIC_ASSERT(cond,reason) \
|
||||
{ enum{ STATIC_ASSERT_ENUM = 1/int(cond) }; }
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace RandomLib {
|
||||
|
||||
/**
|
||||
* \brief Handling random numbers in MPFR.
|
||||
*
|
||||
* This class provides roughly the same capabilities as RandomNumber. The
|
||||
* fraction is represented by a mpz integer \e f and an exponent \e e. We
|
||||
* have \e e ≥ 0 and 0 ≤ \e f < <i>b</i><sup><i>e</i></sup>, and \e b =
|
||||
* 2<sup><i>bits</i></sup>. This represents the number \e x = \e f
|
||||
* <i>b</i><sup>−<i>e</i></sup>, with x in [0, 1).
|
||||
*
|
||||
* @tparam bits the number of bits in each digit.
|
||||
*
|
||||
* \e bits must divide GMP_LIMB_BITS. The default value \e bits = 32 yields
|
||||
* portable results on all MPFR platforms.
|
||||
**********************************************************************/
|
||||
template<int bits = 32> class MPFRRandom {
|
||||
private:
|
||||
static const int limb_ = GMP_LIMB_BITS; // How many bits in a limb
|
||||
static const int loglimb_ = (limb_ == 32 ? 5 :
|
||||
(limb_ == 64 ? 6 :
|
||||
(limb_ == 128 ? 7 : -1)));
|
||||
static const int logbits_ = (bits == 1 ? 0 :
|
||||
(bits == 2 ? 1 :
|
||||
(bits == 4 ? 2 :
|
||||
(bits == 8 ? 3 :
|
||||
(bits == 16 ? 4 :
|
||||
(bits == 32 ? 5 :
|
||||
(bits == 64 ? 6 :
|
||||
(bits == 128 ? 7 : -1))))))));
|
||||
static const mp_limb_t mask_ = (bits == limb_ ? ~0UL : // Digit mask
|
||||
~(~0UL << (bits < limb_ ? bits : 0)));
|
||||
static const int logw_ = loglimb_ - logbits_; // 2^logw digits per limb
|
||||
static const unsigned wmask_ = ~(~0U << logw_);
|
||||
|
||||
mutable mpz_t _tt; // A temporary
|
||||
mpz_t _f; // The fraction
|
||||
mp_size_t _e; // Count of digits
|
||||
unsigned long _n; // Integer part
|
||||
int _s; // Sign
|
||||
void AddDigits(gmp_randstate_t r, long num = 1) { // Add num more digits
|
||||
if (num <= 0) return;
|
||||
mpz_mul_2exp(_f, _f, num << logbits_);
|
||||
mpz_urandomb(_tt, r, num << logbits_);
|
||||
mpz_add(_f, _f, _tt);
|
||||
_e += num;
|
||||
}
|
||||
// return k'th digit counting k = 0 as most significant
|
||||
mp_limb_t Digit(gmp_randstate_t r, mp_size_t k) {
|
||||
ExpandTo(r, k); // Now e > k
|
||||
k = _e - 1 - k; // Reverse k so k = 0 is least significant
|
||||
// (k >> logw) is the limb index
|
||||
// (k & wmask) is the digit position within the limb
|
||||
return mask_ &
|
||||
(mpz_getlimbn(_f, k >> logw_) >> ((k & wmask_) << logbits_));
|
||||
}
|
||||
// Return index [0..32] of highest bit set. Return 0 if x = 0, 32 is if x
|
||||
// = ~0. (From Algorithms for programmers by Joerg Arndt.)
|
||||
static int highest_bit_idx(unsigned long x) throw() {
|
||||
if (x == 0) return 0;
|
||||
int r = 1;
|
||||
// STILL TO DO: handle 64-bit unsigned longs.
|
||||
if (x & 0xffff0000UL) { x >>= 16; r += 16; }
|
||||
if (x & 0x0000ff00UL) { x >>= 8; r += 8; }
|
||||
if (x & 0x000000f0UL) { x >>= 4; r += 4; }
|
||||
if (x & 0x0000000cUL) { x >>= 2; r += 2; }
|
||||
if (x & 0x00000002UL) { r += 1; }
|
||||
return r;
|
||||
}
|
||||
public:
|
||||
/**
|
||||
* Initialize the MPFRRandom object.
|
||||
**********************************************************************/
|
||||
MPFRRandom() : _e(0u), _n(0u), _s(1) {
|
||||
STATIC_ASSERT(logbits_ >= 0 && loglimb_ >= 0 && logbits_ <= loglimb_,
|
||||
"MPRFRandom: unsupported value for bits");
|
||||
mpz_init(_f); mpz_init(_tt);
|
||||
}
|
||||
/**
|
||||
* Initialize the MPFRRandom object from another one.
|
||||
*
|
||||
* @param[in] t the MPFRRandom to copy.
|
||||
**********************************************************************/
|
||||
MPFRRandom(const MPFRRandom& t) : _e(t._e), _n(t._n), _s(t._s)
|
||||
{ mpz_init(_f); mpz_set(_f, t._f); mpz_init(_tt); }
|
||||
/**
|
||||
* Destroy the MPFRRandom object.
|
||||
**********************************************************************/
|
||||
~MPFRRandom() { mpz_clear(_f); mpz_clear(_tt); }
|
||||
/**
|
||||
* Assignment operator. (But swapping is typically faster.)
|
||||
*
|
||||
* @param[in] t the MPFRRandom to copy.
|
||||
**********************************************************************/
|
||||
MPFRRandom& operator=(const MPFRRandom& t) {
|
||||
_e = t._e;
|
||||
_n = t._n;
|
||||
_s = t._s;
|
||||
mpz_set(_f, t._f); // Don't copy _tt
|
||||
return *this;
|
||||
}
|
||||
/**
|
||||
* Swap with another MPFRRandom. This is a fast way of doing an
|
||||
* assignment.
|
||||
*
|
||||
* @param[in,out] t the MPFRRandom to swap with.
|
||||
**********************************************************************/
|
||||
void swap(MPFRRandom& t) throw() {
|
||||
if (this != &t) {
|
||||
std::swap(_e, t._e);
|
||||
std::swap(_n, t._n);
|
||||
std::swap(_s, t._s);
|
||||
mpz_swap(_f, t._f); // Don't swap _tt
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Reinitialize the MPFRRandom object, setting its value to [0,1].
|
||||
**********************************************************************/
|
||||
void Init() { mpz_set_ui(_f, 0u); _e = 0; _n = 0; _s = 1; }
|
||||
/**
|
||||
* @return the sign of the MPFRRandom (± 1).
|
||||
**********************************************************************/
|
||||
int Sign() const throw() { return _s; }
|
||||
/**
|
||||
* Change the sign of the MPFRRandom.
|
||||
**********************************************************************/
|
||||
void Negate() throw() { _s *= -1; }
|
||||
/**
|
||||
* @return the floor of the MPFRRandom
|
||||
**********************************************************************/
|
||||
long Floor() const throw() { return _s > 0 ? long(_n) : -1 - long(_n); }
|
||||
/**
|
||||
* @return the ceiling of the MPFRRandom
|
||||
**********************************************************************/
|
||||
long Ceiling() const throw() { return _s > 0 ? 1 + long(_n) : -long(_n); }
|
||||
/**
|
||||
* @return the unsigned integer component of the MPFRRandom.
|
||||
**********************************************************************/
|
||||
unsigned long UInteger() const throw() { return _n; }
|
||||
/**
|
||||
* @return the number of digits in fraction
|
||||
**********************************************************************/
|
||||
unsigned long Size() const throw() { return unsigned(_e); }
|
||||
/**
|
||||
* Add integer \e k to the MPRFRandom.
|
||||
*
|
||||
* @param[in] k the integer to add.
|
||||
**********************************************************************/
|
||||
void AddInteger(long k) {
|
||||
k += Floor(); // The new floor
|
||||
int ns = k < 0 ? -1 : 1; // The new sign
|
||||
if (ns != _s) { // If sign changes, set f = 1 - f
|
||||
mpz_set_ui(_tt, 1u);
|
||||
mpz_mul_2exp(_tt, _tt, _e << logbits_);
|
||||
mpz_sub_ui(_tt, _tt, 1u);
|
||||
mpz_sub(_f, _tt, _f);
|
||||
_s = ns;
|
||||
}
|
||||
_n = ns > 0 ? k : -(k + 1);
|
||||
}
|
||||
/**
|
||||
* Compare with another MPFRRandom, *this < \e t.
|
||||
*
|
||||
* @param[in,out] r a random generator.
|
||||
* @param[in,out] t a MPFRRandom to compare.
|
||||
* @return true if *this < \e t.
|
||||
**********************************************************************/
|
||||
int LessThan(gmp_randstate_t r, MPFRRandom& t) {
|
||||
if (this == &t) return false; // same object
|
||||
if (_s != t._s) return _s < t._s;
|
||||
if (_n != t._n) return (_s < 0) ^ (_n < t._n);
|
||||
for (mp_size_t k = 0; ; ++k) {
|
||||
mp_limb_t x = Digit(r, k);
|
||||
mp_limb_t y = t.Digit(r, k);
|
||||
if (x != y) return (_s < 0) ^ (x < y);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Set high bit of fraction to 1.
|
||||
*
|
||||
* @param[in,out] r a random generator.
|
||||
**********************************************************************/
|
||||
void SetHighBit(gmp_randstate_t r) { // Set the msb to 1
|
||||
ExpandTo(r, 0); // Generate msb if necessary
|
||||
mpz_setbit(_f, (_e << logbits_) - 1);
|
||||
}
|
||||
/**
|
||||
* Test high bit of fraction.
|
||||
*
|
||||
* @param[in,out] r a random generator.
|
||||
**********************************************************************/
|
||||
int TestHighBit(gmp_randstate_t r) { // test the msb of f
|
||||
ExpandTo(r, 0); // Generate msb if necessary
|
||||
return mpz_tstbit(_f, (_e << logbits_) - 1);
|
||||
}
|
||||
/**
|
||||
* Return the position of the most significant bit in the MPFRRandom.
|
||||
*
|
||||
* @param[in,out] r a random generator.
|
||||
*
|
||||
* The bit position is numbered such the 1/2 bit is 0, the 1/4 bit is -1,
|
||||
* etc.
|
||||
**********************************************************************/
|
||||
mp_size_t LeadingBit(gmp_randstate_t r) {
|
||||
if (_n) return highest_bit_idx(_n);
|
||||
while (true) {
|
||||
int sgn = mpz_sgn(_f);
|
||||
if (sgn != 0)
|
||||
return mp_size_t(mpz_sizeinbase(_f, 2)) - mp_size_t(_e << logbits_);
|
||||
AddDigits(r);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Ensure that the k'th digit of the fraction is computed.
|
||||
*
|
||||
* @param[in,out] r a random generator.
|
||||
* @param[in] k the digit number (0 is the most significant, 1 is the next
|
||||
* most significant, etc.
|
||||
**********************************************************************/
|
||||
void ExpandTo(gmp_randstate_t r, mp_size_t k)
|
||||
{ if (_e <= k) AddDigits(r, k - _e + 1); }
|
||||
/**
|
||||
* Convert to a MPFR number \e without adding more bits.
|
||||
*
|
||||
* @param[out] val the value of s * (n + *this).
|
||||
* @param[in] round the rounding direction.
|
||||
* @return the MPFR ternary result (± if val is larger/smaller than
|
||||
* the exact sample).
|
||||
*
|
||||
* If round is MPFR_RNDN, then the rounded midpoint of the interval
|
||||
* represented by the MPFRRandom is returned. Otherwise it is the rounded
|
||||
* lower or upper bound of the interval (whichever is appropriate).
|
||||
**********************************************************************/
|
||||
int operator()(mpfr_t val, mpfr_rnd_t round)
|
||||
{ return operator()(val, NULL, round); }
|
||||
/**
|
||||
* Convert to a MPFR number.
|
||||
*
|
||||
* @param[out] val the value of s * (n + *this).
|
||||
* @param[in,out] r a GMP random generator.
|
||||
* @param[in] round the rounding direction.
|
||||
* @return the MPFR ternary result (± if val is larger/smaller than
|
||||
* the exact sample).
|
||||
*
|
||||
* If \e r is NULL, then no additional random bits are generated and the
|
||||
* lower bound, midpoint, or upper bound of the MPFRRandom interval is
|
||||
* returned, depending on the value of \e round.
|
||||
**********************************************************************/
|
||||
int operator()(mpfr_t val, gmp_randstate_t r, mpfr_rnd_t round) {
|
||||
// The value is constructed as a positive quantity, so adjust rounding
|
||||
// mode to account for this.
|
||||
switch (round) {
|
||||
case MPFR_RNDD:
|
||||
case MPFR_RNDU:
|
||||
case MPFR_RNDN:
|
||||
break;
|
||||
case MPFR_RNDZ:
|
||||
round = _s < 0 ? MPFR_RNDU : MPFR_RNDD;
|
||||
break;
|
||||
case MPFR_RNDA:
|
||||
round = _s < 0 ? MPFR_RNDD : MPFR_RNDU;
|
||||
break;
|
||||
default:
|
||||
round = MPFR_RNDN; // New rounding modes are variants of N
|
||||
break;
|
||||
} // Now round is one of MPFR_RND{D,N,U}
|
||||
|
||||
mp_size_t excess;
|
||||
mpfr_exp_t expt;
|
||||
if (r == NULL) {
|
||||
// If r is NULL then all the bits currently generated are considered
|
||||
// significant. Thus no excess bits need to be squeezed out.
|
||||
excess = 0;
|
||||
// And the exponent shift in mpfr_set_z_2exp is just...
|
||||
expt = -(_e << logbits_);
|
||||
// However, if rounding to nearest, we need to make room for the
|
||||
// midpoint bit.
|
||||
if (round == MPFR_RNDN) {
|
||||
excess = -1;
|
||||
--expt;
|
||||
}
|
||||
} else { // r is non-NULL
|
||||
// Generate enough digits, i.e., enough to generate prec significant
|
||||
// figures for RNDD and RNDU; for RNDN we need to generate an
|
||||
// additional guard bit.
|
||||
mp_size_t lead = LeadingBit(r);
|
||||
mpfr_prec_t prec = mpfr_get_prec (val);
|
||||
mp_size_t trail = lead - prec; // position one past trailing bit
|
||||
mp_size_t guard = trail + (round == MPFR_RNDN ? 0 : 1); // guard bit pos
|
||||
// Generate the bits needed.
|
||||
if (guard <= 0) ExpandTo(r, (-guard) >> logbits_);
|
||||
// Unless bits = 1, the generation process will typically have
|
||||
// generated too many bits. We figure out how many, but leaving room
|
||||
// for one additional "inexact" bit. The inexact bit is set to 1 in
|
||||
// order to force MPFR to treat the result as inexact, to break RNDN
|
||||
// ties, and to get the ternary value set correctly.
|
||||
//
|
||||
// expt is the exponent used when forming the number using
|
||||
// mpfr_set_z_2exp. Without the inexact bit, it's (guard - 1).
|
||||
// Subtract 1 to account for the inexact bit.
|
||||
expt = guard - 2;
|
||||
// The number of excess bits is now the difference between the number
|
||||
// of bits in the fraction (e << logbits) and -expt. Note that this
|
||||
// may be -1 (meaning we'll need to shift the number left to
|
||||
// accommodate the inexact bit).
|
||||
excess = (_e << logbits_) + expt;
|
||||
}
|
||||
mpz_set_ui(_tt, _n); // The integer part
|
||||
mpz_mul_2exp(_tt, _tt, _e << logbits_); // Shift to allow for fraction
|
||||
mpz_add(_tt, _tt, _f); // Add fraction
|
||||
if (excess > 0)
|
||||
mpz_tdiv_q_2exp(_tt, _tt, excess);
|
||||
else if (excess < 0)
|
||||
mpz_mul_2exp(_tt, _tt, -excess);
|
||||
if (r || round == MPFR_RNDN)
|
||||
// Set the inexact bit (or compute the midpoint if r is NULL).
|
||||
mpz_setbit(_tt, 0);
|
||||
else if (round == MPFR_RNDU)
|
||||
// If r is NULL, compute the upper bound.
|
||||
mpz_add_ui(_tt, _tt, 1u);
|
||||
|
||||
// Convert to a mpfr number. If r is specified, then there are
|
||||
// sufficient bits in tt that the result is inexact and that (in the case
|
||||
// of RNDN) there are no ties.
|
||||
int flag = mpfr_set_z_2exp(val, _tt, expt, round);
|
||||
if (_s < 0) {
|
||||
mpfr_neg (val, val, MPFR_RNDN);
|
||||
flag = -flag;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
/**
|
||||
* A coin toss. (This should really be a static function. But it uses the
|
||||
* MPFRRandom temporary variable.)
|
||||
*
|
||||
* @param[in,out] r a GMP random generator.
|
||||
* @return true or false.
|
||||
**********************************************************************/
|
||||
int Boolean(gmp_randstate_t r) const {
|
||||
mpz_urandomb(_tt, r, 1);
|
||||
return mpz_tstbit(_tt, 0);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace RandomLib
|
||||
|
||||
#endif // HAVE_MPFR
|
||||
#endif // RANDOMLIB_MPFRRANDOM_HPP
|
@ -1,72 +0,0 @@
|
||||
/**
|
||||
* \file MPFRUniform.hpp
|
||||
* \brief Header for MPFRUniform
|
||||
*
|
||||
* Sampling exactly from a uniform distribution for MPFR.
|
||||
*
|
||||
* Copyright (c) Charles Karney (2012) <charles@karney.com> and licensed under
|
||||
* the MIT/X11 License. For more information, see
|
||||
* http://randomlib.sourceforge.net/
|
||||
**********************************************************************/
|
||||
|
||||
#if !defined(RANDOMLIB_MPFRUNIFORM_HPP)
|
||||
#define RANDOMLIB_MPFRUNIFORM_HPP 1
|
||||
|
||||
#include <RandomLib/MPFRRandom.hpp>
|
||||
|
||||
#if HAVE_MPFR || defined(DOXYGEN)
|
||||
|
||||
namespace RandomLib {
|
||||
|
||||
/**
|
||||
* \brief The uniform distribution for MPFR.
|
||||
*
|
||||
* This is just a thin layer on top of MPFRRandom to provide random numbers
|
||||
* uniformly distributed in [0,1].
|
||||
*
|
||||
* This class uses a mutable private object. So a single MPFRUniform object
|
||||
* cannot safely be used by multiple threads. In a multi-processing
|
||||
* environment, each thread should use a thread-specific MPFRUniform object.
|
||||
*
|
||||
* @tparam bits the number of bits in each digit.
|
||||
**********************************************************************/
|
||||
template<int bits = 32> class MPFRUniform {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Initialize the MPFRUniform object.
|
||||
**********************************************************************/
|
||||
MPFRUniform() {};
|
||||
/**
|
||||
* Sample from the uniform distribution in [0,1] returning a MPFRRandom.
|
||||
* This function takes an unused GMP random generator as a parameter, in
|
||||
* order to parallel the usage of MPFRExponential and MPFRNormal.
|
||||
*
|
||||
* @param[out] t the MPFRRandom result.
|
||||
* @param[in,out] r a GMP random generator (unused).
|
||||
**********************************************************************/
|
||||
void operator()(MPFRRandom<bits>& t, gmp_randstate_t r) const
|
||||
{ Compute(r); _x.swap(t); }
|
||||
/**
|
||||
* Sample from the uniform distribution in [0,1].
|
||||
*
|
||||
* @param[out] val the sample from the uniform distribution
|
||||
* @param[in,out] r a GMP random generator.
|
||||
* @param[in] round the rounding direction.
|
||||
* @return the MPFR ternary result (± if val is larger/smaller than
|
||||
* the exact sample).
|
||||
**********************************************************************/
|
||||
int operator()(mpfr_t val, gmp_randstate_t r, mpfr_rnd_t round) const
|
||||
{ Compute(r); return _x(val, r, round); }
|
||||
private:
|
||||
// disable copy constructor and assignment operator
|
||||
MPFRUniform(const MPFRUniform&);
|
||||
MPFRUniform& operator=(const MPFRUniform&);
|
||||
void Compute(gmp_randstate_t /* r */) const { _x. Init(); }
|
||||
mutable MPFRRandom<bits> _x;
|
||||
};
|
||||
|
||||
} // namespace RandomLib
|
||||
|
||||
#endif // HAVE_MPFR
|
||||
#endif // RANDOMLIB_MPFRUNIFORM_HPP
|
@ -1,114 +0,0 @@
|
||||
/**
|
||||
* \file NormalDistribution.hpp
|
||||
* \brief Header for NormalDistribution
|
||||
*
|
||||
* Compute normal deviates.
|
||||
*
|
||||
* Copyright (c) Charles Karney (2006-2011) <charles@karney.com> and licensed
|
||||
* under the MIT/X11 License. For more information, see
|
||||
* http://randomlib.sourceforge.net/
|
||||
**********************************************************************/
|
||||
|
||||
#if !defined(RANDOMLIB_NORMALDISTRIBUTION_HPP)
|
||||
#define RANDOMLIB_NORMALDISTRIBUTION_HPP 1
|
||||
|
||||
#include <cmath> // for std::log
|
||||
|
||||
namespace RandomLib {
|
||||
/**
|
||||
* \brief Normal deviates
|
||||
*
|
||||
* Sample from the normal distribution.
|
||||
*
|
||||
* This uses the ratio method; see Knuth, TAOCP, Vol 2, Sec. 3.4.1.C,
|
||||
* Algorithm R. Unlike the Box-Muller method which generates two normal
|
||||
* deviates at a time, this method generates just one. This means that this
|
||||
* class has no state that needs to be saved when checkpointing a
|
||||
* calculation. Original citation is\n A. J. Kinderman, J. F. Monahan,\n
|
||||
* Computer Generation of Random Variables Using the Ratio of Uniform
|
||||
* Deviates,\n ACM TOMS 3, 257--260 (1977).
|
||||
*
|
||||
* Improved "quadratic" bounds are given by\n J. L. Leva,\n A Fast Normal
|
||||
* Random Number Generator,\n ACM TOMS 18, 449--453 and 454--455
|
||||
* (1992).
|
||||
*
|
||||
* The log is evaluated 1.369 times per normal deviate with no bounds, 0.232
|
||||
* times with Knuth's bounds, and 0.012 times with the quadratic bounds.
|
||||
* Time is approx 0.3 us per deviate (1GHz machine, optimized, RealType =
|
||||
* float).
|
||||
*
|
||||
* Example
|
||||
* \code
|
||||
* #include <RandomLib/NormalDistribution.hpp>
|
||||
*
|
||||
* RandomLib::Random r;
|
||||
* std::cout << "Seed set to " << r.SeedString() << "\n";
|
||||
* RandomLib::NormalDistribution<double> normdist;
|
||||
* std::cout << "Select from normal distribution:";
|
||||
* for (size_t i = 0; i < 10; ++i)
|
||||
* std::cout << " " << normdist(r);
|
||||
* std::cout << "\n";
|
||||
* \endcode
|
||||
*
|
||||
* @tparam RealType the real type of the results (default double).
|
||||
**********************************************************************/
|
||||
template<typename RealType = double> class NormalDistribution {
|
||||
public:
|
||||
/**
|
||||
* The type returned by NormalDistribution::operator()(Random&)
|
||||
**********************************************************************/
|
||||
typedef RealType result_type;
|
||||
/**
|
||||
* Return a sample of type RealType from the normal distribution with mean
|
||||
* μ and standard deviation σ.
|
||||
*
|
||||
* For μ = 0 and σ = 1 (the defaults), the distribution is
|
||||
* symmetric about zero and is nonzero. The maximum result is less than 2
|
||||
* sqrt(log(2) \e p) where \e p is the precision of real type RealType.
|
||||
* The minimum positive value is approximately 1/2<sup><i>p</i>+1</sup>.
|
||||
* Here \e p is the precision of real type RealType.
|
||||
*
|
||||
* @tparam Random the type of RandomCanonical generator.
|
||||
* @param[in,out] r the RandomCanonical generator.
|
||||
* @param[in] mu the mean value of the normal distribution (default 0).
|
||||
* @param[in] sigma the standard deviation of the normal distribution
|
||||
* (default 1).
|
||||
* @return the random sample.
|
||||
**********************************************************************/
|
||||
template<class Random>
|
||||
RealType operator()(Random& r, RealType mu = RealType(0),
|
||||
RealType sigma = RealType(1)) const throw();
|
||||
};
|
||||
|
||||
template<typename RealType> template<class Random> inline RealType
|
||||
NormalDistribution<RealType>::operator()(Random& r, RealType mu,
|
||||
RealType sigma) const throw() {
|
||||
// N.B. These constants can be regarded as "exact", so that the same number
|
||||
// of significant figures are used in all versions. (They serve to
|
||||
// "bracket" the real boundary specified by the log expression.)
|
||||
const RealType
|
||||
m = RealType( 1.7156 ), // sqrt(8/e) (rounded up)
|
||||
s = RealType( 0.449871), // Constants from Leva
|
||||
t = RealType(-0.386595),
|
||||
a = RealType( 0.19600 ),
|
||||
b = RealType( 0.25472 ),
|
||||
r1 = RealType( 0.27597 ),
|
||||
r2 = RealType( 0.27846 );
|
||||
RealType u, v, Q;
|
||||
do { // This loop is executed 1.369 times on average
|
||||
// Pick point P = (u, v)
|
||||
u = r.template FixedU<RealType>(); // Sample u in (0,1]
|
||||
v = m * r.template FixedS<RealType>(); // Sample v in (-m/2, m/2); avoid 0
|
||||
// Compute quadratic form Q
|
||||
const RealType x = u - s;
|
||||
const RealType y = (v < 0 ? -v : v) - t; // Sun has no long double abs!
|
||||
Q = x*x + y * (a*y - b*x);
|
||||
} while ( Q >= r1 && // accept P if Q < r1
|
||||
( Q > r2 || // reject P if Q > r2
|
||||
v*v > - 4 * u*u * std::log(u) ) ); // accept P if v^2 <= ...
|
||||
return mu + sigma * (v / u); // return the slope of P (note u != 0)
|
||||
}
|
||||
|
||||
} // namespace RandomLib
|
||||
|
||||
#endif // RANDOMLIB_NORMALDISTRIBUTION_HPP
|
@ -1,141 +0,0 @@
|
||||
/**
|
||||
* \file Random.hpp
|
||||
* \brief Header for Random, RandomGenerator.
|
||||
*
|
||||
* This loads up the header for RandomCanonical, RandomEngine, etc., to
|
||||
* provide access to random integers of various sizes, random reals with
|
||||
* various precisions, a random probability, etc.
|
||||
*
|
||||
* Copyright (c) Charles Karney (2006-2011) <charles@karney.com> and licensed
|
||||
* under the MIT/X11 License. For more information, see
|
||||
* http://randomlib.sourceforge.net/
|
||||
**********************************************************************/
|
||||
|
||||
#if !defined(RANDOMLIB_RANDOM_HPP)
|
||||
#define RANDOMLIB_RANDOM_HPP 1
|
||||
|
||||
#include <RandomLib/Config.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
typedef unsigned uint32_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Use table, Power2::power2, for pow2? This isn't necessary with g++ 4.0
|
||||
* because calls to std::pow are optimized. g++ 4.1 seems to have lost this
|
||||
* capability though! And it's back in g++ 4.4. So, for simplicity, assume
|
||||
* that all "current" versions of g++ perform the optimization.
|
||||
**********************************************************************/
|
||||
#if !defined(RANDOMLIB_POWERTABLE)
|
||||
#if defined(__GNUC__)
|
||||
#define RANDOMLIB_POWERTABLE 0
|
||||
#else
|
||||
// otherwise use a lookup table
|
||||
#define RANDOMLIB_POWERTABLE 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !HAVE_LONG_DOUBLE || defined(_MSC_VER)
|
||||
#define RANDOMLIB_LONGDOUBLEPREC 53
|
||||
#elif defined(__sparc)
|
||||
#define RANDOMLIB_LONGDOUBLEPREC 113
|
||||
#else
|
||||
/**
|
||||
* The precision of long doubles, used for sizing Power2::power2. 64 on
|
||||
* Linux/Intel, 106 on MaxOS/PowerPC
|
||||
**********************************************************************/
|
||||
#define RANDOMLIB_LONGDOUBLEPREC __LDBL_MANT_DIG__
|
||||
#endif
|
||||
|
||||
/**
|
||||
* A compile-time assert. Use C++11 static_assert, if available.
|
||||
**********************************************************************/
|
||||
#if !defined(STATIC_ASSERT)
|
||||
# if __cplusplus >= 201103
|
||||
# define STATIC_ASSERT static_assert
|
||||
# elif defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# define STATIC_ASSERT static_assert
|
||||
# elif defined(_MSC_VER) && _MSC_VER >= 1600
|
||||
# define STATIC_ASSERT static_assert
|
||||
# else
|
||||
# define STATIC_ASSERT(cond,reason) \
|
||||
{ enum{ STATIC_ASSERT_ENUM = 1/int(cond) }; }
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Are denormalized reals of type RealType supported?
|
||||
**********************************************************************/
|
||||
#define RANDOMLIB_HASDENORM(RealType) 1
|
||||
|
||||
#if defined(_MSC_VER) && defined(RANDOMLIB_SHARED_LIB) && RANDOMLIB_SHARED_LIB
|
||||
# if RANDOMLIB_SHARED_LIB > 1
|
||||
# error RANDOMLIB_SHARED_LIB must be 0 or 1
|
||||
# elif defined(RandomLib_EXPORTS)
|
||||
# define RANDOMLIB_EXPORT __declspec(dllexport)
|
||||
# else
|
||||
# define RANDOMLIB_EXPORT __declspec(dllimport)
|
||||
# endif
|
||||
#else
|
||||
# define RANDOMLIB_EXPORT
|
||||
#endif
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
/**
|
||||
* \brief Namespace for %RandomLib
|
||||
*
|
||||
* All of %RandomLib is defined within the RandomLib namespace. In addtiion
|
||||
* all the header files are included via %RandomLib/filename. This minimizes
|
||||
* the likelihood of conflicts with other packages.
|
||||
**********************************************************************/
|
||||
namespace RandomLib {
|
||||
|
||||
/**
|
||||
* \brief Exception handling for %RandomLib
|
||||
*
|
||||
* A class to handle exceptions. It's derived from std::runtime_error so it
|
||||
* can be caught by the usual catch clauses.
|
||||
**********************************************************************/
|
||||
class RandomErr : public std::runtime_error {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param[in] msg a string message, which is accessible in the catch
|
||||
* clause, via what().
|
||||
**********************************************************************/
|
||||
RandomErr(const std::string& msg) : std::runtime_error(msg) {}
|
||||
};
|
||||
|
||||
} // namespace RandomLib
|
||||
|
||||
#include <RandomLib/RandomCanonical.hpp>
|
||||
|
||||
#if !defined(RANDOMLIB_BUILDING_LIBRARY)
|
||||
|
||||
namespace RandomLib {
|
||||
|
||||
#if !defined(RANDOMLIB_DEFAULT_GENERATOR)
|
||||
#define RANDOMLIB_DEFAULT_GENERATOR SRandomGenerator32
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Point Random to one of a specific MT19937 generators.
|
||||
**********************************************************************/
|
||||
typedef RANDOMLIB_DEFAULT_GENERATOR RandomGenerator;
|
||||
|
||||
/**
|
||||
* Hook Random to RandomGenerator
|
||||
**********************************************************************/
|
||||
typedef RandomCanonical<RandomGenerator> Random;
|
||||
|
||||
} // namespace RandomLib
|
||||
|
||||
#endif // !defined(RANDOMLIB_BUILDING_LIBRARY)
|
||||
|
||||
#endif // RANDOMLIB_RANDOM_HPP
|
@ -1,384 +0,0 @@
|
||||
/**
|
||||
* \file RandomAlgorithm.hpp
|
||||
* \brief Header for MT19937 and SFMT19937.
|
||||
*
|
||||
* This provides an interface to the Mersenne Twister
|
||||
* <a href="http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html">
|
||||
* MT19937</a> and SIMD oriented Fast Mersenne Twister
|
||||
* <a href="http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html">
|
||||
* SFMT19937</a> random number engines.
|
||||
*
|
||||
* Interface routines written by Charles Karney <charles@karney.com> and
|
||||
* licensed under the MIT/X11 License. For more information, see
|
||||
* http://randomlib.sourceforge.net/
|
||||
**********************************************************************/
|
||||
|
||||
#if !defined(RANDOMLIB_RANDOMALGORITHM_HPP)
|
||||
#define RANDOMLIB_RANDOMALGORITHM_HPP 1
|
||||
|
||||
#include <RandomLib/RandomType.hpp>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#if defined(HAVE_SSE2) && HAVE_SSE2
|
||||
#include <emmintrin.h>
|
||||
#endif
|
||||
|
||||
#if (defined(HAVE_SSE2) && HAVE_SSE2) && (defined(HAVE_ALTIVEC) && HAVE_ALTIVEC)
|
||||
#error "HAVE_SSE2 and HAVE_ALTIVEC should not both be defined"
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
// Squelch warnings about casts truncating constants
|
||||
# pragma warning (push)
|
||||
# pragma warning (disable: 4310)
|
||||
#endif
|
||||
|
||||
namespace RandomLib {
|
||||
|
||||
/**
|
||||
* \brief The %MT19937 random number engine.
|
||||
*
|
||||
* This provides an interface to Mersenne Twister random number engine,
|
||||
* <a href="http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html">
|
||||
* MT19937</a>. See\n Makoto Matsumoto and Takuji Nishimura,\n Mersenne
|
||||
* Twister: A 623-Dimensionally Equidistributed Uniform Pseudo-Random Number
|
||||
* Generator,\n ACM TOMACS 8, 3--30 (1998)
|
||||
*
|
||||
* This is adapted from the 32-bit and 64-bit C versions available at
|
||||
* http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html and
|
||||
* http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt64.html
|
||||
*
|
||||
* The template argument give the type \e RandomType of the "natural" result.
|
||||
* This incorporates the bit width and the C++ type of the result. Although
|
||||
* the two versions of MT19937 produce different sequences, the
|
||||
* implementations here are portable across 32-bit and 64-bit architectures.
|
||||
*
|
||||
* The class chiefly supplies the method for advancing the state by
|
||||
* Transition.
|
||||
*
|
||||
* @tparam RandomType the type of the results, either Random_u32 or
|
||||
* Random_u64.
|
||||
*
|
||||
* Interface routines written by Charles Karney <charles@karney.com> and
|
||||
* licensed under the MIT/X11 License. For more information, see
|
||||
* http://randomlib.sourceforge.net/
|
||||
**********************************************************************/
|
||||
template<class RandomType> class RANDOMLIB_EXPORT MT19937 {
|
||||
public:
|
||||
/**
|
||||
* The result RandomType
|
||||
**********************************************************************/
|
||||
typedef RandomType engine_t;
|
||||
/**
|
||||
* The internal numeric type for MT19337::Transition
|
||||
**********************************************************************/
|
||||
typedef typename engine_t::type internal_type;
|
||||
private:
|
||||
/**
|
||||
* The unsigned type of engine_t
|
||||
**********************************************************************/
|
||||
typedef typename engine_t::type engine_type;
|
||||
/**
|
||||
* The width of the engine_t
|
||||
**********************************************************************/
|
||||
static const unsigned width = engine_t::width;
|
||||
enum {
|
||||
/**
|
||||
* The Mersenne prime is 2<sup><i>P</i></sup> − 1
|
||||
**********************************************************************/
|
||||
P = 19937,
|
||||
/**
|
||||
* The short lag for MT19937
|
||||
**********************************************************************/
|
||||
M = width == 32 ? 397 : 156,
|
||||
/**
|
||||
* The number of ignored bits in the first word of the state
|
||||
**********************************************************************/
|
||||
R = ((P + width - 1)/width) * width - P
|
||||
};
|
||||
static const engine_type mask = engine_t::mask;
|
||||
/**
|
||||
* Magic matrix for MT19937
|
||||
**********************************************************************/
|
||||
static const engine_type magic =
|
||||
width == 32 ? 0x9908b0dfULL : 0xb5026f5aa96619e9ULL;
|
||||
/**
|
||||
* Mask for top \e width − \e R bits of a word
|
||||
**********************************************************************/
|
||||
static const engine_type upper = mask << R & mask;
|
||||
/**
|
||||
* Mask for low \e R bits of a <i>width</i>-bit word
|
||||
**********************************************************************/
|
||||
static const engine_type lower = ~upper & mask;
|
||||
|
||||
public:
|
||||
/**
|
||||
* A version number "EnMT" or "EnMU" to ensure safety of Save/Load. This
|
||||
* needs to be unique across RandomAlgorithms.
|
||||
**********************************************************************/
|
||||
static const unsigned version = 0x456e4d54UL + (engine_t::width/32 - 1);
|
||||
enum {
|
||||
/**
|
||||
* The size of the state. This is the long lag for MT19937.
|
||||
**********************************************************************/
|
||||
N = (P + width - 1)/width
|
||||
};
|
||||
/**
|
||||
* Advance state by \e count batches. For speed all \e N words of state
|
||||
* are advanced together. If \e count is negative, the state is stepped
|
||||
* backwards. This is the meat of the MT19937 engine.
|
||||
*
|
||||
* @param[in] count how many batches to advance.
|
||||
* @param[in,out] statev the internal state of the random number generator.
|
||||
**********************************************************************/
|
||||
static void Transition(long long count, internal_type statev[]) throw();
|
||||
|
||||
/**
|
||||
* Manipulate a word of the state prior to output.
|
||||
*
|
||||
* @param[in] y a word of the state.
|
||||
* @return the result.
|
||||
**********************************************************************/
|
||||
static engine_type Generate(engine_type y) throw();
|
||||
|
||||
/**
|
||||
* Convert an arbitrary state into a legal one. This consists of (a)
|
||||
* turning on one bit if the state is all zero and (b) making 31 bits of
|
||||
* the state consistent with the other 19937 bits.
|
||||
*
|
||||
* @param[in,out] state the state of the generator.
|
||||
**********************************************************************/
|
||||
static void NormalizeState(engine_type state[]) throw();
|
||||
|
||||
/**
|
||||
* Check that the state is legal, throwing an exception if it is not. At
|
||||
* the same time, accumulate a checksum of the state.
|
||||
*
|
||||
* @param[in] state the state of the generator.
|
||||
* @param[in,out] check an accumulated checksum.
|
||||
**********************************************************************/
|
||||
static void CheckState(const engine_type state[], Random_u32::type& check);
|
||||
|
||||
/**
|
||||
* Return the name of the engine
|
||||
*
|
||||
* @return the name.
|
||||
**********************************************************************/
|
||||
static std::string Name() throw() {
|
||||
return "MT19937<Random_u" + std::string(width == 32 ? "32" : "64") + ">";
|
||||
}
|
||||
};
|
||||
|
||||
/// \cond SKIP
|
||||
template<>
|
||||
inline Random_u32::type MT19937<Random_u32>::Generate(engine_type y) throw() {
|
||||
y ^= y >> 11;
|
||||
y ^= y << 7 & engine_type(0x9d2c5680UL);
|
||||
y ^= y << 15 & engine_type(0xefc60000UL);
|
||||
y ^= y >> 18;
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline Random_u64::type MT19937<Random_u64>::Generate(engine_type y) throw() {
|
||||
// Specific tempering instantiation for width = 64 given in
|
||||
// http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt64.html
|
||||
y ^= y >> 29 & engine_type(0x5555555555555555ULL);
|
||||
y ^= y << 17 & engine_type(0x71d67fffeda60000ULL);
|
||||
y ^= y << 37 & engine_type(0xfff7eee000000000ULL);
|
||||
y ^= y >> 43;
|
||||
|
||||
return y;
|
||||
}
|
||||
/// \endcond
|
||||
|
||||
/**
|
||||
* \brief The SFMT random number engine.
|
||||
*
|
||||
* This provides an implementation of the SIMD-oriented Fast Mersenne Twister
|
||||
* random number engine,
|
||||
* <a href="http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html">
|
||||
* SFMT</a>. See\n Mutsuo Saito,\n An Application of Finite Field: Design
|
||||
* and Implementation of 128-bit Instruction-Based Fast Pseudorandom Number
|
||||
* Generator,\n Master's Thesis, Dept. of Math., Hiroshima University
|
||||
* (Feb. 2007).\n
|
||||
* http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/M062821.pdf
|
||||
* Mutsuo Saito and Makoto Matsumoto,\n
|
||||
* SIMD-oriented Fast Mersenne Twister: a 128-bit Pseudorandom Number
|
||||
* Generator,\n accepted in the proceedings of MCQMC2006\n
|
||||
* http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/ARTICLES/sfmt.pdf
|
||||
*
|
||||
* The template argument gives the type \e RandomType of the "natural"
|
||||
* result. This incorporates the bit width and the C++ type of the result.
|
||||
* The 32-bit and 64-bit versions of SFMT19937 produce the same sequences and
|
||||
* the differing only in whether how the state is represented. The
|
||||
* implementation includes a version using 128-bit SSE2 instructions. On
|
||||
* machines without these instructions, portable implementations using
|
||||
* traditional operations are provided. With the same starting seed,
|
||||
* SRandom32::Ran64() and SRandom64::Ran64() produces the same sequences.
|
||||
* Similarly SRandom64::Ran32() produces every other member of the sequence
|
||||
* produced by SRandom32::Ran32().
|
||||
*
|
||||
* The class chiefly supplies the method for advancing the state by
|
||||
* Transition.
|
||||
*
|
||||
* @tparam RandomType the type of the results, either Random_u32 or
|
||||
* Random_u64.
|
||||
*
|
||||
* Written by Charles Karney <charles@karney.com> and licensed under the
|
||||
* MIT/X11 License. For more information, see
|
||||
* http://randomlib.sourceforge.net/
|
||||
**********************************************************************/
|
||||
template<class RandomType> class RANDOMLIB_EXPORT SFMT19937 {
|
||||
public:
|
||||
/**
|
||||
* The result RandomType
|
||||
**********************************************************************/
|
||||
typedef RandomType engine_t;
|
||||
#if defined(HAVE_SSE2) && HAVE_SSE2
|
||||
typedef __m128i internal_type;
|
||||
#elif defined(HAVE_ALTIVEC) && HAVE_ALTIVEC
|
||||
typedef vector unsigned internal_type;
|
||||
#else
|
||||
/**
|
||||
* The internal numeric type for SFMT19337::Transition
|
||||
**********************************************************************/
|
||||
typedef typename engine_t::type internal_type;
|
||||
#endif
|
||||
private:
|
||||
/**
|
||||
* The unsigned type of engine_t
|
||||
**********************************************************************/
|
||||
typedef typename engine_t::type engine_type;
|
||||
/**
|
||||
* The width of the engine_t
|
||||
**********************************************************************/
|
||||
static const unsigned width = engine_t::width;
|
||||
enum {
|
||||
/**
|
||||
* The Mersenne prime is 2<sup><i>P</i></sup> − 1
|
||||
**********************************************************************/
|
||||
P = 19937,
|
||||
/**
|
||||
* The long lag for SFMT19937 in units of 128-bit words
|
||||
**********************************************************************/
|
||||
N128 = (P + 128 - 1)/128,
|
||||
/**
|
||||
* How many width words per 128-bit word.
|
||||
**********************************************************************/
|
||||
R = 128 / width,
|
||||
/**
|
||||
* The short lag for SFMT19937 in units of 128-bit words
|
||||
**********************************************************************/
|
||||
M128 = 122,
|
||||
/**
|
||||
* The short lag for SFMT19937
|
||||
**********************************************************************/
|
||||
M = M128 * R
|
||||
};
|
||||
#if (defined(HAVE_SSE2) && HAVE_SSE2) || (defined(HAVE_ALTIVEC) && HAVE_ALTIVEC)
|
||||
static const Random_u32::type magic0 = 0x1fffefUL;
|
||||
static const Random_u32::type magic1 = 0x1ecb7fUL;
|
||||
static const Random_u32::type magic2 = 0x1affffUL;
|
||||
static const Random_u32::type magic3 = 0x1ffff6UL;
|
||||
#else
|
||||
/**
|
||||
* Magic matrix for SFMT19937. Only the low 21 (= 32 − 11) bits need
|
||||
* to be set. (11 is the right shift applied to the words before masking.
|
||||
**********************************************************************/
|
||||
static const engine_type
|
||||
magic0 = width == 32 ? 0x1fffefULL : 0x1ecb7f001fffefULL;
|
||||
static const engine_type
|
||||
magic1 = width == 32 ? 0x1ecb7fULL : 0x1ffff6001affffULL;
|
||||
static const engine_type
|
||||
magic2 = width == 32 ? 0x1affffULL : 0ULL;
|
||||
static const engine_type
|
||||
magic3 = width == 32 ? 0x1ffff6ULL : 0ULL;
|
||||
#endif
|
||||
/**
|
||||
* Mask for simulating u32 << 18 with 64-bit words
|
||||
**********************************************************************/
|
||||
static const engine_type mask18 = engine_type(0xfffc0000fffc0000ULL);
|
||||
/**
|
||||
* Magic constants needed by "period certification"
|
||||
**********************************************************************/
|
||||
static const engine_type PARITY0 = 1U;
|
||||
static const engine_type PARITY1 = width == 32 ? 0U : 0x13c9e68400000000ULL;
|
||||
static const engine_type PARITY2 = 0U;
|
||||
static const engine_type PARITY3 = width == 32 ? 0x13c9e684UL : 0U;
|
||||
/**
|
||||
* Least significant bit of PARITY
|
||||
**********************************************************************/
|
||||
static const unsigned PARITY_LSB = 0;
|
||||
static const engine_type mask = engine_t::mask;
|
||||
|
||||
public:
|
||||
/**
|
||||
* A version number "EnSM" or "EnSN" to ensure safety of Save/Load. This
|
||||
* needs to be unique across RandomAlgorithms.
|
||||
**********************************************************************/
|
||||
static const unsigned version = 0x456e534dUL + (engine_t::width/32 - 1);
|
||||
enum {
|
||||
/**
|
||||
* The size of the state. The long lag for SFMT19937
|
||||
**********************************************************************/
|
||||
N = N128 * R
|
||||
};
|
||||
/**
|
||||
* Advance state by \e count batches. For speed all \e N words of state
|
||||
* are advanced together. If \e count is negative, the state is stepped
|
||||
* backwards. This is the meat of the SFMT19937 engine.
|
||||
*
|
||||
* @param[in] count how many batches to advance.
|
||||
* @param[in,out] statev the internal state of the random number generator.
|
||||
**********************************************************************/
|
||||
static void Transition(long long count, internal_type statev[])
|
||||
throw();
|
||||
|
||||
/**
|
||||
* Manipulate a word of the state prior to output. This is a no-op for
|
||||
* SFMT19937.
|
||||
*
|
||||
* @param[in] y a word of the state.
|
||||
* @return the result.
|
||||
**********************************************************************/
|
||||
static engine_type Generate(engine_type y) throw() { return y; }
|
||||
|
||||
/**
|
||||
* Convert an arbitrary state into a legal one. This consists a "period
|
||||
* certification to ensure that the period of the generator is at least
|
||||
* 2<sup><i>P</i></sup> − 1.
|
||||
*
|
||||
* @param[in,out] state the state of the generator.
|
||||
**********************************************************************/
|
||||
static void NormalizeState(engine_type state[]) throw();
|
||||
|
||||
/**
|
||||
* Check that the state is legal, throwing an exception if it is not. This
|
||||
* merely verifies that the state is not all zero. At the same time,
|
||||
* accumulate a checksum of the state.
|
||||
*
|
||||
* @param[in] state the state of the generator.
|
||||
* @param[in,out] check an accumulated checksum.
|
||||
**********************************************************************/
|
||||
static void CheckState(const engine_type state[], Random_u32::type& check);
|
||||
|
||||
/**
|
||||
* Return the name of the engine
|
||||
*
|
||||
* @return the name.
|
||||
**********************************************************************/
|
||||
static std::string Name() throw() {
|
||||
return "SFMT19937<Random_u" +
|
||||
std::string(width == 32 ? "32" : "64") + ">";
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace RandomLib
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning (pop)
|
||||
#endif
|
||||
|
||||
#endif // RANDOMLIB_RANDOMALGORITHM_HPP
|
File diff suppressed because it is too large
Load Diff
@ -1,640 +0,0 @@
|
||||
/**
|
||||
* \file RandomEngine.hpp
|
||||
* \brief Header for RandomEngine.
|
||||
*
|
||||
* Copyright (c) Charles Karney (2006-2012) <charles@karney.com> and licensed
|
||||
* under the MIT/X11 License. For more information, see
|
||||
* http://randomlib.sourceforge.net/
|
||||
**********************************************************************/
|
||||
|
||||
#if !defined(RANDOMLIB_RANDOMENGINE_HPP)
|
||||
#define RANDOMLIB_RANDOMENGINE_HPP 1
|
||||
|
||||
#include <RandomLib/RandomSeed.hpp>
|
||||
#include <RandomLib/RandomAlgorithm.hpp>
|
||||
#include <RandomLib/RandomMixer.hpp>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#if defined(HAVE_SSE2) && HAVE_SSE2 && defined(_MSC_VER) && !defined(_WIN64)
|
||||
#include <new>
|
||||
#endif
|
||||
|
||||
#if !defined(RANDOMLIB_BUILDING_LIBRARY) && \
|
||||
defined(HAVE_BOOST_SERIALIZATION) && HAVE_BOOST_SERIALIZATION
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <boost/serialization/split_member.hpp>
|
||||
#include <boost/serialization/vector.hpp>
|
||||
#endif
|
||||
|
||||
namespace RandomLib {
|
||||
/**
|
||||
* \brief Uniform random number generator.
|
||||
*
|
||||
* This implements a generic random number generator. Such a generator
|
||||
* requires two data holders RandomSeed, to hold the seed, and RandomEngine,
|
||||
* to hold the state. In addition we need two piece of machinery, a "Mixer"
|
||||
* to convert the seed into an initial state and an "Algorithm" to advance the
|
||||
* state.
|
||||
*
|
||||
* @tparam Algorithm the random number algorithm.
|
||||
* @tparam Mixer the way seeds are turned into state.
|
||||
*
|
||||
* RandomSeed is responsible for setting and reporting the seed.
|
||||
*
|
||||
* Mixer has no state and implements only static methods. It needs to have
|
||||
* the following public interface
|
||||
* - typedef mixer_t: a RandomType giving the output type
|
||||
* - unsigned version: an identifying version number
|
||||
* - static std::string Name(): an identifying name for the mixer
|
||||
* - static method SeedToState: converts a seed into n words of state.
|
||||
*
|
||||
* Algorithm has no state and implements only static methods. It needs to
|
||||
* have the following public interface
|
||||
* - typedef engine_t: a RandomType giving the output type
|
||||
* - typedef internal_type: a integer type used by Transition. This is
|
||||
* usually the same as engine_t::type. However it allows the use of
|
||||
* vector instructions on some platforms. We require that engine_t::type
|
||||
* and internal_type line up properly in a union so that there is no need
|
||||
* to convert the data explicitly between internal_type and
|
||||
* engine_t::type.
|
||||
* - unsigned version: an identifying version number
|
||||
* - static std::string Name(): an identifying name for the mixer
|
||||
* - enum N: the size of the state in units of engine_t.
|
||||
* - static method Transition: steps the generator forwards or backwards.
|
||||
* - static method Generate: tempers the state immediately prior to output
|
||||
* - static method NormalizeState: force the initial state (the result of
|
||||
* the Mixer) into a legal state.
|
||||
* - static method CheckState accumulates the checksum for the state into
|
||||
* check. In addition it throws an exception if the state is bad.
|
||||
*
|
||||
* RandomEngine is the glue that holds everything together. It repacks
|
||||
* the mixer_t data from Mixer into engine_t if necessary. It deals with
|
||||
* delivering individual random results, stepping the state forwards and
|
||||
* backwards, leapfrogging the generator, I/O of the generator, etc.
|
||||
*
|
||||
* Written by Charles Karney <charles@karney.com> and licensed under the
|
||||
* MIT/X11 License. For more information, see
|
||||
* http://randomlib.sourceforge.net/
|
||||
**********************************************************************/
|
||||
template<class Algorithm, class Mixer>
|
||||
class RANDOMLIB_EXPORT RandomEngine : public RandomSeed {
|
||||
private:
|
||||
/**
|
||||
* The result RandomType (carried over from the \e Algorithm).
|
||||
**********************************************************************/
|
||||
typedef typename Algorithm::engine_t result_t;
|
||||
/**
|
||||
* The RandomType used by the \e Mixer.
|
||||
**********************************************************************/
|
||||
typedef typename Mixer::mixer_t mixer_t;
|
||||
/**
|
||||
* The internal_type used by the Algorithm::Transition().
|
||||
**********************************************************************/
|
||||
typedef typename Algorithm::internal_type engine_type;
|
||||
public:
|
||||
/**
|
||||
* The number of random bits produced by Ran().
|
||||
**********************************************************************/
|
||||
enum {
|
||||
width = result_t::width
|
||||
};
|
||||
|
||||
/**
|
||||
* A type large enough to hold \e width bits. This is used for the
|
||||
* internal state of the generator and the result returned by Ran().
|
||||
**********************************************************************/
|
||||
typedef typename result_t::type result_type;
|
||||
|
||||
/**
|
||||
* The minimum result returned by Ran() = 0.
|
||||
**********************************************************************/
|
||||
static const result_type min = result_t::min;
|
||||
|
||||
/**
|
||||
* The maximum result returned by Ran() = 2<sup><i>w</i></sup> − 1.
|
||||
**********************************************************************/
|
||||
static const result_type max = result_t::max;
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* The mask for the result_t.
|
||||
**********************************************************************/
|
||||
static const result_type mask = result_t::mask;
|
||||
|
||||
private:
|
||||
/**
|
||||
* A version number "RandLib0" to ensure safety of Save/Load. The first 7
|
||||
* bytes can be regarded as a "signature" and the 8th byte a version
|
||||
* number.
|
||||
**********************************************************************/
|
||||
static const u64::type version = 0x52616e644c696230ULL; // 'RandLib0'
|
||||
/**
|
||||
* Marker for uninitialized object
|
||||
**********************************************************************/
|
||||
static const unsigned UNINIT = 0xffffffffU;
|
||||
enum {
|
||||
/**
|
||||
* The size of the state in units of result_type
|
||||
**********************************************************************/
|
||||
N = Algorithm::N,
|
||||
/**
|
||||
* The size of the state in units of mixer_t::type
|
||||
**********************************************************************/
|
||||
NU = (N * width + mixer_t::width - 1) / mixer_t::width,
|
||||
/**
|
||||
* The size of the state in units of engine_type.
|
||||
**********************************************************************/
|
||||
NV = N * sizeof(result_type) / sizeof(engine_type)
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Union for the state.
|
||||
*
|
||||
* A union to hold the state in the result_type, mixer_t::type, and
|
||||
* engine_type representations.
|
||||
**********************************************************************/
|
||||
union {
|
||||
/**
|
||||
* the result_type representation returned by Ran()
|
||||
**********************************************************************/
|
||||
result_type _state[N];
|
||||
/**
|
||||
* the mixer_t::type representation returned by Mixer::SeedToState.
|
||||
**********************************************************************/
|
||||
typename mixer_t::type _stateu[NU];
|
||||
/**
|
||||
* the engine_type representation returned by Algorithm::Transition.
|
||||
**********************************************************************/
|
||||
engine_type _statev[NV];
|
||||
};
|
||||
|
||||
/**
|
||||
* The index for the next random value
|
||||
**********************************************************************/
|
||||
unsigned _ptr;
|
||||
/**
|
||||
* How many times has Transition() been called
|
||||
**********************************************************************/
|
||||
long long _rounds;
|
||||
/**
|
||||
* Stride for leapfrogging
|
||||
**********************************************************************/
|
||||
unsigned _stride;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* \name Constructors
|
||||
**********************************************************************/
|
||||
///@{
|
||||
/**
|
||||
* Initialize from a vector. Only the low \e 32 bits of each element are
|
||||
* used.
|
||||
*
|
||||
* @tparam IntType the integral type of the elements of the vector.
|
||||
* @param[in] v the vector of elements.
|
||||
**********************************************************************/
|
||||
template<typename IntType>
|
||||
explicit RandomEngine(const std::vector<IntType>& v) { Reseed(v); }
|
||||
/**
|
||||
* Initialize from a pair of iterators setting seed to [\e a, \e b). The
|
||||
* iterator must produce results which can be converted into seed_type.
|
||||
* Only the low \e 32 bits of each element are used.
|
||||
*
|
||||
* @tparam InputIterator the type of the iterator.
|
||||
* @param[in] a the beginning iterator.
|
||||
* @param[in] b the ending iterator.
|
||||
**********************************************************************/
|
||||
template<typename InputIterator>
|
||||
RandomEngine(InputIterator a, InputIterator b) { Reseed(a, b); }
|
||||
/**
|
||||
* Initialize with seed [\e n]. Only the low \e width bits of \e n are
|
||||
* used.
|
||||
*
|
||||
* @param[in] n the new seed to use.
|
||||
**********************************************************************/
|
||||
explicit RandomEngine(seed_type n) { Reseed(n); }
|
||||
/**
|
||||
* Initialize with seed []. This can be followed by a call to Reseed() to
|
||||
* select a unique seed.
|
||||
**********************************************************************/
|
||||
RandomEngine() { unsigned long s[1]; Reseed(s, s); }
|
||||
/**
|
||||
* Initialize from a string. See Reseed(const std::string& s)
|
||||
*
|
||||
* @param[in] s the string to be decoded into a seed.
|
||||
**********************************************************************/
|
||||
explicit RandomEngine(const std::string& s) { Reseed(s); }
|
||||
|
||||
///@}
|
||||
|
||||
/**
|
||||
* \name Functions for returning random data
|
||||
**********************************************************************/
|
||||
///@{
|
||||
/**
|
||||
* Return \e width bits of randomness. This is the natural unit of random
|
||||
* data produced random number generator.
|
||||
*
|
||||
* @return the next random number of width \e width.
|
||||
**********************************************************************/
|
||||
result_type Ran() throw() {
|
||||
if (_ptr >= N)
|
||||
Next();
|
||||
result_type y = _state[_ptr];
|
||||
_ptr += _stride;
|
||||
|
||||
return Algorithm::Generate(y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return 32 bits of randomness.
|
||||
*
|
||||
* @return a 32-bit random number.
|
||||
**********************************************************************/
|
||||
u32::type Ran32() throw() {
|
||||
// return width > 32 ? u32::cast(Ran()) : Ran();
|
||||
return u32::cast(Ran());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return 64 bits of randomness.
|
||||
*
|
||||
* @return a 64-bit random number.
|
||||
**********************************************************************/
|
||||
u64::type Ran64() throw() {
|
||||
const u64::type x = Ran();
|
||||
return width > 32 ? x : u64::cast(Ran()) << (64 - width) | x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return \e width bits of randomness. Result is in [0,
|
||||
* 2<sup><i>w</i></sup>). (This just calls Ran().)
|
||||
*
|
||||
* @return the next random number of width \e width.
|
||||
**********************************************************************/
|
||||
result_type operator()() throw() { return Ran(); }
|
||||
///@}
|
||||
|
||||
#if defined(HAVE_SSE2) && HAVE_SSE2 && defined(_MSC_VER) && !defined(_WIN64)
|
||||
/**
|
||||
* new operator with alignment (needed for Visual Studio)
|
||||
**********************************************************************/
|
||||
void* operator new(size_t n) {
|
||||
void* p = _aligned_malloc(n, __alignof(RandomEngine));
|
||||
if (p == 0) throw std::bad_alloc();
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* delete operator with alignment (needed for Visual Studio)
|
||||
**********************************************************************/
|
||||
void operator delete(void* p) { _aligned_free(p); }
|
||||
|
||||
/**
|
||||
* new[] operator with alignment (needed for Visual Studio)
|
||||
**********************************************************************/
|
||||
void* operator new[](size_t n) {
|
||||
void* p = _aligned_malloc(n, __alignof(RandomEngine));
|
||||
if (p == 0) throw std::bad_alloc();
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* delete[] operator with alignment (needed for Visual Studio)
|
||||
**********************************************************************/
|
||||
void operator delete[](void* p) { _aligned_free(p); }
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \name Comparing Random objects
|
||||
**********************************************************************/
|
||||
///@{
|
||||
/**
|
||||
* Test equality of two Random objects. This test that the seeds match and
|
||||
* that they have produced the same number of random numbers.
|
||||
*
|
||||
* @param[in] r the RandomEngine object to compare.
|
||||
* @return true if the RandomEngine objects produce the same results.
|
||||
**********************************************************************/
|
||||
bool operator==(const RandomEngine& r) const throw()
|
||||
// Ensure that the two Random objects behave the same way. Note however
|
||||
// that the internal states may still be different, e.g., the following all
|
||||
// result in Random objects which are == (with Count() == 0) but which all
|
||||
// have different internal states:
|
||||
//
|
||||
// Random r(0); _ptr == UNINIT
|
||||
// r.StepCount( 1); r.StepCount(-1); _ptr == 0, _rounds == 0
|
||||
// r.StepCount(-1); r.StepCount( 1); _ptr == N, _rounds == -1
|
||||
{ return Count() == r.Count() && _seed == r._seed &&
|
||||
_stride == r._stride; }
|
||||
/**
|
||||
* Test inequality of two Random objects. See Random::operator==
|
||||
*
|
||||
* @param[in] r the RandomEngine object to compare.
|
||||
* @return true if the RandomEngine objects produce different results.
|
||||
**********************************************************************/
|
||||
bool operator!=(const RandomEngine& r) const throw()
|
||||
{ return !operator==(r); }
|
||||
///@}
|
||||
|
||||
/**
|
||||
* \name Interchanging Random objects
|
||||
**********************************************************************/
|
||||
///@{
|
||||
/**
|
||||
* Swap with another Random object.
|
||||
*
|
||||
* @param[in,out] t the RandomEngine object to swap with.
|
||||
**********************************************************************/
|
||||
void swap(RandomEngine& t) throw() {
|
||||
_seed.swap(t._seed);
|
||||
std::swap(_ptr, t._ptr);
|
||||
std::swap(_stride, t._stride);
|
||||
std::swap(_rounds, t._rounds);
|
||||
std::swap_ranges(_state, _state + N, t._state);
|
||||
}
|
||||
///@}
|
||||
|
||||
/**
|
||||
* \name Writing to and reading from a stream
|
||||
**********************************************************************/
|
||||
///@{
|
||||
/**
|
||||
* Save the state of the Random object to an output stream. Format is a
|
||||
* sequence of unsigned 32-bit integers written either in decimal (\e bin
|
||||
* false, text format) or in network order with most significant byte first
|
||||
* (\e bin true, binary format). Data consists of:
|
||||
*
|
||||
* - RandomLib magic string + version (2 words)
|
||||
* - Algorithm version (1 word)
|
||||
* - Mixer version (1 word)
|
||||
* - _seed.size() (1 word)
|
||||
* - _seed data (_seed.size() words)
|
||||
* - _ptr (1 word)
|
||||
* - _stride (1 word)
|
||||
* - if _ptr != UNINIT, _rounds (2 words)
|
||||
* - if _ptr != UNINIT, _state (N words or 2 N words)
|
||||
* - checksum
|
||||
*
|
||||
* Shortest possible saved result consists of 8 words. This corresponds to
|
||||
* RandomSeed() = [] and Count() = 0.
|
||||
*
|
||||
* @param[in,out] os the output stream.
|
||||
* @param[in] bin if true (the default) save in binary mode.
|
||||
**********************************************************************/
|
||||
void Save(std::ostream& os, bool bin = true) const;
|
||||
/**
|
||||
* Restore the state of the Random object from an input stream. If \e bin,
|
||||
* read in binary, else use text format. See documentation of
|
||||
* RandomEngine::Save for the format. Include error checking on data to
|
||||
* make sure the input has not been corrupted. If an error occurs while
|
||||
* reading, the Random object is unchanged.
|
||||
*
|
||||
* @param[in,out] is the input stream.
|
||||
* @param[in] bin if true (the default) load in binary mode.
|
||||
* @exception RandomErr if the state read from \e is is illegal.
|
||||
**********************************************************************/
|
||||
void Load(std::istream& is, bool bin = true) {
|
||||
// Read state into temporary so as not to change object on error.
|
||||
RandomEngine t(is, bin);
|
||||
_seed.reserve(t._seed.size());
|
||||
*this = t;
|
||||
}
|
||||
///@}
|
||||
|
||||
/**
|
||||
* \name Basic I/O
|
||||
**********************************************************************/
|
||||
///@{
|
||||
/**
|
||||
* Write the state of a generator to stream \e os as text
|
||||
*
|
||||
* @param[in,out] os the output stream.
|
||||
* @param[in] r the RandomEngine object to be saved.
|
||||
**********************************************************************/
|
||||
friend std::ostream& operator<<(std::ostream& os, const RandomEngine& r) {
|
||||
r.Save(os, false);
|
||||
return os;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the state of a generator from stream \e is as text
|
||||
*
|
||||
* @param[in,out] is the output stream.
|
||||
* @param[in] r the RandomEngine object to be loaded.
|
||||
* @exception RandomErr if the state read from \e is is illegal.
|
||||
**********************************************************************/
|
||||
friend std::istream& operator>>(std::istream& is, RandomEngine& r) {
|
||||
r.Load(is, false);
|
||||
return is;
|
||||
}
|
||||
///@}
|
||||
|
||||
/**
|
||||
* \name Examining and advancing the Random generator
|
||||
**********************************************************************/
|
||||
///@{
|
||||
/**
|
||||
* Return the number of random numbers used. This needs to return a long
|
||||
* long result since it can reasonably exceed 2<sup>31</sup>. (On a 1GHz
|
||||
* machine, it takes about a minute to produce 2<sup>32</sup> random
|
||||
* numbers.) More precisely this is the (zero-based) index of the next
|
||||
* random number to be produced. (This distinction is important when
|
||||
* leapfrogging is in effect.)
|
||||
*
|
||||
* @return the count of random numbers used.
|
||||
**********************************************************************/
|
||||
long long Count() const throw()
|
||||
{ return _ptr == UNINIT ? 0 : _rounds * N + _ptr; }
|
||||
/**
|
||||
* Step the generator forwards or backwards so that the value returned
|
||||
* by Count() is \e n
|
||||
*
|
||||
* @param[in] n the new count.
|
||||
**********************************************************************/
|
||||
void SetCount(long long n) throw() { StepCount(n - Count()); }
|
||||
/**
|
||||
* Step the generator forward \e n steps. \e n can be negative.
|
||||
*
|
||||
* @param[in] n how much to step the generator forward.
|
||||
**********************************************************************/
|
||||
void StepCount(long long n) throw();
|
||||
/**
|
||||
* Resets the sequence. Equivalent to SetCount(0), but works by
|
||||
* reinitializing the Random object from its seed, rather than by stepping
|
||||
* the sequence backwards. In addition, this undoes leapfrogging.
|
||||
**********************************************************************/
|
||||
void Reset() throw() { _ptr = UNINIT; _stride = 1; }
|
||||
///@}
|
||||
|
||||
/**
|
||||
* \name Leapfrogging
|
||||
**********************************************************************/
|
||||
///@{
|
||||
/**
|
||||
* Set leapfrogging stride to a positive number \e n and increment Count()
|
||||
* by \e k < \e n. If the current Count() is \e i, then normally the next
|
||||
* 3 random numbers would have (zero-based) indices \e i, \e i + 1, \e i +
|
||||
* 2, and the new Count() is \e i + 2. However, after SetStride(\e n, \e
|
||||
* k) the next 3 random numbers have indices \e i + \e k, \e i + \e k + \e
|
||||
* n, \e i + \e k + 2\e n, and the new Count() is \e i + \e k + 3\e n.
|
||||
* With leapfrogging in effect, the time to produce raw random numbers is
|
||||
* roughly proportional to 1 + (\e n − 1)/3. Reseed(...) and Reset()
|
||||
* both reset the stride back to 1. See \ref parallel for a description of
|
||||
* how to use this facility.
|
||||
*
|
||||
* @param[in] n the stride (default 1).
|
||||
* @param[in] k the initial increment (default 0).
|
||||
* @exception RandomErr if \e n is 0 or too large or if \e k is not less
|
||||
* than \e n.
|
||||
**********************************************************************/
|
||||
void SetStride(unsigned n = 1, unsigned k = 0) {
|
||||
// Limit stride to UNINIT/2. This catches negative numbers that have
|
||||
// been cast into unsigned. In reality the stride should be no more than
|
||||
// 10-100.
|
||||
if (n == 0 || n > UNINIT/2)
|
||||
throw RandomErr("RandomEngine: Invalid stride");
|
||||
if (k >= n)
|
||||
throw RandomErr("RandomEngine: Invalid offset");
|
||||
_stride = n;
|
||||
StepCount(k);
|
||||
}
|
||||
/**
|
||||
* Return leapfrogging stride.
|
||||
*
|
||||
* @return the stride.
|
||||
**********************************************************************/
|
||||
unsigned GetStride() const throw() { return _stride; }
|
||||
///@}
|
||||
|
||||
/**
|
||||
* Tests basic engine.
|
||||
*
|
||||
* @exception RandomErr if any of the tests fail.
|
||||
**********************************************************************/
|
||||
static void SelfTest();
|
||||
|
||||
/**
|
||||
* Return the name of the generator. This incorporates the names of the \e
|
||||
* Algorithm and \e Mixer.
|
||||
*
|
||||
* @return the name of the generator.
|
||||
**********************************************************************/
|
||||
static std::string Name() {
|
||||
return "RandomEngine<" + Algorithm::Name() + "," + Mixer::Name() + ">";
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* Compute initial state from seed
|
||||
**********************************************************************/
|
||||
void Init() throw();
|
||||
/**
|
||||
* The interface to Transition used by Ran().
|
||||
**********************************************************************/
|
||||
void Next() throw() {
|
||||
if (_ptr == UNINIT)
|
||||
Init();
|
||||
_rounds += _ptr/N;
|
||||
Algorithm::Transition(_ptr/N, _statev);
|
||||
_ptr %= N;
|
||||
}
|
||||
|
||||
u32::type Check(u64::type v, u32::type e, u32::type m) const;
|
||||
|
||||
static result_type SelfTestResult(unsigned) throw() { return 0; }
|
||||
|
||||
/**
|
||||
* Read from an input stream. Potentially corrupts object. This private
|
||||
* constructor is used by RandomEngine::Load so that it can avoid
|
||||
* corrupting its state on bad input.
|
||||
**********************************************************************/
|
||||
explicit RandomEngine(std::istream& is, bool bin);
|
||||
|
||||
#if !defined(RANDOMLIB_BUILDING_LIBRARY) && \
|
||||
defined(HAVE_BOOST_SERIALIZATION) && HAVE_BOOST_SERIALIZATION
|
||||
friend class boost::serialization::access;
|
||||
/**
|
||||
* Save to a boost archive. Boost versioning isn't very robust. (It
|
||||
* allows a RandomGenerator32 to be read back in as a RandomGenerator64.
|
||||
* It doesn't interact well with templates.) So we do our own versioning
|
||||
* and supplement this with a checksum.
|
||||
**********************************************************************/
|
||||
template<class Archive> void save(Archive& ar, const unsigned int) const {
|
||||
u64::type _version = version;
|
||||
u32::type _eversion = Algorithm::version,
|
||||
_mversion = Mixer::version,
|
||||
_checksum = Check(_version, _eversion, _mversion);
|
||||
ar & boost::serialization::make_nvp("version" , _version )
|
||||
& boost::serialization::make_nvp("eversion", _eversion)
|
||||
& boost::serialization::make_nvp("mversion", _mversion)
|
||||
& boost::serialization::make_nvp("seed" , _seed )
|
||||
& boost::serialization::make_nvp("ptr" , _ptr )
|
||||
& boost::serialization::make_nvp("stride" , _stride );
|
||||
if (_ptr != UNINIT)
|
||||
ar & boost::serialization::make_nvp("rounds", _rounds )
|
||||
& boost::serialization::make_nvp("state" , _state );
|
||||
ar & boost::serialization::make_nvp("checksum", _checksum);
|
||||
}
|
||||
/**
|
||||
* Load from a boost archive. Do this safely so that the current object is
|
||||
* not corrupted if the archive is bogus.
|
||||
**********************************************************************/
|
||||
template<class Archive> void load(Archive& ar, const unsigned int) {
|
||||
u64::type _version;
|
||||
u32::type _eversion, _mversion, _checksum;
|
||||
ar & boost::serialization::make_nvp("version" , _version )
|
||||
& boost::serialization::make_nvp("eversion", _eversion )
|
||||
& boost::serialization::make_nvp("mversion", _mversion );
|
||||
RandomEngine<Algorithm, Mixer> t(std::vector<seed_type>(0));
|
||||
ar & boost::serialization::make_nvp("seed" , t._seed )
|
||||
& boost::serialization::make_nvp("ptr" , t._ptr )
|
||||
& boost::serialization::make_nvp("stride" , t._stride );
|
||||
if (t._ptr != UNINIT)
|
||||
ar & boost::serialization::make_nvp("rounds", t._rounds )
|
||||
& boost::serialization::make_nvp("state" , t._state );
|
||||
ar & boost::serialization::make_nvp("checksum", _checksum );
|
||||
if (t.Check(_version, _eversion, _mversion) != _checksum)
|
||||
throw RandomErr("RandomEngine: Checksum failure");
|
||||
_seed.reserve(t._seed.size());
|
||||
*this = t;
|
||||
}
|
||||
/**
|
||||
* Glue the boost save and load functionality together---a bit of boost
|
||||
* magic.
|
||||
**********************************************************************/
|
||||
template<class Archive>
|
||||
void serialize(Archive &ar, const unsigned int file_version)
|
||||
{ boost::serialization::split_member(ar, *this, file_version); }
|
||||
#endif // HAVE_BOOST_SERIALIZATION
|
||||
|
||||
};
|
||||
|
||||
typedef RandomEngine<MT19937 <Random_u32>, MixerSFMT> MRandomGenerator32;
|
||||
typedef RandomEngine<MT19937 <Random_u64>, MixerSFMT> MRandomGenerator64;
|
||||
typedef RandomEngine<SFMT19937<Random_u32>, MixerSFMT> SRandomGenerator32;
|
||||
typedef RandomEngine<SFMT19937<Random_u64>, MixerSFMT> SRandomGenerator64;
|
||||
|
||||
} // namespace RandomLib
|
||||
|
||||
namespace std {
|
||||
/**
|
||||
* Swap two RandomEngines. This is about 3x faster than the default swap.
|
||||
*
|
||||
* @tparam Algorithm the algorithm for the RandomEngine.
|
||||
* @tparam Mixer the mixer for the RandomEngine.
|
||||
* @param[in,out] r the first RandomEngine to swap.
|
||||
* @param[in,out] s the second RandomEngine to swap.
|
||||
**********************************************************************/
|
||||
template<class Algorithm, class Mixer>
|
||||
void swap(RandomLib::RandomEngine<Algorithm, Mixer>& r,
|
||||
RandomLib::RandomEngine<Algorithm, Mixer>& s) throw() {
|
||||
r.swap(s);
|
||||
}
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif // RANDOMLIB_RANDOMENGINE_HPP
|
@ -1,258 +0,0 @@
|
||||
/**
|
||||
* \file RandomMixer.hpp
|
||||
* \brief Header for Mixer classes.
|
||||
*
|
||||
* Mixer classes convert a seed vector into a random generator state. An
|
||||
* important property of this method is that "close" seeds should produce
|
||||
* "widely separated" states. This allows the seeds to be set is some
|
||||
* systematic fashion to produce a set of uncorrelated random number
|
||||
* sequences.
|
||||
*
|
||||
* Copyright (c) Charles Karney (2006-2011) <charles@karney.com> and licensed
|
||||
* under the MIT/X11 License. For more information, see
|
||||
* http://randomlib.sourceforge.net/
|
||||
**********************************************************************/
|
||||
|
||||
#if !defined(RANDOMLIB_RANDOMMIXER_HPP)
|
||||
#define RANDOMLIB_RANDOMMIXER_HPP 1
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <RandomLib/RandomSeed.hpp>
|
||||
|
||||
namespace RandomLib {
|
||||
|
||||
/**
|
||||
* \brief The original %MT19937 mixing functionality
|
||||
*
|
||||
* This implements the functionality of init_by_array in MT19937
|
||||
* http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/CODES/mt19937ar.c
|
||||
* and init_by_array64 in MT19937_64
|
||||
* http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/VERSIONS/C-LANG/mt19937-64.c
|
||||
* with the following changes:
|
||||
* - in the case of an zero-length seed array, behave in the same way if
|
||||
* MT19937 and MT19937_64 are called without initialization in which case,
|
||||
* e.g., init_genrand(5489UL) is called. (init_by_array does not allow
|
||||
* calling with a zero-length seed.)
|
||||
* - init_by_array64 accepts a seed array of 64-bit unsigned ints. Here with
|
||||
* seed is an array of 32-bit unsigned ints and these are repacked into
|
||||
* 64-bit quantities internally using a LSB convention. Thus, to mimic the
|
||||
* MT19937_64 sample invocation with a seed array {0x12345ULL, 0x23456ULL,
|
||||
* 0x34567ULL, 0x45678ULL}, MixerMT0<Random_u64>::SeedToState needs to
|
||||
* be invoked with a seed vector [0x12345UL, 0, 0x23456UL, 0, 0x34567UL, 0,
|
||||
* 0x45678UL, 0]. (Actually the last 0 is unnecessary.)
|
||||
*
|
||||
* The template parameter \e RandomType switches between the 32-bit and
|
||||
* 64-bit versions.
|
||||
*
|
||||
* MixerMT0 is specific to the MT19937 generators and should not be used
|
||||
* for other generators (e.g., SFMT19937). In addition, MixerMT0 has
|
||||
* known defects and should only be used to check the operation of the
|
||||
* MT19937 engines against the original implementation. These defects are
|
||||
* described in the MixerMT1 which is a modification of MixerMT0
|
||||
* which corrects these defects. For production use MixerMT1 or,
|
||||
* preferably, MixerSFMT should be used.
|
||||
*
|
||||
* @tparam RandomType the type of the results, either Random_u32 or
|
||||
* Random_u64.
|
||||
**********************************************************************/
|
||||
template<class RandomType> class RANDOMLIB_EXPORT MixerMT0 {
|
||||
public:
|
||||
/**
|
||||
* The RandomType controlling the output of MixerMT0::SeedToState
|
||||
**********************************************************************/
|
||||
typedef RandomType mixer_t;
|
||||
/**
|
||||
* A version number which should be unique to this RandomMixer. This
|
||||
* prevents RandomEngine::Load from loading a saved generator with a
|
||||
* different RandomMixer. Here the version is "MxMT" or "MxMU".
|
||||
**********************************************************************/
|
||||
static const unsigned version = 0x4d784d54UL + (mixer_t::width == 64);
|
||||
private:
|
||||
/**
|
||||
* The unsigned type corresponding to mixer_t.
|
||||
**********************************************************************/
|
||||
typedef typename mixer_t::type mixer_type;
|
||||
/**
|
||||
* The mask for mixer_t.
|
||||
**********************************************************************/
|
||||
static const mixer_type mask = mixer_t::mask;
|
||||
public:
|
||||
/**
|
||||
* Mix the seed vector, \e seed, into the state array, \e state, of size \e
|
||||
* n.
|
||||
*
|
||||
* @param[in] seed the input seed vector.
|
||||
* @param[out] state the generator state.
|
||||
* @param[in] n the size of the state.
|
||||
**********************************************************************/
|
||||
static void SeedToState(const std::vector<RandomSeed::seed_type>& seed,
|
||||
mixer_type state[], unsigned n) throw();
|
||||
/**
|
||||
* Return the name of this class.
|
||||
*
|
||||
* @return the name.
|
||||
**********************************************************************/
|
||||
static std::string Name() {
|
||||
return "MixerMT0<Random_u" +
|
||||
std::string(mixer_t::width == 32 ? "32" : "64") + ">";
|
||||
}
|
||||
private:
|
||||
static const mixer_type a0 = 5489ULL;
|
||||
static const mixer_type a1 = 19650218ULL;
|
||||
static const mixer_type
|
||||
b = mixer_t::width == 32 ? 1812433253ULL : 6364136223846793005ULL;
|
||||
static const mixer_type
|
||||
c = mixer_t::width == 32 ? 1664525ULL : 3935559000370003845ULL;
|
||||
static const mixer_type
|
||||
d = mixer_t::width == 32 ? 1566083941ULL : 2862933555777941757ULL;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief The modified %MT19937 mixing functionality
|
||||
*
|
||||
* MixerMT0 has two defects
|
||||
* - The zeroth word of the state is set to a constant (independent of the
|
||||
* seed). This is a relatively minor defect which halves the accessible
|
||||
* state space for MT19937 (but the resulting state space is still huge).
|
||||
* (Actually, for the 64-bit version, it reduces the accessible states by
|
||||
* 2<sup>33</sup>. On the other hand the 64-bit has better mixing
|
||||
* properties.)
|
||||
* - Close seeds, for example, [1] and [1,0], result in the same state. This
|
||||
* is a potentially serious flaw which might result is identical random
|
||||
* number sequences being generated instead of independent sequences.
|
||||
*
|
||||
* MixerMT1 fixes these defects in a straightforward manner. The
|
||||
* resulting algorithm was included in one of the proposals for Random Number
|
||||
* Generation for C++0X, see Brown, et al.,
|
||||
* http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2079.pdf
|
||||
*
|
||||
* The template parameter \e RandomType switches between the 32-bit and
|
||||
* 64-bit versions.
|
||||
*
|
||||
* MixerMT1 still has a weakness in that it doesn't thoroughly mix the
|
||||
* state. This is illustrated by an example given to me by Makoto Matsumoto:
|
||||
* Consider a seed of length \e N and suppose we consider all \e
|
||||
* W<sup><i>N</i>/2</sup> values for the first half of the seed (here \e W =
|
||||
* 2<sup><i>width</i></sup>). MixerMT1 has a bottleneck in the way that
|
||||
* the state is initialized which results in the second half of the state
|
||||
* only taking on \e W<sup>2</sup> possible values. MixerSFMT mixes the
|
||||
* seed into the state much more thoroughly.
|
||||
*
|
||||
* @tparam RandomType the type of the results, either Random_u32 or
|
||||
* Random_u64.
|
||||
**********************************************************************/
|
||||
template<class RandomType> class RANDOMLIB_EXPORT MixerMT1 {
|
||||
public:
|
||||
/**
|
||||
* The RandomType controlling the output of MixerMT1::SeedToState
|
||||
**********************************************************************/
|
||||
typedef RandomType mixer_t;
|
||||
/**
|
||||
* A version number which should be unique to this RandomMixer. This
|
||||
* prevents RandomEngine::Load from loading a saved generator with a
|
||||
* different RandomMixer. Here the version is "MxMV" or "MxMW".
|
||||
**********************************************************************/
|
||||
static const unsigned version = 0x4d784d56UL + (mixer_t::width == 64);
|
||||
private:
|
||||
/**
|
||||
* The unsigned type corresponding to mixer_t.
|
||||
**********************************************************************/
|
||||
typedef typename mixer_t::type mixer_type;
|
||||
/**
|
||||
* The mask for mixer_t.
|
||||
**********************************************************************/
|
||||
static const mixer_type mask = mixer_t::mask;
|
||||
public:
|
||||
/**
|
||||
* Mix the seed vector, \e seed, into the state array, \e state, of size \e
|
||||
* n.
|
||||
*
|
||||
* @param[in] seed the input seed vector.
|
||||
* @param[out] state the generator state.
|
||||
* @param[in] n the size of the state.
|
||||
**********************************************************************/
|
||||
static void SeedToState(const std::vector<RandomSeed::seed_type>& seed,
|
||||
mixer_type state[], unsigned n) throw();
|
||||
/**
|
||||
* Return the name of this class.
|
||||
*
|
||||
* @return the name.
|
||||
**********************************************************************/
|
||||
static std::string Name() {
|
||||
return "MixerMT1<Random_u" +
|
||||
std::string(mixer_t::width == 32 ? "32" : "64") + ">";
|
||||
}
|
||||
private:
|
||||
static const mixer_type a = 5489ULL;
|
||||
static const mixer_type
|
||||
b = mixer_t::width == 32 ? 1812433253ULL : 6364136223846793005ULL;
|
||||
static const mixer_type
|
||||
c = mixer_t::width == 32 ? 1664525ULL : 3935559000370003845ULL;
|
||||
static const mixer_type
|
||||
d = mixer_t::width == 32 ? 1566083941ULL : 2862933555777941757ULL;
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief The SFMT mixing functionality
|
||||
*
|
||||
* MixerSFMT is adapted from SFMT's init_by_array Mutsuo Saito given in
|
||||
* http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/SFMT-src-1.2.tar.gz
|
||||
* and is part of the C++11 standard; see P. Becker, Working Draft, Standard
|
||||
* for Programming Language C++, Oct. 2007, Sec. 26.4.7.1,
|
||||
* http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2461.pdf
|
||||
*
|
||||
* MixerSFMT contains a single change is to allow it to function properly
|
||||
* when the size of the state is small.
|
||||
*
|
||||
* MixerSFMT mixes the seed much more thoroughly than MixerMT1 and, in
|
||||
* particular, it removes the mixing bottleneck present in MixerMT1.
|
||||
* Thus it is the recommended mixing scheme for all production work.
|
||||
**********************************************************************/
|
||||
class RANDOMLIB_EXPORT MixerSFMT {
|
||||
public:
|
||||
/**
|
||||
* The RandomType controlling the output of MixerSFMT::SeedToState
|
||||
**********************************************************************/
|
||||
typedef Random_u32 mixer_t;
|
||||
/**
|
||||
* A version number which should be unique to this RandomMixer. This
|
||||
* prevents RandomEngine::Load from loading a saved generator with a
|
||||
* different RandomMixer. Here the version is "MxSM".
|
||||
**********************************************************************/
|
||||
static const unsigned version = 0x4d78534dUL;
|
||||
private:
|
||||
/**
|
||||
* The unsigned type corresponding to mixer_t.
|
||||
**********************************************************************/
|
||||
typedef mixer_t::type mixer_type;
|
||||
/**
|
||||
* The mask for mixer_t.
|
||||
**********************************************************************/
|
||||
static const mixer_type mask = mixer_t::mask;
|
||||
public:
|
||||
/**
|
||||
* Mix the seed vector, \e seed, into the state array, \e state, of size \e
|
||||
* n.
|
||||
*
|
||||
* @param[in] seed the input seed vector.
|
||||
* @param[out] state the generator state.
|
||||
* @param[in] n the size of the state.
|
||||
**********************************************************************/
|
||||
static void SeedToState(const std::vector<RandomSeed::seed_type>& seed,
|
||||
mixer_type state[], unsigned n) throw();
|
||||
/**
|
||||
* Return the name of this class.
|
||||
*
|
||||
* @return the name.
|
||||
**********************************************************************/
|
||||
static std::string Name() { return "MixerSFMT"; }
|
||||
private:
|
||||
static const mixer_type a = 0x8b8b8b8bUL;
|
||||
static const mixer_type b = 1664525UL;
|
||||
static const mixer_type c = 1566083941UL;
|
||||
};
|
||||
|
||||
} // namespace RandomLib
|
||||
|
||||
#endif // RANDOMLIB_RANDOMMIXER_HPP
|
@ -1,472 +0,0 @@
|
||||
/**
|
||||
* \file RandomNumber.hpp
|
||||
* \brief Header for RandomNumber
|
||||
*
|
||||
* Infinite precision random numbers.
|
||||
*
|
||||
* Copyright (c) Charles Karney (2006-2013) <charles@karney.com> and licensed
|
||||
* under the MIT/X11 License. For more information, see
|
||||
* http://randomlib.sourceforge.net/
|
||||
**********************************************************************/
|
||||
|
||||
#if !defined(RANDOMLIB_RANDOMNUMBER_HPP)
|
||||
#define RANDOMLIB_RANDOMNUMBER_HPP 1
|
||||
|
||||
#include <vector>
|
||||
#include <iomanip>
|
||||
#include <limits>
|
||||
#include <cmath> // for std::pow
|
||||
#include <RandomLib/UniformInteger.hpp>
|
||||
|
||||
namespace RandomLib {
|
||||
/**
|
||||
* \brief Infinite precision random numbers.
|
||||
*
|
||||
* Implement infinite precision random numbers. Integer part is non-random.
|
||||
* Fraction part consists of any some number of digits in base
|
||||
* 2<sup><i>b</i></sup>. If \e m digits have been generated then the
|
||||
* fraction is uniformly distributed in the open interval
|
||||
* ∑<sub><i>k</i>=1</sub><sup><i>m</i></sup>
|
||||
* <i>f</i><sub><i>k</i>−1</sub>/2<sup><i>kb</i></sup> +
|
||||
* (0,1)/2<sup><i>mb</i></sup>. When a RandomNumber is first constructed the
|
||||
* integer part is zero and \e m = 0, and the number represents (0,1). A
|
||||
* RandomNumber is able to represent all numbers in the symmetric open
|
||||
* interval (−2<sup>31</sup>, 2<sup>31</sup>). In this implementation,
|
||||
* \e b must one of 1, 2, 3, 4, 8, 12, 16, 20, 24, 28, or 32. (This
|
||||
* restriction allows printing in hexadecimal and can easily be relaxed.
|
||||
* There's also no essential reason why the base should be a power of 2.)
|
||||
*
|
||||
* @tparam bits the number of bits in each digit.
|
||||
**********************************************************************/
|
||||
template<int bits = 1> class RandomNumber {
|
||||
public:
|
||||
/**
|
||||
* Constructor sets number to a random number uniformly distributed in
|
||||
* (0,1).
|
||||
**********************************************************************/
|
||||
RandomNumber() throw() : _n(0), _s(1) {}
|
||||
/**
|
||||
* Swap with another RandomNumber. This is a fast way of doing an
|
||||
* assignment.
|
||||
*
|
||||
* @param[in,out] t the RandomNumber to swap with.
|
||||
**********************************************************************/
|
||||
void swap(RandomNumber& t) throw() {
|
||||
if (this != &t) {
|
||||
std::swap(_n, t._n);
|
||||
std::swap(_s, t._s);
|
||||
_f.swap(t._f);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Return to initial state, uniformly distributed in (0,1).
|
||||
**********************************************************************/
|
||||
void Init() throw() {
|
||||
STATIC_ASSERT(bits > 0 && bits <= w && (bits < 4 || bits % 4 == 0),
|
||||
"RandomNumber: unsupported value for bits");
|
||||
_n = 0;
|
||||
_s = 1;
|
||||
_f.clear();
|
||||
}
|
||||
/**
|
||||
* @return the sign of the RandomNumber (± 1).
|
||||
**********************************************************************/
|
||||
int Sign() const throw() { return _s; }
|
||||
/**
|
||||
* Change the sign of the RandomNumber.
|
||||
**********************************************************************/
|
||||
void Negate() throw() { _s *= -1; }
|
||||
/**
|
||||
* @return the floor of the RandomNumber.
|
||||
**********************************************************************/
|
||||
int Floor() const throw() { return _s > 0 ? int(_n) : -1 - int(_n); }
|
||||
/**
|
||||
* @return the ceiling of the RandomNumber.
|
||||
**********************************************************************/
|
||||
int Ceiling() const throw() { return _s > 0 ? 1 + int(_n) : - int(_n); }
|
||||
/**
|
||||
* @return the unsigned integer component of the RandomNumber.
|
||||
**********************************************************************/
|
||||
unsigned UInteger() const throw() { return _n; }
|
||||
/**
|
||||
* Add integer \e k to the RandomNumber.
|
||||
*
|
||||
* @param[in] k the integer to add.
|
||||
**********************************************************************/
|
||||
void AddInteger(int k) throw() {
|
||||
k += Floor(); // The new floor
|
||||
int ns = k < 0 ? -1 : 1; // The new sign
|
||||
if (ns != _s) // If sign changes, set f = 1 - f
|
||||
for (size_t k = 0; k < Size(); ++k)
|
||||
_f[k] = ~_f[k] & mask;
|
||||
_n = ns > 0 ? k : -(k + 1);
|
||||
}
|
||||
/**
|
||||
* Compare with another RandomNumber, *this < \e t
|
||||
*
|
||||
* @tparam Random the type of the random generator.
|
||||
* @param[in,out] r a random generator.
|
||||
* @param[in,out] t a RandomNumber to compare.
|
||||
* @return true if *this < \e t.
|
||||
**********************************************************************/
|
||||
template<class Random> bool LessThan(Random& r, RandomNumber& t) {
|
||||
if (this == &t) return false; // same object
|
||||
if (_s != t._s) return _s < t._s;
|
||||
if (_n != t._n) return (_s < 0) ^ (_n < t._n);
|
||||
for (unsigned k = 0; ; ++k) {
|
||||
// Impose an order on the evaluation of the digits.
|
||||
const unsigned x = Digit(r,k);
|
||||
const unsigned y = t.Digit(r,k);
|
||||
if (x != y) return (_s < 0) ^ (x < y);
|
||||
// Two distinct numbers are never equal
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Compare RandomNumber with two others, *this > max(\e u, \e v)
|
||||
*
|
||||
* @tparam Random the type of the random generator.
|
||||
* @param[in,out] r a random generator.
|
||||
* @param[in,out] u first RandomNumber to compare.
|
||||
* @param[in,out] v second RandomNumber to compare.
|
||||
* @return true if *this > max(\e u, \e v).
|
||||
**********************************************************************/
|
||||
template<class Random> bool GreaterPair(Random& r,
|
||||
RandomNumber& u, RandomNumber& v) {
|
||||
// cmps is set to false as soon as u <= *this, and likewise for cmpt.
|
||||
bool cmpu = this != &u, cmpv = this != &v && &u != &v;
|
||||
if (!(cmpu || cmpv)) return true;
|
||||
// Check signs first
|
||||
if (cmpu) {
|
||||
if (u._s > _s) return false; // u > *this
|
||||
if (u._s < _s) cmpu = false;
|
||||
}
|
||||
if (cmpv) {
|
||||
if (v._s > _s) return false; // v > *this
|
||||
if (v._s < _s) cmpv = false;
|
||||
}
|
||||
if (!(cmpu || cmpv)) return true; // u <= *this && v <= *this
|
||||
// Check integer parts
|
||||
if (cmpu) {
|
||||
if ((_s < 0) ^ (u._n > _n)) return false; // u > *this
|
||||
if ((_s < 0) ^ (u._n < _n)) cmpu = false;
|
||||
}
|
||||
if (cmpv) {
|
||||
if ((_s < 0) ^ (v._n > _n)) return false; // v > *this
|
||||
if ((_s < 0) ^ (v._n < _n)) cmpv = false;
|
||||
}
|
||||
if (!(cmpu || cmpv)) return true; // u <= *this && v <= *this
|
||||
// Check fractions
|
||||
for (unsigned k = 0; ; ++k) {
|
||||
// Impose an order on the evaluation of the digits. Note that this is
|
||||
// asymmetric on interchange of u and v; since u is tested first, more
|
||||
// digits of u are generated than v (on average).
|
||||
const unsigned x = Digit(r,k);
|
||||
if (cmpu) {
|
||||
const unsigned y = u.Digit(r,k);
|
||||
if ((_s < 0) ^ (y > x)) return false; // u > *this
|
||||
if ((_s < 0) ^ (y < x)) cmpu = false;
|
||||
}
|
||||
if (cmpv) {
|
||||
const unsigned y = v.Digit(r,k);
|
||||
if ((_s < 0) ^ (y > x)) return false; // v > *this
|
||||
if ((_s < 0) ^ (y < x)) cmpv = false;
|
||||
}
|
||||
if (!(cmpu || cmpv)) return true; // u <= *this && v <= *this
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Compare with a fraction, *this < <i>p</i>/<i>q</i>
|
||||
*
|
||||
* @tparam Random the type of the random generator.
|
||||
* @param[in,out] r a random generator.
|
||||
* @param[in] p the numerator of the fraction.
|
||||
* @param[in] q the denominator of the fraction (require \e q > 0).
|
||||
* @return true if *this < <i>p</i>/<i>q</i>.
|
||||
**********************************************************************/
|
||||
template<class Random, typename IntType>
|
||||
bool LessThan(Random& r, IntType p, IntType q) {
|
||||
for (int k = 0;; ++k) {
|
||||
if (p <= 0) return false;
|
||||
if (p >= q) return true;
|
||||
// Here p is in [1,q-1]. Need to avoid overflow in computation of
|
||||
// (q-1)<<bits and (2^bits-1)*q
|
||||
p = (p << bits) - Digit(r,k) * q;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Compare with a paritally sampled fraction
|
||||
*
|
||||
* @tparam Random the type of the random generator.
|
||||
* @param[in,out] r a random generator.
|
||||
* @param[in] p0 the starting point for the numerator.
|
||||
* @param[in] c the stride for the fraction (require \e c > 0).
|
||||
* @param[in] q the denominator of the fraction (require \e q > 0).
|
||||
* @param[in,out] j the increment for the numerator.
|
||||
* @return true if *this < (<i>p</i><sub>0</sub> + <i>cj</i>)/<i>q</i>.
|
||||
**********************************************************************/
|
||||
template<class Random, typename IntType>
|
||||
bool LessThan(Random& r, IntType p0, IntType c, IntType q,
|
||||
UniformInteger<IntType, bits>& j) {
|
||||
for (int k = 0;; ++k) {
|
||||
if (j. LessThanEqual(r, - p0, c)) return false;
|
||||
if (j.GreaterThanEqual(r, q - p0, c)) return true;
|
||||
p0 = (p0 << bits) - IntType(Digit(r,k)) * q;
|
||||
c <<= bits;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @tparam Random the type of the random generator.
|
||||
* @param[in,out] r a random generator.
|
||||
* @param[in] k the index of a digit of the fraction
|
||||
* @return digit number \e k, generating it if necessary.
|
||||
**********************************************************************/
|
||||
template<class Random> unsigned Digit(Random& r, unsigned k) {
|
||||
ExpandTo(r, k + 1);
|
||||
return _f[k];
|
||||
}
|
||||
/**
|
||||
* Add one digit to the fraction.
|
||||
*
|
||||
* @tparam Random the type of the random generator.
|
||||
* @param[in,out] r a random generator.
|
||||
**********************************************************************/
|
||||
template<class Random> void AddDigit(Random& r)
|
||||
{ _f.push_back(RandomDigit(r)); }
|
||||
/**
|
||||
* @param[in] k the index of a digit of the fraction
|
||||
* @return a const reference to digit number \e k, without generating new
|
||||
* digits.
|
||||
* @exception std::out_of_range if the digit hasn't been generated.
|
||||
**********************************************************************/
|
||||
const unsigned& RawDigit(unsigned k) const throw()
|
||||
{ return (const unsigned&)(_f.at(k)); }
|
||||
/**
|
||||
* @param[in] k the index of a digit of the fraction
|
||||
* @return a non-const reference to digit number \e k, without generating
|
||||
* new digits.
|
||||
* @exception std::out_of_range if the digit hasn't been generated.
|
||||
**********************************************************************/
|
||||
unsigned& RawDigit(unsigned k) throw()
|
||||
{ return (unsigned&)(_f.at(k)); }
|
||||
/**
|
||||
* Return to initial state, uniformly distributed in \e n + (0,1). This is
|
||||
* similar to Init but also returns the memory used by the object to the
|
||||
* system. Normally Init should be used.
|
||||
**********************************************************************/
|
||||
void Clear() {
|
||||
std::vector<unsigned> z(0);
|
||||
_n = 0;
|
||||
_s = 1;
|
||||
_f.swap(z);
|
||||
}
|
||||
/**
|
||||
* @return the number of digits in fraction
|
||||
**********************************************************************/
|
||||
unsigned Size() const throw() { return unsigned(_f.size()); }
|
||||
/**
|
||||
* Return the fraction part of the RandomNumber as a floating point number
|
||||
* of type RealType rounded to the nearest multiple of
|
||||
* 1/2<sup><i>p</i></sup>, where \e p =
|
||||
* std::numeric_limits<RealType>::digits, and, if necessary, creating
|
||||
* additional digits of the number.
|
||||
*
|
||||
* @tparam RealType the floating point type to convert to.
|
||||
* @tparam Random the type of the random generator.
|
||||
* @param[in,out] r a random generator for generating the necessary digits.
|
||||
* @return the fraction of the RandomNumber rounded to a RealType.
|
||||
**********************************************************************/
|
||||
template<typename RealType, typename Random> RealType Fraction(Random& r) {
|
||||
STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer,
|
||||
"RandomNumber::Fraction: invalid real type RealType");
|
||||
const int d = std::numeric_limits<RealType>::digits;
|
||||
const int k = (d + bits - 1)/bits;
|
||||
const int kg = (d + bits)/bits; // For guard bit
|
||||
RealType y = 0;
|
||||
if (Digit(r, kg - 1) & (1U << (kg * bits - d - 1)))
|
||||
// if guard bit is set, round up.
|
||||
y += std::pow(RealType(2), -d);
|
||||
const RealType fact = std::pow(RealType(2), -bits);
|
||||
RealType mult = RealType(1);
|
||||
for (int i = 0; i < k; ++i) {
|
||||
mult *= fact;
|
||||
y += mult * RealType(i < k - 1 ? RawDigit(i) :
|
||||
RawDigit(i) & (~0U << (k * bits - d)));
|
||||
}
|
||||
return y;
|
||||
}
|
||||
/**
|
||||
* Return the value of the RandomNumber rounded to nearest floating point
|
||||
* number of type RealType and, if necessary, creating additional digits of
|
||||
* the number.
|
||||
*
|
||||
* @tparam RealType the floating point type to convert to.
|
||||
* @tparam Random the type of the random generator.
|
||||
* @param[in,out] r a random generator for generating the necessary digits.
|
||||
* @return the value of the RandomNumber rounded to a RealType.
|
||||
**********************************************************************/
|
||||
template<typename RealType, class Random> RealType Value(Random& r) {
|
||||
// Ignore the possibility of overflow here (OK because int doesn't
|
||||
// currently overflow any real type). Assume the real type supports
|
||||
// denormalized numbers. Need to treat rounding explicitly since the
|
||||
// missing digits always imply rounding up.
|
||||
STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer,
|
||||
"RandomNumber::Value: invalid real type RealType");
|
||||
const int digits = std::numeric_limits<RealType>::digits,
|
||||
min_exp = std::numeric_limits<RealType>::min_exponent;
|
||||
RealType y;
|
||||
int lead; // Position of leading bit (0.5 = position 0)
|
||||
if (_n) lead = highest_bit_idx(_n);
|
||||
else {
|
||||
int i = 0;
|
||||
while ( Digit(r, i) == 0 && i < (-min_exp)/bits ) ++i;
|
||||
lead = highest_bit_idx(RawDigit(i)) - (i + 1) * bits;
|
||||
// To handle denormalized numbers set lead = max(lead, min_exp)
|
||||
lead = lead > min_exp ? lead : min_exp;
|
||||
}
|
||||
int trail = lead - digits; // Position of guard bit (0.5 = position 0)
|
||||
if (trail > 0) {
|
||||
y = RealType(_n & (~0U << trail));
|
||||
if (_n & (1U << (trail - 1)))
|
||||
y += std::pow(RealType(2), trail);
|
||||
} else {
|
||||
y = RealType(_n);
|
||||
int k = (-trail)/bits; // Byte with guard bit
|
||||
if (Digit(r, k) & (1U << ((k + 1) * bits + trail - 1)))
|
||||
// If guard bit is set, round bit (some subsequent bit will be 1).
|
||||
y += std::pow(RealType(2), trail);
|
||||
// Byte with trailing bit (can be negative)
|
||||
k = (-trail - 1 + bits)/bits - 1;
|
||||
const RealType fact = std::pow(RealType(2), -bits);
|
||||
RealType mult = RealType(1);
|
||||
for (int i = 0; i <= k; ++i) {
|
||||
mult *= fact;
|
||||
y += mult *
|
||||
RealType(i < k ? RawDigit(i) :
|
||||
RawDigit(i) & (~0U << ((k + 1) * bits + trail)));
|
||||
}
|
||||
}
|
||||
if (_s < 0) y *= -1;
|
||||
return y;
|
||||
}
|
||||
/**
|
||||
* Return the range of possible values for the RandomNumber as pair of
|
||||
* doubles. This doesn't create any additional digits of the result and
|
||||
* doesn't try to control roundoff.
|
||||
*
|
||||
* @return a pair denoting the range with first being the lower limit and
|
||||
* second being the upper limit.
|
||||
**********************************************************************/
|
||||
std::pair<double, double> Range() const throw() {
|
||||
double y = _n;
|
||||
const double fact = std::pow(double(2), -bits);
|
||||
double mult = double(1);
|
||||
for (unsigned i = 0; i < Size(); ++i) {
|
||||
mult *= fact;
|
||||
y += mult * RawDigit(i);
|
||||
}
|
||||
return std::pair<double, double>(_s > 0 ? y : -(y + mult),
|
||||
_s > 0 ? (y + mult) : -y);
|
||||
}
|
||||
/**
|
||||
* @tparam Random the type of the random generator.
|
||||
* @param[in,out] r a random generator.
|
||||
* @return a random digit in [0, 2<sup><i>bits</i></sup>).
|
||||
**********************************************************************/
|
||||
template<class Random> static unsigned RandomDigit(Random& r) throw()
|
||||
{ return unsigned(r.template Integer<bits>()); }
|
||||
|
||||
private:
|
||||
/**
|
||||
* The integer part
|
||||
**********************************************************************/
|
||||
unsigned _n;
|
||||
/**
|
||||
* The sign
|
||||
**********************************************************************/
|
||||
int _s;
|
||||
/**
|
||||
* The fraction part
|
||||
**********************************************************************/
|
||||
std::vector<unsigned> _f;
|
||||
/**
|
||||
* Fill RandomNumber to \e k digits.
|
||||
**********************************************************************/
|
||||
template<class Random> void ExpandTo(Random& r, size_t k) {
|
||||
size_t l = _f.size();
|
||||
if (k <= l)
|
||||
return;
|
||||
_f.resize(k);
|
||||
for (size_t i = l; i < k; ++i)
|
||||
_f[i] = RandomDigit(r);
|
||||
}
|
||||
/**
|
||||
* Return index [0..32] of highest bit set. Return 0 if x = 0, 32 is if x
|
||||
* = ~0. (From Algorithms for programmers by Joerg Arndt.)
|
||||
**********************************************************************/
|
||||
static int highest_bit_idx(unsigned x) throw() {
|
||||
if (x == 0) return 0;
|
||||
int r = 1;
|
||||
if (x & 0xffff0000U) { x >>= 16; r += 16; }
|
||||
if (x & 0x0000ff00U) { x >>= 8; r += 8; }
|
||||
if (x & 0x000000f0U) { x >>= 4; r += 4; }
|
||||
if (x & 0x0000000cU) { x >>= 2; r += 2; }
|
||||
if (x & 0x00000002U) { r += 1; }
|
||||
return r;
|
||||
}
|
||||
/**
|
||||
* The number of bits in unsigned.
|
||||
**********************************************************************/
|
||||
static const int w = std::numeric_limits<unsigned>::digits;
|
||||
public:
|
||||
/**
|
||||
* A mask for the digits.
|
||||
**********************************************************************/
|
||||
static const unsigned mask =
|
||||
bits == w ? ~0U : ~(~0U << (bits < w ? bits : 0));
|
||||
};
|
||||
|
||||
/**
|
||||
* \relates RandomNumber
|
||||
* Print a RandomNumber. Format is n.dddd... where the base for printing is
|
||||
* 2<sup>max(4,<i>b</i>)</sup>. The ... represents an infinite sequence of
|
||||
* ungenerated random digits (uniformly distributed). Thus with \e b = 1,
|
||||
* 0.0... = (0,1/2), 0.00... = (0,1/4), 0.11... = (3/4,1), etc.
|
||||
**********************************************************************/
|
||||
template<int bits>
|
||||
std::ostream& operator<<(std::ostream& os, const RandomNumber<bits>& n) {
|
||||
const std::ios::fmtflags oldflags = os.flags();
|
||||
RandomNumber<bits> t = n;
|
||||
os << (t.Sign() > 0 ? "+" : "-");
|
||||
unsigned i = t.UInteger();
|
||||
os << std::hex << std::setfill('0');
|
||||
if (i == 0)
|
||||
os << "0";
|
||||
else {
|
||||
bool first = true;
|
||||
const int w = std::numeric_limits<unsigned>::digits;
|
||||
const unsigned mask = RandomNumber<bits>::mask;
|
||||
for (int s = ((w + bits - 1)/bits) * bits - bits; s >= 0; s -= bits) {
|
||||
unsigned d = mask & (i >> s);
|
||||
if (d || !first) {
|
||||
if (first) {
|
||||
os << d;
|
||||
first = false;
|
||||
}
|
||||
else
|
||||
os << std::setw((bits+3)/4) << d;
|
||||
}
|
||||
}
|
||||
}
|
||||
os << ".";
|
||||
unsigned s = t.Size();
|
||||
for (unsigned i = 0; i < s; ++i)
|
||||
os << std::setw((bits+3)/4) << t.RawDigit(i);
|
||||
os << "..." << std::setfill(' ');
|
||||
os.flags(oldflags);
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace RandomLib
|
||||
|
||||
#endif // RANDOMLIB_RANDOMNUMBER_HPP
|
@ -1,77 +0,0 @@
|
||||
/**
|
||||
* \file RandomPower2.hpp
|
||||
* \brief Header for RandomPower2.
|
||||
*
|
||||
* Return and multiply by powers of two.
|
||||
*
|
||||
* Copyright (c) Charles Karney (2006-2011) <charles@karney.com> and licensed
|
||||
* under the MIT/X11 License. For more information, see
|
||||
* http://randomlib.sourceforge.net/
|
||||
**********************************************************************/
|
||||
|
||||
#if !defined(RANDOMLIB_RANDOMPOWER2_HPP)
|
||||
#define RANDOMLIB_RANDOMPOWER2_HPP 1
|
||||
|
||||
#include <cmath> // For std::pow
|
||||
|
||||
namespace RandomLib {
|
||||
|
||||
/**
|
||||
* \brief Return or multiply by powers of 2
|
||||
*
|
||||
* With some compilers it's fastest to do a table lookup of powers of
|
||||
* 2. If RANDOMLIB_POWERTABLE is 1, a lookup table is used. If
|
||||
* RANDOMLIB_POWERTABLE is 0, then std::pow is used.
|
||||
**********************************************************************/
|
||||
class RANDOMLIB_EXPORT RandomPower2 {
|
||||
public:
|
||||
/**
|
||||
* Return powers of 2 (either using a lookup table or std::pow)
|
||||
*
|
||||
* @param[in] n the integer power.
|
||||
* @return 2<sup><i>n</i></sup>.
|
||||
**********************************************************************/
|
||||
template<typename RealType> static inline RealType pow2(int n) throw() {
|
||||
#if RANDOMLIB_POWERTABLE
|
||||
return RealType(power2[n - minpow]);
|
||||
#else
|
||||
return std::pow(RealType(2), n);
|
||||
#endif
|
||||
}
|
||||
/**
|
||||
* Multiply a real by a power of 2
|
||||
*
|
||||
* @tparam RealType the type of \e x.
|
||||
* @param[in] x the real number.
|
||||
* @param[in] n the power (positive or negative).
|
||||
* @return \e x 2<sup><i>n</i></sup>.
|
||||
**********************************************************************/
|
||||
template<typename RealType>
|
||||
static inline RealType shiftf(RealType x, int n) throw()
|
||||
// std::ldexp(x, n); is equivalent, but slower
|
||||
{ return x * pow2<RealType>(n); }
|
||||
|
||||
// Constants
|
||||
enum {
|
||||
/**
|
||||
* Minimum power in RandomPower2::power2
|
||||
**********************************************************************/
|
||||
#if RANDOMLIB_LONGDOUBLEPREC > 64
|
||||
minpow = -120,
|
||||
#else
|
||||
minpow = -64,
|
||||
#endif
|
||||
maxpow = 64 /**< Maximum power in RandomPower2::power2. */
|
||||
};
|
||||
private:
|
||||
#if RANDOMLIB_POWERTABLE
|
||||
/**
|
||||
* Table of powers of two
|
||||
**********************************************************************/
|
||||
static const float power2[maxpow - minpow + 1]; // Powers of two
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace RandomLib
|
||||
|
||||
#endif // RANDOMLIB_RANDOMPOWER2_HPP
|
@ -1,251 +0,0 @@
|
||||
/**
|
||||
* \file RandomSeed.hpp
|
||||
* \brief Header for RandomSeed
|
||||
*
|
||||
* This provides a base class for random generators.
|
||||
*
|
||||
* Copyright (c) Charles Karney (2006-2011) <charles@karney.com> and licensed
|
||||
* under the MIT/X11 License. For more information, see
|
||||
* http://randomlib.sourceforge.net/
|
||||
**********************************************************************/
|
||||
|
||||
#if !defined(RANDOMLIB_RANDOMSEED_HPP)
|
||||
#define RANDOMLIB_RANDOMSEED_HPP 1
|
||||
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include <iterator>
|
||||
#include <algorithm> // For std::transform
|
||||
#include <sstream> // For VectorToString
|
||||
#include <RandomLib/RandomType.hpp>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
// Squelch warnings about dll vs vector
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable: 4251)
|
||||
#endif
|
||||
|
||||
namespace RandomLib {
|
||||
/**
|
||||
* \brief A base class for random generators
|
||||
*
|
||||
* This provides facilities for managing the seed and for converting the seed
|
||||
* into random generator state.
|
||||
*
|
||||
* The seed is taken to be a vector of unsigned longs of arbitrary length.
|
||||
* (Only the low 32 bit of each element of the vector are used.) The class
|
||||
* provides several methods for setting the seed, static functions for
|
||||
* producing "random" and "unique" seeds, and facilities for converting the
|
||||
* seed to a string so that it can be printed easily.
|
||||
*
|
||||
* The seeding algorithms are those used by
|
||||
* <a href="http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html">
|
||||
* MT19937</a> with some modifications to make all states accessible and to
|
||||
* minimize the likelihood of different seeds giving the same state.
|
||||
*
|
||||
* Finally some low-level routines are provided to facilitate the creation of
|
||||
* I/O methods for the random generator.
|
||||
*
|
||||
* A random generator class can be written based on this class. The
|
||||
* generator class would use the base class methods for setting the seed and
|
||||
* for converting the seed into state. It would provide the machinery for
|
||||
* advancing the state and for producing random data. It is also responsible
|
||||
* for the routine to save and restore the generator state (including the
|
||||
* seed).
|
||||
*
|
||||
* Written by Charles Karney <charles@karney.com> and licensed under the
|
||||
* MIT/X11 License. The seeding algorithms are adapted from those of
|
||||
* <a href="http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html">
|
||||
* MT19937</a>. For more information, see http://randomlib.sourceforge.net/
|
||||
**********************************************************************/
|
||||
class RANDOMLIB_EXPORT RandomSeed {
|
||||
public:
|
||||
typedef Random_u32 u32;
|
||||
typedef Random_u64 u64;
|
||||
|
||||
virtual ~RandomSeed() throw() = 0;
|
||||
/**
|
||||
* A type large enough to hold the seed words. This is needs to hold 32
|
||||
* bits and is an unsigned long for portability.
|
||||
**********************************************************************/
|
||||
typedef RandomType<32, unsigned long> seed_t;
|
||||
typedef seed_t::type seed_type;
|
||||
|
||||
/**
|
||||
* \name Resetting the seed
|
||||
**********************************************************************/
|
||||
///@{
|
||||
/**
|
||||
* Set the seed to a vector \e v. Only the low \e 32 bits of each element
|
||||
* are used.
|
||||
*
|
||||
* @tparam IntType the integral type of the elements of the vector.
|
||||
* @param[in] v the vector of elements.
|
||||
**********************************************************************/
|
||||
template<typename IntType> void Reseed(const std::vector<IntType>& v) {
|
||||
Reseed(v.begin(), v.end());
|
||||
}
|
||||
/**
|
||||
* Set the seed to [\e a, \e b) from a pair of iterators. The iterator
|
||||
* must produce results which can be converted into seed_type. Only the
|
||||
* low 32 bits of each element are used.
|
||||
*
|
||||
* @tparam InputIterator the type of the iterator.
|
||||
* @param[in] a the beginning iterator.
|
||||
* @param[in] b the ending iterator.
|
||||
**********************************************************************/
|
||||
template<typename InputIterator>
|
||||
void Reseed(InputIterator a, InputIterator b) {
|
||||
// Read new seed into temporary so as not to change object on error.
|
||||
std::vector<seed_type> t;
|
||||
std::transform(a, b, back_inserter(t),
|
||||
seed_t::cast<typename std::iterator_traits<InputIterator>
|
||||
::value_type>);
|
||||
_seed.swap(t);
|
||||
Reset();
|
||||
}
|
||||
/**
|
||||
* Set the seed to [\e n]. Only the low 32 bits of \e n are used.
|
||||
*
|
||||
* @param[in] n the new seed to use.
|
||||
**********************************************************************/
|
||||
void Reseed(seed_type n) {
|
||||
// Reserve space for new seed so as not to change object on error.
|
||||
_seed.reserve(1);
|
||||
_seed.resize(1);
|
||||
_seed[0] = seed_t::cast(n);
|
||||
Reset();
|
||||
}
|
||||
/**
|
||||
* Set the seed to [SeedVector()]. This is the standard way to reseed with
|
||||
* a "unique" seed.
|
||||
**********************************************************************/
|
||||
void Reseed() { Reseed(SeedVector()); }
|
||||
/**
|
||||
* Set the seed from the string \e s using Random::StringToVector.
|
||||
*
|
||||
* @param[in] s the string to be decoded into a seed.
|
||||
**********************************************************************/
|
||||
void Reseed(const std::string& s) {
|
||||
// Read new seed into temporary so as not to change object on error.
|
||||
std::vector<seed_type> t = StringToVector(s);
|
||||
_seed.swap(t);
|
||||
Reset();
|
||||
}
|
||||
///@}
|
||||
|
||||
/**
|
||||
* \name Examining the seed
|
||||
**********************************************************************/
|
||||
///@{
|
||||
/**
|
||||
* Return reference to the seed vector (read-only).
|
||||
*
|
||||
* @return the seed vector.
|
||||
**********************************************************************/
|
||||
const std::vector<seed_type>& Seed() const throw() { return _seed; }
|
||||
/**
|
||||
* Format the current seed suitable for printing.
|
||||
*
|
||||
* @return the seedd as a string.
|
||||
**********************************************************************/
|
||||
std::string SeedString() const { return VectorToString(_seed); }
|
||||
///@}
|
||||
|
||||
/**
|
||||
* \name Resetting the random seed
|
||||
**********************************************************************/
|
||||
///@{
|
||||
/**
|
||||
* Resets the sequence to its just-seeded state. This needs to be declared
|
||||
* virtual here so that the Reseed functions can call it after saving the
|
||||
* seed.
|
||||
**********************************************************************/
|
||||
virtual void Reset() throw() = 0;
|
||||
///@}
|
||||
|
||||
/**
|
||||
* \name Static functions for seed management
|
||||
**********************************************************************/
|
||||
///@{
|
||||
/**
|
||||
* Return a 32 bits of data suitable for seeding the random generator. The
|
||||
* result is obtained by combining data from /dev/urandom, gettimeofday,
|
||||
* time, and getpid to provide a reasonably "random" word of data.
|
||||
* Usually, it is safer to seed the random generator with SeedVector()
|
||||
* instead of SeedWord().
|
||||
*
|
||||
* @return a single "more-or-less random" seed_type to be used as a seed.
|
||||
**********************************************************************/
|
||||
static seed_type SeedWord();
|
||||
/**
|
||||
* Return a vector of unsigned longs suitable for seeding the random
|
||||
* generator. The vector is almost certainly unique; however, the results
|
||||
* of successive calls to Random::SeedVector() will be correlated. If
|
||||
* several Random objects are required within a single program execution,
|
||||
* call Random::SeedVector once, print it out (!), push_back additional
|
||||
* data to identify the instance (e.g., loop index, thread ID, etc.), and
|
||||
* use the result to seed the Random object. The number of elements
|
||||
* included in the vector may depend on the operating system. Additional
|
||||
* elements may be added in future versions of this library.
|
||||
*
|
||||
* @return a "unique" vector of seed_type to be uses as a seed.
|
||||
**********************************************************************/
|
||||
static std::vector<seed_type> SeedVector();
|
||||
/**
|
||||
* Convert a vector into a string suitable for printing or as an argument
|
||||
* for Random::Reseed(const std::string& s).
|
||||
*
|
||||
* @tparam IntType the integral type of the elements of the vector.
|
||||
* @param[in] v the vector to be converted.
|
||||
* @return the resulting string.
|
||||
**********************************************************************/
|
||||
template<typename IntType>
|
||||
static std::string VectorToString(const std::vector<IntType>& v) {
|
||||
std::ostringstream os;
|
||||
os << "[";
|
||||
for (typename std::vector<IntType>::const_iterator n = v.begin();
|
||||
n != v.end(); ++n) {
|
||||
if (n != v.begin())
|
||||
os << ",";
|
||||
// Normalize in case this is called by user.
|
||||
os << seed_t::cast(*n);
|
||||
}
|
||||
os << "]";
|
||||
return os.str();
|
||||
}
|
||||
/**
|
||||
* Convert a string into a vector of seed_type suitable for printing or as
|
||||
* an argument for Random::Reseed(const std::vector<seed_type>& v). Reads
|
||||
* consecutive digits in string. Thus "[1,2,3]" => [1,2,3]; "-0.123e-4" =>
|
||||
* [0,123,4], etc. strtoul understands C's notation for octal and
|
||||
* hexadecimal, for example "012 10 0xa" => [10,10,10]. Reading of a
|
||||
* number stops at the first illegal character for the base. Thus
|
||||
* "2006-04-08" => [2006,4,0,8] (i.e., 08 becomes two numbers). Note that
|
||||
* input numbers greater than ULONG_MAX overflow to ULONG_MAX, which
|
||||
* probably will result in the number being interpreted as LONG_MASK.
|
||||
*
|
||||
* @param[in] s the string to be converted.
|
||||
* @return the resulting vector of seed_type.
|
||||
**********************************************************************/
|
||||
static std::vector<seed_type> StringToVector(const std::string& s);
|
||||
///@}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* The seed vector
|
||||
**********************************************************************/
|
||||
std::vector<seed_type> _seed;
|
||||
|
||||
};
|
||||
|
||||
inline RandomSeed::~RandomSeed() throw() {}
|
||||
|
||||
} // namespace RandomLib
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning (pop)
|
||||
#endif
|
||||
|
||||
#endif // RANDOMLIB_RANDOMSEED_HPP
|
@ -1,335 +0,0 @@
|
||||
/**
|
||||
* \file RandomSelect.hpp
|
||||
* \brief Header for RandomSelect.
|
||||
*
|
||||
* An implementation of the Walker algorithm for selecting from a finite set.
|
||||
*
|
||||
* Copyright (c) Charles Karney (2006-2011) <charles@karney.com> and licensed
|
||||
* under the MIT/X11 License. For more information, see
|
||||
* http://randomlib.sourceforge.net/
|
||||
**********************************************************************/
|
||||
|
||||
#if !defined(RANDOMLIB_RANDOMSELECT_HPP)
|
||||
#define RANDOMLIB_RANDOMSELECT_HPP 1
|
||||
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
// Squelch warnings about constant conditional expressions
|
||||
# pragma warning (push)
|
||||
# pragma warning (disable: 4127)
|
||||
#endif
|
||||
|
||||
namespace RandomLib {
|
||||
/**
|
||||
* \brief Random selection from a discrete set.
|
||||
*
|
||||
* An implementation of Walker algorithm for selecting from a finite set
|
||||
* (following Knuth, TAOCP, Vol 2, Sec 3.4.1.A). This provides a rapid way
|
||||
* of selecting one of several choices depending on a discrete set weights.
|
||||
* Original citation is\n A. J. Walker,\n An Efficient Method for Generating
|
||||
* Discrete Random Variables and General Distributions,\n ACM TOMS 3,
|
||||
* 253--256 (1977).
|
||||
*
|
||||
* There are two changes here in the setup algorithm as given by Knuth:
|
||||
*
|
||||
* - The probabilities aren't sorted at the beginning of the setup; nor are
|
||||
* they maintained in a sorted order. Instead they are just partitioned on
|
||||
* the mean. This improves the setup time from O(\e k<sup>2</sup>) to O(\e
|
||||
* k).
|
||||
*
|
||||
* - The internal calculations are carried out with type \e NumericType. If
|
||||
* the input weights are of integer type, then choosing an integer type for
|
||||
* \e NumericType yields an exact solution for the returned distribution
|
||||
* (assuming that the underlying random generator is exact.)
|
||||
*
|
||||
* Example:
|
||||
* \code
|
||||
#include <RandomLib/RandomSelect.hpp>
|
||||
|
||||
// Weights for throwing a pair of dice
|
||||
unsigned w[] = { 0, 0, 1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1 };
|
||||
|
||||
// Initialize selection
|
||||
RandomLib::RandomSelect<unsigned> sel(w, w + 13);
|
||||
|
||||
RandomLib::Random r; // Initialize random numbers
|
||||
std::cout << "Seed set to " << r.SeedString() << "\n";
|
||||
|
||||
std::cout << "Throw a pair of dice 100 times:";
|
||||
for (unsigned i = 0; i < 100; ++i)
|
||||
std::cout << " " << sel(r);
|
||||
std::cout << "\n";
|
||||
\endcode
|
||||
*
|
||||
* @tparam NumericType the numeric type to use (default double).
|
||||
**********************************************************************/
|
||||
template<typename NumericType = double> class RandomSelect {
|
||||
public:
|
||||
/**
|
||||
* Initialize in a cleared state (equivalent to having a single
|
||||
* choice).
|
||||
**********************************************************************/
|
||||
RandomSelect() : _k(0), _wsum(0), _wmax(0) {}
|
||||
|
||||
/**
|
||||
* Initialize with a weight vector \e w of elements of type \e WeightType.
|
||||
* Internal calculations are carried out with type \e NumericType. \e
|
||||
* NumericType needs to allow Choices() * MaxWeight() to be represented.
|
||||
* Sensible combinations are:
|
||||
* - \e WeightType integer, \e NumericType integer with
|
||||
* digits(\e NumericType) ≥ digits(\e WeightType)
|
||||
* - \e WeightType integer, \e NumericType real
|
||||
* - \e WeightType real, \e NumericType real with digits(\e NumericType)
|
||||
* ≥ digits(\e WeightType)
|
||||
*
|
||||
* @tparam WeightType the type of the weights.
|
||||
* @param[in] w the vector of weights.
|
||||
* @exception RandomErr if any of the weights are negative or if the total
|
||||
* weight is not positive.
|
||||
**********************************************************************/
|
||||
template<typename WeightType>
|
||||
RandomSelect(const std::vector<WeightType>& w) { Init(w.begin(), w.end()); }
|
||||
|
||||
/**
|
||||
* Initialize with a weight given by a pair of iterators [\e a, \e b).
|
||||
*
|
||||
* @tparam InputIterator the type of the iterator.
|
||||
* @param[in] a the beginning iterator.
|
||||
* @param[in] b the ending iterator.
|
||||
* @exception RandomErr if any of the weights are negative or if the total
|
||||
* weight is not positive.
|
||||
**********************************************************************/
|
||||
template<typename InputIterator>
|
||||
RandomSelect(InputIterator a, InputIterator b);
|
||||
|
||||
/**
|
||||
* Clear the state (equivalent to having a single choice).
|
||||
**********************************************************************/
|
||||
void Init() throw()
|
||||
{ _k = 0; _wsum = 0; _wmax = 0; _Q.clear(); _Y.clear(); }
|
||||
|
||||
/**
|
||||
* Re-initialize with a weight vector \e w. Leave state unaltered in the
|
||||
* case of an error.
|
||||
*
|
||||
* @tparam WeightType the type of the weights.
|
||||
* @param[in] w the vector of weights.
|
||||
**********************************************************************/
|
||||
template<typename WeightType>
|
||||
void Init(const std::vector<WeightType>& w) { Init(w.begin(), w.end()); }
|
||||
|
||||
/**
|
||||
* Re-initialize with a weight given as a pair of iterators [\e a, \e b).
|
||||
* Leave state unaltered in the case of an error.
|
||||
*
|
||||
* @tparam InputIterator the type of the iterator.
|
||||
* @param[in] a the beginning iterator.
|
||||
* @param[in] b the ending iterator.
|
||||
**********************************************************************/
|
||||
template<typename InputIterator>
|
||||
void Init(InputIterator a, InputIterator b) {
|
||||
RandomSelect<NumericType> t(a, b);
|
||||
_Q.reserve(t._k);
|
||||
_Y.reserve(t._k);
|
||||
*this = t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an index into the weight vector with probability proportional to
|
||||
* the weight.
|
||||
*
|
||||
* @tparam Random the type of RandomCanonical generator.
|
||||
* @param[in,out] r the RandomCanonical generator.
|
||||
* @return the random index into the weight vector.
|
||||
**********************************************************************/
|
||||
template<class Random>
|
||||
unsigned operator()(Random& r) const throw() {
|
||||
if (_k <= 1)
|
||||
return 0; // Special cases
|
||||
const unsigned K = r.template Integer<unsigned>(_k);
|
||||
// redundant casts to type NumericType to prevent warning from MS Project
|
||||
return (std::numeric_limits<NumericType>::is_integer ?
|
||||
r.template Prob<NumericType>(NumericType(_Q[K]),
|
||||
NumericType(_wsum)) :
|
||||
r.template Prob<NumericType>(NumericType(_Q[K]))) ?
|
||||
K : _Y[K];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the sum of the weights.
|
||||
**********************************************************************/
|
||||
NumericType TotalWeight() const throw() { return _wsum; }
|
||||
|
||||
/**
|
||||
* @return the maximum weight.
|
||||
**********************************************************************/
|
||||
NumericType MaxWeight() const throw() { return _wmax; }
|
||||
|
||||
/**
|
||||
* @param[in] i the index in to the weight vector.
|
||||
* @return the weight for sample \e i. Weight(i) / TotalWeight() gives the
|
||||
* probability of sample \e i.
|
||||
**********************************************************************/
|
||||
NumericType Weight(unsigned i) const throw() {
|
||||
if (i >= _k)
|
||||
return NumericType(0);
|
||||
else if (_k == 1)
|
||||
return _wsum;
|
||||
const NumericType n = std::numeric_limits<NumericType>::is_integer ?
|
||||
_wsum : NumericType(1);
|
||||
NumericType p = _Q[i];
|
||||
for (unsigned j = _k; j;)
|
||||
if (_Y[--j] == i)
|
||||
p += n - _Q[j];
|
||||
// If NumericType is integral, then p % _k == 0.
|
||||
// assert(!std::numeric_limits<NumericType>::is_integer || p % _k == 0);
|
||||
return (p / NumericType(_k)) * (_wsum / n);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the number of choices, i.e., the length of the weight vector.
|
||||
**********************************************************************/
|
||||
unsigned Choices() const throw() { return _k; }
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Size of weight vector
|
||||
**********************************************************************/
|
||||
unsigned _k;
|
||||
/**
|
||||
* Vector of cutoffs
|
||||
**********************************************************************/
|
||||
std::vector<NumericType> _Q;
|
||||
/**
|
||||
* Vector of aliases
|
||||
**********************************************************************/
|
||||
std::vector<unsigned> _Y;
|
||||
/**
|
||||
* The sum of the weights
|
||||
**********************************************************************/
|
||||
NumericType _wsum;
|
||||
/**
|
||||
* The maximum weight
|
||||
**********************************************************************/
|
||||
NumericType _wmax;
|
||||
|
||||
};
|
||||
|
||||
template<typename NumericType> template<typename InputIterator>
|
||||
RandomSelect<NumericType>::RandomSelect(InputIterator a, InputIterator b) {
|
||||
|
||||
typedef typename std::iterator_traits<InputIterator>::value_type
|
||||
WeightType;
|
||||
// Disallow WeightType = real, NumericType = integer
|
||||
STATIC_ASSERT(std::numeric_limits<WeightType>::is_integer ||
|
||||
!std::numeric_limits<NumericType>::is_integer,
|
||||
"RandomSelect: inconsistent WeightType and NumericType");
|
||||
|
||||
// If WeightType and NumericType are the same type, NumericType as precise
|
||||
// as WeightType
|
||||
STATIC_ASSERT(std::numeric_limits<WeightType>::is_integer !=
|
||||
std::numeric_limits<NumericType>::is_integer ||
|
||||
std::numeric_limits<NumericType>::digits >=
|
||||
std::numeric_limits<WeightType>::digits,
|
||||
"RandomSelect: NumericType insufficiently precise");
|
||||
|
||||
_wsum = 0;
|
||||
_wmax = 0;
|
||||
std::vector<NumericType> p;
|
||||
|
||||
for (InputIterator wptr = a; wptr != b; ++wptr) {
|
||||
// Test *wptr < 0 without triggering compiler warning when *wptr =
|
||||
// unsigned
|
||||
if (!(*wptr > 0 || *wptr == 0))
|
||||
// This also catches NaNs
|
||||
throw RandomErr("RandomSelect: Illegal weight");
|
||||
NumericType w = NumericType(*wptr);
|
||||
if (w > (std::numeric_limits<NumericType>::max)() - _wsum)
|
||||
throw RandomErr("RandomSelect: Overflow");
|
||||
_wsum += w;
|
||||
_wmax = w > _wmax ? w : _wmax;
|
||||
p.push_back(w);
|
||||
}
|
||||
|
||||
_k = unsigned(p.size());
|
||||
if (_wsum <= 0)
|
||||
throw RandomErr("RandomSelect: Zero total weight");
|
||||
|
||||
if (_k <= 1) {
|
||||
// We treat k <= 1 as a special case in operator()
|
||||
_Q.clear();
|
||||
_Y.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
if ((std::numeric_limits<NumericType>::max)()/NumericType(_k) <
|
||||
NumericType(_wmax))
|
||||
throw RandomErr("RandomSelect: Overflow");
|
||||
|
||||
std::vector<unsigned> j(_k);
|
||||
_Q.resize(_k);
|
||||
_Y.resize(_k);
|
||||
|
||||
// Pointers to the next empty low and high slots
|
||||
unsigned u = 0;
|
||||
unsigned v = _k - 1;
|
||||
|
||||
// Scale input and store in p and setup index array j. Note _wsum =
|
||||
// mean(p). We could scale out _wsum here, but the following is exact when
|
||||
// w[i] are low integers.
|
||||
for (unsigned i = 0; i < _k; ++i) {
|
||||
p[i] *= NumericType(_k);
|
||||
j[p[i] > _wsum ? v-- : u++] = i;
|
||||
}
|
||||
|
||||
// Pointers to the next low and high slots to use. Work towards the
|
||||
// middle. This simplifies the loop exit test to u == v.
|
||||
u = 0;
|
||||
v = _k - 1;
|
||||
|
||||
// For integer NumericType, store the unnormalized probability in _Q and
|
||||
// select using the exact Prob(_Q[k], _wsum). For real NumericType, store
|
||||
// the normalized probability and select using Prob(_Q[k]). There will be
|
||||
// a round off error in performing the division; but there is also the
|
||||
// potential for round off errors in performing the arithmetic on p. There
|
||||
// is therefore no point in simulating the division exactly using the
|
||||
// slower Prob(real, real).
|
||||
const NumericType n = std::numeric_limits<NumericType>::is_integer ?
|
||||
NumericType(1) : _wsum;
|
||||
|
||||
while (true) {
|
||||
// A loop invariant here is mean(p[j[u..v]]) == _wsum
|
||||
_Q[j[u]] = p[j[u]] / n;
|
||||
|
||||
// If all arithmetic were exact this assignment could be:
|
||||
// if (p[j[u]] < _wsum) _Y[j[u]] = j[v];
|
||||
// But the following is safer:
|
||||
_Y[j[u]] = j[p[j[u]] < _wsum ? v : u];
|
||||
|
||||
if (u == v) {
|
||||
// The following assertion may fail because of roundoff errors
|
||||
// assert( p[j[u]] == _wsum );
|
||||
break;
|
||||
}
|
||||
|
||||
// Update p, u, and v maintaining the loop invariant
|
||||
p[j[v]] = p[j[v]] - (_wsum - p[j[u]]);
|
||||
if (p[j[v]] > _wsum)
|
||||
++u;
|
||||
else
|
||||
j[u] = j[v--];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
} // namespace RandomLib
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning (pop)
|
||||
#endif
|
||||
|
||||
#endif // RANDOMLIB_RANDOMSELECT_HPP
|
@ -1,137 +0,0 @@
|
||||
/**
|
||||
* \file RandomType.hpp
|
||||
* \brief Class to hold bit-width and unsigned type
|
||||
*
|
||||
* This provides a simple class to couple a bit-width and an unsigned type
|
||||
* capable of holding all the bits. In addition is offers static methods for
|
||||
* I/O and checksumming.
|
||||
*
|
||||
* Copyright (c) Charles Karney (2006-2011) <charles@karney.com> and licensed
|
||||
* under the MIT/X11 License. For more information, see
|
||||
* http://randomlib.sourceforge.net/
|
||||
**********************************************************************/
|
||||
#if !defined(RANDOMLIB_RANDOMTYPE_HPP)
|
||||
#define RANDOMLIB_RANDOMTYPE_HPP 1
|
||||
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
namespace RandomLib {
|
||||
/**
|
||||
* \brief Class to hold bit-width and unsigned type
|
||||
*
|
||||
* This provides a simple class to couple a bit-width and an unsigned type
|
||||
* capable of holding all the bits. In addition is offers static methods for
|
||||
* I/O and checksumming.
|
||||
*
|
||||
* @tparam bits the number of significant bits.
|
||||
* @tparam UIntType the C++ unsigned integer type capable of holding the bits.
|
||||
**********************************************************************/
|
||||
template<int bits, typename UIntType>
|
||||
class RANDOMLIB_EXPORT RandomType {
|
||||
public:
|
||||
/**
|
||||
* The unsigned C++ type
|
||||
**********************************************************************/
|
||||
typedef UIntType type;
|
||||
/**
|
||||
* The number of significant bits
|
||||
**********************************************************************/
|
||||
static const unsigned width = bits;
|
||||
/**
|
||||
* A mask for the significant bits.
|
||||
**********************************************************************/
|
||||
static const type mask =
|
||||
~type(0) >> (std::numeric_limits<type>::digits - width);
|
||||
/**
|
||||
* The minimum representable value
|
||||
**********************************************************************/
|
||||
static const type min = type(0);
|
||||
/**
|
||||
* The maximum representable value
|
||||
**********************************************************************/
|
||||
static const type max = mask;
|
||||
/**
|
||||
* A combined masking and casting operation
|
||||
*
|
||||
* @tparam IntType the integer type of the \e x.
|
||||
* @param[in] x the input integer.
|
||||
* @return the masked and casted result.
|
||||
**********************************************************************/
|
||||
template<typename IntType> static type cast(IntType x) throw()
|
||||
{ return type(x) & mask; }
|
||||
/**
|
||||
* Read a data value from a stream of 32-bit quantities (binary or text)
|
||||
*
|
||||
* @param[in,out] is the input stream.
|
||||
* @param[in] bin true if the stream is binary.
|
||||
* @param[out] x the data value read from the stream.
|
||||
**********************************************************************/
|
||||
static void Read32(std::istream& is, bool bin, type& x);
|
||||
/**
|
||||
* Write the data value to a stream of 32-bit quantities (binary or text)
|
||||
*
|
||||
* @param[in,out] os the output stream.
|
||||
* @param[in] bin true if the stream is binary.
|
||||
* @param[in,out] cnt controls the use of spaces and newlines for text
|
||||
* output.
|
||||
* @param[in] x the data value to be written to the stream.
|
||||
*
|
||||
* \e cnt should be zero on the first invocation of a series of writes.
|
||||
* This function increments it by one on each call.
|
||||
**********************************************************************/
|
||||
static void Write32(std::ostream& os, bool bin, int& cnt, type x);
|
||||
/**
|
||||
* Accumulate a checksum of a integer into a 32-bit check. This implements
|
||||
* a very simple checksum and is intended to avoid accidental corruption
|
||||
* only.
|
||||
*
|
||||
* @param[in] n the number to be included in the checksum.
|
||||
* @param[in,out] check the running checksum.
|
||||
**********************************************************************/
|
||||
static void CheckSum(type n, uint32_t& check) throw();
|
||||
};
|
||||
|
||||
/**
|
||||
* The standard unit for 32-bit quantities
|
||||
**********************************************************************/
|
||||
typedef RandomType<32, uint32_t> Random_u32;
|
||||
/**
|
||||
* The standard unit for 64-bit quantities
|
||||
**********************************************************************/
|
||||
typedef RandomType<64, uint64_t> Random_u64;
|
||||
|
||||
/**
|
||||
* The integer type of constructing bitsets. This used to be unsigned long.
|
||||
* C++11 has made this unsigned long long.
|
||||
**********************************************************************/
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1600
|
||||
typedef unsigned long long bitset_uint_t;
|
||||
#else
|
||||
typedef unsigned long bitset_uint_t;
|
||||
#endif
|
||||
|
||||
/// \cond SKIP
|
||||
|
||||
// Accumulate a checksum of a 32-bit quantity into check
|
||||
template<>
|
||||
inline void Random_u32::CheckSum(Random_u32::type n, Random_u32::type& check)
|
||||
throw() {
|
||||
// Circular shift left by one bit and add new word.
|
||||
check = (check << 1 | (check >> 31 & Random_u32::type(1))) + n;
|
||||
check &= Random_u32::mask;
|
||||
}
|
||||
|
||||
// Accumulate a checksum of a 64-bit quantity into check
|
||||
template<>
|
||||
inline void Random_u64::CheckSum(Random_u64::type n, Random_u32::type& check)
|
||||
throw() {
|
||||
Random_u32::CheckSum(Random_u32::cast(n >> 32), check);
|
||||
Random_u32::CheckSum(Random_u32::cast(n ), check);
|
||||
}
|
||||
/// \endcond
|
||||
|
||||
} // namespace RandomLib
|
||||
|
||||
#endif // RANDOMLIB_RANDOMTYPE_HPP
|
@ -1,253 +0,0 @@
|
||||
/**
|
||||
* \file UniformInteger.hpp
|
||||
* \brief Header for UniformInteger
|
||||
*
|
||||
* Partially sample a uniform integer distribution.
|
||||
*
|
||||
* Copyright (c) Charles Karney (2013) <charles@karney.com> and licensed
|
||||
* under the MIT/X11 License. For more information, see
|
||||
* http://randomlib.sourceforge.net/
|
||||
**********************************************************************/
|
||||
|
||||
#if !defined(RANDOMLIB_UNIFORMINTEGER_HPP)
|
||||
#define RANDOMLIB_UNIFORMINTEGER_HPP 1
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace RandomLib {
|
||||
/**
|
||||
* \brief The partial uniform integer distribution.
|
||||
*
|
||||
* A class to sample in [0, \e m). For background, see:
|
||||
* - D. E. Knuth and A. C. Yao, The Complexity of Nonuniform Random Number
|
||||
* Generation, in "Algorithms and Complexity" (Academic Press, 1976),
|
||||
* pp. 357--428.
|
||||
* - J. Lumbroso, Optimal Discrete Uniform Generation from Coin Flips,
|
||||
* and Applications, http://arxiv.org/abs/1304.1916 (2013)
|
||||
* .
|
||||
* Lumbroso's algorithm is a realization of the Knuth-Yao method for the case
|
||||
* of uniform probabilities. This class generalizes the method to accept
|
||||
* random digits in a base, \e b = 2<sup>\e bits</sup>. An important
|
||||
* additional feature is that only sufficient random digits are drawn to
|
||||
* narrow the allowed range to a power of b. Thus after
|
||||
* <code>UniformInteger<int,1> u(r,5)</code>, \e u represents \verbatim
|
||||
range prob
|
||||
[0,4) 8/15
|
||||
[0,2) 2/15
|
||||
[2,4) 2/15
|
||||
4 1/5 \endverbatim
|
||||
* <code>u.Min()</code> and <code>u.Max()</code> give the extent of the
|
||||
* closed range. The number of additional random digits needed to fix the
|
||||
* value is given by <code>u.Entropy()</code>. The comparison operations may
|
||||
* require additional digits to be drawn and so the range might be narrowed
|
||||
* down. If you need a definite value then use <code>u(r)</code>.
|
||||
*
|
||||
* The DiscreteNormalAlt class uses UniformInteger to achieve an
|
||||
* asymptotically ideal scaling wherein the number of random bits required
|
||||
* per sample is constant + log<sub>2</sub>σ. If Lumbroso's algorithm
|
||||
* for sampling in [0,\e m) were used the log<sub>2</sub>σ term would
|
||||
* be multiplied by about 1.4.
|
||||
*
|
||||
* It is instructive to look at the Knuth-Yao discrete distribution
|
||||
* generating (DDG) tree for the case \e m = 5 (the binary expansion of 1/5
|
||||
* is 0.00110011...); Lumbroso's algorithm implements this tree.
|
||||
* \image html ky-5.png "Knuth-Yao for \e m = 5"
|
||||
*
|
||||
* UniformInteger collapses all of the full subtrees above to their parent
|
||||
* nodes to yield this tree where now some of the outcomes are ranges.
|
||||
* \image html ky-5-collapse.png "Collapsed Knuth-Yao for \e m = 5"
|
||||
*
|
||||
* Averaging over many samples, the maximum number of digits required to
|
||||
* construct a UniformInteger, i.e., invoking
|
||||
* <code>UniformInteger(r,m)</code>, is (2\e b − 1)/(\e b − 1).
|
||||
* (Note that this does not increase as \e m increases.) The maximum number
|
||||
* of digits required to sample specific integers, i.e., invoking
|
||||
* <code>UniformInteger(r,m)(r)</code>, is <i>b</i>/(\e b − 1) +
|
||||
* log<sub>\e b</sub>\e m. The worst cases are when \e m is slightly more
|
||||
* than a power of \e b.
|
||||
*
|
||||
* The number of random bits required for sampling is shown as a function of
|
||||
* the fractional part of log<sub>2</sub>\e m below. The red line shows what
|
||||
* Lumbroso calls the "toll", the number of bits in excess of the entropy
|
||||
* that are required for sampling.
|
||||
* \image html
|
||||
* uniform-bits.png "Random bits to sample in [0,\e m) for \e b = 2"
|
||||
*
|
||||
* @tparam IntType the type of the integer (must be signed).
|
||||
* @tparam bits the number of bits in each digit used for sampling;
|
||||
* the base for sampling is \e b = 2<sup>\e bits</sup>.
|
||||
**********************************************************************/
|
||||
template<typename IntType = int, int bits = 1> class UniformInteger {
|
||||
public:
|
||||
/**
|
||||
* Constructor creating a partially sampled integer in [0, \e m)
|
||||
*
|
||||
* @param[in] r random object.
|
||||
* @param[in] m constructed object represents an integer in [0, \e m).
|
||||
* @param[in] flip if true, rearrange the ranges so that the widest ones
|
||||
* are at near the upper end of [0, \e m) (default false).
|
||||
*
|
||||
* The samples enough random digits to obtain a uniform range whose size is
|
||||
* a power of the base. The range can subsequently be narrowed by sampling
|
||||
* additional digits.
|
||||
**********************************************************************/
|
||||
template<class Random>
|
||||
UniformInteger(Random& r, IntType m, bool flip = false);
|
||||
/**
|
||||
* @return the minimum of the current range.
|
||||
**********************************************************************/
|
||||
IntType Min() const { return _a; }
|
||||
/**
|
||||
* @return the maximum of the current range.
|
||||
**********************************************************************/
|
||||
IntType Max() const { return _a + (IntType(1) << (_l * bits)) - 1; }
|
||||
/**
|
||||
* @return the entropy of the current range (in units of random digits).
|
||||
*
|
||||
* Max() + 1 - Min() = 2<sup>Entropy() * \e bits</sup>.
|
||||
**********************************************************************/
|
||||
IntType Entropy() const { return _l; }
|
||||
/**
|
||||
* Sample until the entropy vanishes, i.e., Min() = Max().
|
||||
*
|
||||
* @return the resulting integer sample.
|
||||
**********************************************************************/
|
||||
template<class Random> IntType operator()(Random& r)
|
||||
{ while (_l) Refine(r); return _a; }
|
||||
/**
|
||||
* Negate the range, [Min(), Max()] → [−Max(), −Min()].
|
||||
**********************************************************************/
|
||||
void Negate() { _a = -Max(); }
|
||||
/**
|
||||
* Add a constant to the range
|
||||
*
|
||||
* @param[in] c the constant to be added.
|
||||
*
|
||||
* [Min(), Max()] → [Min() + \e c, Max() + \e c].
|
||||
**********************************************************************/
|
||||
void Add(IntType c) { _a += c; }
|
||||
/**
|
||||
* Compare with a fraction, *this < <i>p</i>/<i>q</i>
|
||||
*
|
||||
* @tparam Random the type of the random generator.
|
||||
* @param[in,out] r a random generator.
|
||||
* @param[in] p the numerator of the fraction.
|
||||
* @param[in] q the denominator of the fraction (require \e q > 0).
|
||||
* @return true if *this < <i>p</i>/<i>q</i>.
|
||||
**********************************************************************/
|
||||
// test j < p/q (require q > 0)
|
||||
template<class Random> bool LessThan(Random& r, IntType p, IntType q) {
|
||||
for (;;) {
|
||||
if ( (q * Max() < p)) return true;
|
||||
if (!(q * Min() < p)) return false;
|
||||
Refine(r);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Compare with a fraction, *this ≤ <i>p</i>/<i>q</i>
|
||||
*
|
||||
* @tparam Random the type of the random generator.
|
||||
* @param[in,out] r a random generator.
|
||||
* @param[in] p the numerator of the fraction.
|
||||
* @param[in] q the denominator of the fraction (require \e q > 0).
|
||||
* @return true if *this ≤ <i>p</i>/<i>q</i>.
|
||||
**********************************************************************/
|
||||
template<class Random>
|
||||
bool LessThanEqual(Random& r, IntType p, IntType q)
|
||||
{ return LessThan(r, p + 1, q); }
|
||||
/**
|
||||
* Compare with a fraction, *this > <i>p</i>/<i>q</i>
|
||||
*
|
||||
* @tparam Random the type of the random generator.
|
||||
* @param[in,out] r a random generator.
|
||||
* @param[in] p the numerator of the fraction.
|
||||
* @param[in] q the denominator of the fraction (require \e q > 0).
|
||||
* @return true if *this > <i>p</i>/<i>q</i>.
|
||||
**********************************************************************/
|
||||
template<class Random>
|
||||
bool GreaterThan(Random& r, IntType p, IntType q)
|
||||
{ return !LessThanEqual(r, p, q); }
|
||||
/**
|
||||
* Compare with a fraction, *this ≥ <i>p</i>/<i>q</i>
|
||||
*
|
||||
* @tparam Random the type of the random generator.
|
||||
* @param[in,out] r a random generator.
|
||||
* @param[in] p the numerator of the fraction.
|
||||
* @param[in] q the denominator of the fraction (require \e q > 0).
|
||||
* @return true if *this ≥ <i>p</i>/<i>q</i>.
|
||||
**********************************************************************/
|
||||
template<class Random>
|
||||
bool GreaterThanEqual(Random& r, IntType p, IntType q)
|
||||
{ return !LessThan(r, p, q); }
|
||||
/**
|
||||
* Check that overflow will not happen.
|
||||
*
|
||||
* @param[in] mmax the largest \e m in the constructor.
|
||||
* @param[in] qmax the largest \e q in LessThan().
|
||||
* @return true if overflow will not happen.
|
||||
*
|
||||
* It is important that this check be carried out. If overflow occurs,
|
||||
* incorrect results are obtained and the constructor may never terminate.
|
||||
**********************************************************************/
|
||||
static bool Check(IntType mmax, IntType qmax) {
|
||||
return ( mmax - 1 <= ((std::numeric_limits<IntType>::max)() >> bits) &&
|
||||
mmax - 1 <= (std::numeric_limits<IntType>::max)() / qmax );
|
||||
}
|
||||
private:
|
||||
IntType _a, _l; // current range is _a + [0, 2^(bits*_l)).
|
||||
template<class Random> static unsigned RandomDigit(Random& r) throw()
|
||||
{ return unsigned(r.template Integer<bits>()); }
|
||||
template<class Random> void Refine(Random& r) // only gets called if _l > 0.
|
||||
{ _a += IntType(RandomDigit(r) << (bits * --_l)); }
|
||||
};
|
||||
|
||||
template<typename IntType, int bits> template<class Random>
|
||||
UniformInteger<IntType, bits>::UniformInteger(Random& r, IntType m, bool flip)
|
||||
{
|
||||
STATIC_ASSERT(std::numeric_limits<IntType>::is_integer,
|
||||
"UniformInteger: invalid integer type IntType");
|
||||
STATIC_ASSERT(std::numeric_limits<IntType>::is_signed,
|
||||
"UniformInteger: IntType must be a signed type");
|
||||
STATIC_ASSERT(bits > 0 && bits < std::numeric_limits<IntType>::digits &&
|
||||
bits <= std::numeric_limits<unsigned>::digits,
|
||||
"UniformInteger: bits out of range");
|
||||
m = m < 1 ? 1 : m;
|
||||
for (IntType v = 1, c = 0;;) {
|
||||
_l = 0; _a = c;
|
||||
for (IntType w = v, a = c, d = 1;;) {
|
||||
// play out Lumbroso's algorithm without drawing random digits with w
|
||||
// playing the role of v and c represented by the range [a, a + d).
|
||||
// Return if both ends of range qualify as return values at the same
|
||||
// time. Otherwise, fail and draw another random digit.
|
||||
if (w >= m) {
|
||||
IntType j = (a / m) * m; a -= j; w -= j;
|
||||
if (w >= m) {
|
||||
if (a + d <= m) { _a = !flip ? a : m - a - d; return; }
|
||||
break;
|
||||
}
|
||||
}
|
||||
w <<= bits; a <<= bits; d <<= bits; ++_l;
|
||||
}
|
||||
IntType j = (v / m) * m; v -= j; c -= j;
|
||||
v <<= bits; c <<= bits; c += IntType(RandomDigit(r));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \relates UniformInteger
|
||||
* Print a UniformInteger. Format is [\e min,\e max] unless the entropy is
|
||||
* zero, in which case it's \e val.
|
||||
**********************************************************************/
|
||||
template<typename IntType, int bits>
|
||||
std::ostream& operator<<(std::ostream& os,
|
||||
const UniformInteger<IntType, bits>& u) {
|
||||
if (u.Entropy())
|
||||
os << "[" << u.Min() << "," << u.Max() << "]";
|
||||
else
|
||||
os << u.Min();
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace RandomLib
|
||||
|
||||
#endif // RANDOMLIB_UNIFORMINTEGER_HPP
|
42
include/aes256.h
Normal file
42
include/aes256.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Byte-oriented AES-256 implementation.
|
||||
* All lookup tables replaced with 'on the fly' calculations.
|
||||
*
|
||||
* Copyright (c) 2007-2009 Ilya O. Levin, http://www.literatecode.com
|
||||
* Other contributors: Hal Finney
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifndef uint8_t
|
||||
#define uint8_t unsigned char
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint8_t key[32];
|
||||
uint8_t enckey[32];
|
||||
uint8_t deckey[32];
|
||||
} aes256_context;
|
||||
|
||||
|
||||
void aes256_init(aes256_context *, uint8_t * /* key */);
|
||||
void aes256_done(aes256_context *);
|
||||
void aes256_encrypt_ecb(aes256_context *, uint8_t * /* plaintext */);
|
||||
void aes256_decrypt_ecb(aes256_context *, uint8_t * /* cipertext */);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
223
include/maxminddb.h
Normal file
223
include/maxminddb.h
Normal file
@ -0,0 +1,223 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef MAXMINDDB_H
|
||||
#define MAXMINDDB_H
|
||||
|
||||
#ifndef _POSIX_C_SOURCE
|
||||
#define _POSIX_C_SOURCE 200112L
|
||||
#endif
|
||||
|
||||
#include <maxminddb_config.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
/* libmaxminddb package version from configure */
|
||||
#define PACKAGE_VERSION "1.1.4"
|
||||
|
||||
typedef ADDRESS_FAMILY sa_family_t;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
/* MSVC doesn't define signed size_t, copy it from configure */
|
||||
#define ssize_t int
|
||||
|
||||
/* MSVC doesn't support restricted pointers */
|
||||
#define restrict
|
||||
#endif
|
||||
#else
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#define MMDB_DATA_TYPE_EXTENDED (0)
|
||||
#define MMDB_DATA_TYPE_POINTER (1)
|
||||
#define MMDB_DATA_TYPE_UTF8_STRING (2)
|
||||
#define MMDB_DATA_TYPE_DOUBLE (3)
|
||||
#define MMDB_DATA_TYPE_BYTES (4)
|
||||
#define MMDB_DATA_TYPE_UINT16 (5)
|
||||
#define MMDB_DATA_TYPE_UINT32 (6)
|
||||
#define MMDB_DATA_TYPE_MAP (7)
|
||||
#define MMDB_DATA_TYPE_INT32 (8)
|
||||
#define MMDB_DATA_TYPE_UINT64 (9)
|
||||
#define MMDB_DATA_TYPE_UINT128 (10)
|
||||
#define MMDB_DATA_TYPE_ARRAY (11)
|
||||
#define MMDB_DATA_TYPE_CONTAINER (12)
|
||||
#define MMDB_DATA_TYPE_END_MARKER (13)
|
||||
#define MMDB_DATA_TYPE_BOOLEAN (14)
|
||||
#define MMDB_DATA_TYPE_FLOAT (15)
|
||||
|
||||
/* flags for open */
|
||||
#define MMDB_MODE_MMAP (1)
|
||||
#define MMDB_MODE_MASK (7)
|
||||
|
||||
/* error codes */
|
||||
#define MMDB_SUCCESS (0)
|
||||
#define MMDB_FILE_OPEN_ERROR (1)
|
||||
#define MMDB_CORRUPT_SEARCH_TREE_ERROR (2)
|
||||
#define MMDB_INVALID_METADATA_ERROR (3)
|
||||
#define MMDB_IO_ERROR (4)
|
||||
#define MMDB_OUT_OF_MEMORY_ERROR (5)
|
||||
#define MMDB_UNKNOWN_DATABASE_FORMAT_ERROR (6)
|
||||
#define MMDB_INVALID_DATA_ERROR (7)
|
||||
#define MMDB_INVALID_LOOKUP_PATH_ERROR (8)
|
||||
#define MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR (9)
|
||||
#define MMDB_INVALID_NODE_NUMBER_ERROR (10)
|
||||
#define MMDB_IPV6_LOOKUP_IN_IPV4_DATABASE_ERROR (11)
|
||||
|
||||
#if !(MMDB_UINT128_IS_BYTE_ARRAY)
|
||||
#if MMDB_UINT128_USING_MODE
|
||||
typedef unsigned int mmdb_uint128_t __attribute__ ((__mode__(TI)));
|
||||
#else
|
||||
typedef unsigned __int128 mmdb_uint128_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* This is a pointer into the data section for a given IP address lookup */
|
||||
typedef struct MMDB_entry_s {
|
||||
struct MMDB_s *mmdb;
|
||||
uint32_t offset;
|
||||
} MMDB_entry_s;
|
||||
|
||||
typedef struct MMDB_lookup_result_s {
|
||||
bool found_entry;
|
||||
MMDB_entry_s entry;
|
||||
uint16_t netmask;
|
||||
} MMDB_lookup_result_s;
|
||||
|
||||
typedef struct MMDB_entry_data_s {
|
||||
bool has_data;
|
||||
union {
|
||||
uint32_t pointer;
|
||||
const char *utf8_string;
|
||||
double double_value;
|
||||
const uint8_t *bytes;
|
||||
uint16_t uint16;
|
||||
uint32_t uint32;
|
||||
int32_t int32;
|
||||
uint64_t uint64;
|
||||
#if MMDB_UINT128_IS_BYTE_ARRAY
|
||||
uint8_t uint128[16];
|
||||
#else
|
||||
mmdb_uint128_t uint128;
|
||||
#endif
|
||||
bool boolean;
|
||||
float float_value;
|
||||
};
|
||||
/* This is a 0 if a given entry cannot be found. This can only happen
|
||||
* when a call to MMDB_(v)get_value() asks for hash keys or array
|
||||
* indices that don't exist. */
|
||||
uint32_t offset;
|
||||
/* This is the next entry in the data section, but it's really only
|
||||
* relevant for entries that part of a larger map or array
|
||||
* struct. There's no good reason for an end user to look at this
|
||||
* directly. */
|
||||
uint32_t offset_to_next;
|
||||
/* This is only valid for strings, utf8_strings or binary data */
|
||||
uint32_t data_size;
|
||||
/* This is an MMDB_DATA_TYPE_* constant */
|
||||
uint32_t type;
|
||||
} MMDB_entry_data_s;
|
||||
|
||||
/* This is the return type when someone asks for all the entry data in a map or array */
|
||||
typedef struct MMDB_entry_data_list_s {
|
||||
MMDB_entry_data_s entry_data;
|
||||
struct MMDB_entry_data_list_s *next;
|
||||
} MMDB_entry_data_list_s;
|
||||
|
||||
typedef struct MMDB_description_s {
|
||||
const char *language;
|
||||
const char *description;
|
||||
} MMDB_description_s;
|
||||
|
||||
typedef struct MMDB_metadata_s {
|
||||
uint32_t node_count;
|
||||
uint16_t record_size;
|
||||
uint16_t ip_version;
|
||||
const char *database_type;
|
||||
struct {
|
||||
size_t count;
|
||||
const char **names;
|
||||
} languages;
|
||||
uint16_t binary_format_major_version;
|
||||
uint16_t binary_format_minor_version;
|
||||
uint64_t build_epoch;
|
||||
struct {
|
||||
size_t count;
|
||||
MMDB_description_s **descriptions;
|
||||
} description;
|
||||
} MMDB_metadata_s;
|
||||
|
||||
typedef struct MMDB_ipv4_start_node_s {
|
||||
uint16_t netmask;
|
||||
uint32_t node_value;
|
||||
} MMDB_ipv4_start_node_s;
|
||||
|
||||
typedef struct MMDB_s {
|
||||
uint32_t flags;
|
||||
const char *filename;
|
||||
ssize_t file_size;
|
||||
const uint8_t *file_content;
|
||||
const uint8_t *data_section;
|
||||
uint32_t data_section_size;
|
||||
const uint8_t *metadata_section;
|
||||
uint32_t metadata_section_size;
|
||||
uint16_t full_record_byte_size;
|
||||
uint16_t depth;
|
||||
MMDB_ipv4_start_node_s ipv4_start_node;
|
||||
MMDB_metadata_s metadata;
|
||||
} MMDB_s;
|
||||
|
||||
typedef struct MMDB_search_node_s {
|
||||
uint64_t left_record;
|
||||
uint64_t right_record;
|
||||
} MMDB_search_node_s;
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
/* --prototypes automatically generated by dev-bin/regen-prototypes.pl - don't remove this comment */
|
||||
extern int MMDB_open(const char *const filename, uint32_t flags, MMDB_s *const mmdb);
|
||||
extern MMDB_lookup_result_s MMDB_lookup_string(MMDB_s *const mmdb,
|
||||
const char *const ipstr,
|
||||
int *const gai_error,
|
||||
int *const mmdb_error);
|
||||
extern MMDB_lookup_result_s MMDB_lookup_sockaddr(
|
||||
MMDB_s *const mmdb,
|
||||
const struct sockaddr *const sockaddr,
|
||||
int *const mmdb_error);
|
||||
extern int MMDB_read_node(MMDB_s *const mmdb, uint32_t node_number,
|
||||
MMDB_search_node_s *const node);
|
||||
extern int MMDB_get_value(MMDB_entry_s *const start,
|
||||
MMDB_entry_data_s *const entry_data,
|
||||
...);
|
||||
extern int MMDB_vget_value(MMDB_entry_s *const start,
|
||||
MMDB_entry_data_s *const entry_data,
|
||||
va_list va_path);
|
||||
extern int MMDB_aget_value(MMDB_entry_s *const start,
|
||||
MMDB_entry_data_s *const entry_data,
|
||||
const char *const *const path);
|
||||
extern int MMDB_get_metadata_as_entry_data_list(
|
||||
MMDB_s *const mmdb, MMDB_entry_data_list_s **const entry_data_list);
|
||||
extern int MMDB_get_entry_data_list(
|
||||
MMDB_entry_s *start, MMDB_entry_data_list_s **const entry_data_list);
|
||||
extern void MMDB_free_entry_data_list(MMDB_entry_data_list_s *const entry_data_list);
|
||||
extern void MMDB_close(MMDB_s *const mmdb);
|
||||
extern const char *MMDB_lib_version(void);
|
||||
extern int MMDB_dump_entry_data_list(FILE *const stream,
|
||||
MMDB_entry_data_list_s *const entry_data_list,
|
||||
int indent);
|
||||
extern const char *MMDB_strerror(int error_code);
|
||||
/* --prototypes end - don't remove this comment-- */
|
||||
/* *INDENT-ON* */
|
||||
|
||||
#endif /* MAXMINDDB_H */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -33,7 +33,7 @@ Int32 Document::Cmp(const Document & o) const
|
||||
{
|
||||
if (m_Doc == o.m_Doc)
|
||||
return 0;
|
||||
else if (this > &o)
|
||||
else if (m_Doc.m_Ptr > o.m_Doc.m_Ptr)
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
|
@ -109,14 +109,6 @@ public:
|
||||
return m_Doc;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether any data has been loaded into this document.
|
||||
*/
|
||||
bool IsEmpty() const
|
||||
{
|
||||
return m_Doc->IsEmpty();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Return the number of active references to this document instance.
|
||||
*/
|
||||
@ -125,6 +117,14 @@ public:
|
||||
return m_Doc.Count();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether any data has been loaded into this document.
|
||||
*/
|
||||
bool IsEmpty() const
|
||||
{
|
||||
return m_Doc->IsEmpty();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Deallocate all memory stored by this document.
|
||||
*/
|
||||
|
@ -18,7 +18,7 @@ Int32 Entries::Cmp(const Entries & o) const
|
||||
{
|
||||
if (m_Elem == o.m_Elem)
|
||||
return 0;
|
||||
else if (this > &o)
|
||||
else if (m_List.size() > o.m_List.size())
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
|
120
modules/mmdb/Common.cpp
Normal file
120
modules/mmdb/Common.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Common.hpp"
|
||||
#include "Module.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <cfloat>
|
||||
#include <climits>
|
||||
#include <cstdlib>
|
||||
#include <cstdarg>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <sqrat.h>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static SQChar g_Buffer[4096]; // Common buffer to reduce memory allocations.
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SStr GetTempBuff()
|
||||
{
|
||||
return g_Buffer;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Uint32 GetTempBuffSize()
|
||||
{
|
||||
return sizeof(g_Buffer);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void SqThrowF(CSStr str, ...)
|
||||
{
|
||||
// Initialize the argument list
|
||||
va_list args;
|
||||
va_start (args, str);
|
||||
// Write the requested contents
|
||||
if (snprintf(g_Buffer, sizeof(g_Buffer), str, args) < 0)
|
||||
strcpy(g_Buffer, "Unknown error has occurred");
|
||||
// Release the argument list
|
||||
va_end(args);
|
||||
// Throw the exception with the resulted message
|
||||
throw Sqrat::Exception(g_Buffer);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr FmtStr(CSStr str, ...)
|
||||
{
|
||||
// Initialize the argument list
|
||||
va_list args;
|
||||
va_start (args, str);
|
||||
// Write the requested contents
|
||||
if (snprintf(g_Buffer, sizeof(g_Buffer), str, args) < 0)
|
||||
g_Buffer[0] = 0; /* make sure the string is terminated */
|
||||
// Release the argument list
|
||||
va_end(args);
|
||||
// Return the data from the buffer
|
||||
return g_Buffer;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
StackGuard::StackGuard(HSQUIRRELVM vm)
|
||||
: m_Top(sq_gettop(vm)), m_VM(vm)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
StackGuard::~StackGuard()
|
||||
{
|
||||
sq_pop(m_VM, sq_gettop(m_VM) - m_Top);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
DbRef::Pointer DbRef::Create()
|
||||
{
|
||||
return reinterpret_cast< Pointer >(malloc(sizeof(Type)));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void DbRef::Destroy(Pointer db)
|
||||
{
|
||||
if (db)
|
||||
free(db);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const char NumLimit< char >::Min = CHAR_MIN;
|
||||
const signed char NumLimit< signed char >::Min = SCHAR_MIN;
|
||||
const unsigned char NumLimit< unsigned char >::Min = 0;
|
||||
const signed short NumLimit< signed short >::Min = SHRT_MIN;
|
||||
const unsigned short NumLimit< unsigned short >::Min = 0;
|
||||
const signed int NumLimit< signed int >::Min = INT_MIN;
|
||||
const unsigned int NumLimit< unsigned int >::Min = 0;
|
||||
const signed long NumLimit< signed long >::Min = LONG_MIN;
|
||||
const unsigned long NumLimit< unsigned long >::Min = 0;
|
||||
const signed long long NumLimit< signed long long >::Min = LLONG_MIN;
|
||||
const unsigned long long NumLimit< unsigned long long >::Min = 0;
|
||||
const float NumLimit< float >::Min = FLT_MIN;
|
||||
const double NumLimit< double >::Min = DBL_MIN;
|
||||
const long double NumLimit< long double >::Min = LDBL_MIN;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const char NumLimit< char >::Max = CHAR_MAX;
|
||||
const signed char NumLimit< signed char >::Max = SCHAR_MAX;
|
||||
const unsigned char NumLimit< unsigned char >::Max = UCHAR_MAX;
|
||||
const signed short NumLimit< signed short >::Max = SHRT_MAX;
|
||||
const unsigned short NumLimit< unsigned short >::Max = USHRT_MAX;
|
||||
const signed int NumLimit< signed int >::Max = INT_MAX;
|
||||
const unsigned int NumLimit< unsigned int >::Max = UINT_MAX;
|
||||
const signed long NumLimit< signed long >::Max = LONG_MAX;
|
||||
const unsigned long NumLimit< unsigned long >::Max = ULONG_MAX;
|
||||
const signed long long NumLimit< signed long long >::Max = LLONG_MAX;
|
||||
const unsigned long long NumLimit< unsigned long long >::Max = ULLONG_MAX;
|
||||
const float NumLimit< float >::Max = FLT_MAX;
|
||||
const double NumLimit< double >::Max = DBL_MAX;
|
||||
const long double NumLimit< long double >::Max = LDBL_MAX;
|
||||
|
||||
} // Namespace:: SqMod
|
453
modules/mmdb/Common.hpp
Normal file
453
modules/mmdb/Common.hpp
Normal file
@ -0,0 +1,453 @@
|
||||
#ifndef _SQMMDB_COMMON_HPP_
|
||||
#define _SQMMDB_COMMON_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "ModBase.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <maxminddb.h>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* SOFTWARE INFORMATION
|
||||
*/
|
||||
#define SQMMDB_NAME "Squirrel MaxmindDB Module"
|
||||
#define SQMMDB_AUTHOR "Sandu Liviu Catalin (S.L.C)"
|
||||
#define SQMMDB_COPYRIGHT "Copyright (C) 2016 Sandu Liviu Catalin"
|
||||
#define SQMMDB_HOST_NAME "SqModMMDBHost"
|
||||
#define SQMMDB_VERSION 001
|
||||
#define SQMMDB_VERSION_STR "0.0.1"
|
||||
#define SQMMDB_VERSION_MAJOR 0
|
||||
#define SQMMDB_VERSION_MINOR 0
|
||||
#define SQMMDB_VERSION_PATCH 1
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Forward declarations.
|
||||
*/
|
||||
class Database;
|
||||
class SockAddr;
|
||||
class EntryDataList;
|
||||
class LookupResult;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the temporary buffer.
|
||||
*/
|
||||
SStr GetTempBuff();
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve the size of the temporary buffer.
|
||||
*/
|
||||
Uint32 GetTempBuffSize();
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Throw a formatted exception.
|
||||
*/
|
||||
void SqThrowF(CSStr str, ...);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Generate a formatted string.
|
||||
*/
|
||||
CSStr FmtStr(CSStr str, ...);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Implements RAII to restore the VM stack to it's initial size on function exit.
|
||||
*/
|
||||
struct StackGuard
|
||||
{
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Base constructor.
|
||||
*/
|
||||
StackGuard(HSQUIRRELVM vm);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~StackGuard();
|
||||
|
||||
private:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor.
|
||||
*/
|
||||
StackGuard(const StackGuard &);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move constructor.
|
||||
*/
|
||||
StackGuard(StackGuard &&);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
StackGuard & operator = (const StackGuard &);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
StackGuard & operator = (StackGuard &&);
|
||||
|
||||
private:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
Int32 m_Top; /* The top of the stack when this instance was created. */
|
||||
HSQUIRRELVM m_VM; /* The VM where the stack should be restored. */
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Manages a reference counted INI document instance.
|
||||
*/
|
||||
class DbRef
|
||||
{
|
||||
// --------------------------------------------------------------------------------------------
|
||||
friend class Database;
|
||||
|
||||
public:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef MMDB_s Type; // The managed type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Type* Pointer; // Pointer to the managed type.
|
||||
typedef const Type* ConstPtr; // Constant pointer to the managed type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Type& Reference; // Reference to the managed type.
|
||||
typedef const Type& ConstRef; // Constant reference to the managed type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef unsigned int Counter; // Reference counter type.
|
||||
|
||||
private:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
Pointer m_Ptr; // The document reader, writer and manager instance.
|
||||
Counter* m_Ref; // Reference count to the managed instance.
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Creates a database structure.
|
||||
*/
|
||||
static Pointer Create();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destroyes the specified database structure.
|
||||
*/
|
||||
static void Destroy(Pointer db);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Grab a strong reference to a document instance.
|
||||
*/
|
||||
void Grab()
|
||||
{
|
||||
if (m_Ptr)
|
||||
++(*m_Ref);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Drop a strong reference to a document instance.
|
||||
*/
|
||||
void Drop()
|
||||
{
|
||||
if (m_Ptr && --(*m_Ref) == 0)
|
||||
{
|
||||
MMDB_close(m_Ptr);
|
||||
Destroy(m_Ptr);
|
||||
delete m_Ref;
|
||||
m_Ptr = NULL;
|
||||
m_Ref = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Base constructor.
|
||||
*/
|
||||
DbRef(bool make)
|
||||
: m_Ptr(make ? Create() : NULL), m_Ref(m_Ptr ? new Counter(1) : NULL)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Default constructor (null).
|
||||
*/
|
||||
DbRef()
|
||||
: m_Ptr(NULL), m_Ref(NULL)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor.
|
||||
*/
|
||||
DbRef(const DbRef & o)
|
||||
: m_Ptr(o.m_Ptr), m_Ref(o.m_Ref)
|
||||
|
||||
{
|
||||
Grab();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move constructor.
|
||||
*/
|
||||
DbRef(DbRef && o)
|
||||
: m_Ptr(o.m_Ptr), m_Ref(o.m_Ref)
|
||||
|
||||
{
|
||||
o.m_Ptr = NULL;
|
||||
o.m_Ref = NULL;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~DbRef()
|
||||
{
|
||||
Drop();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
DbRef & operator = (const DbRef & o)
|
||||
{
|
||||
if (m_Ptr != o.m_Ptr)
|
||||
{
|
||||
Drop();
|
||||
m_Ptr = o.m_Ptr;
|
||||
m_Ref = o.m_Ref;
|
||||
Grab();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
DbRef & operator = (DbRef && o)
|
||||
{
|
||||
if (m_Ptr != o.m_Ptr)
|
||||
{
|
||||
m_Ptr = o.m_Ptr;
|
||||
m_Ref = o.m_Ref;
|
||||
o.m_Ptr = NULL;
|
||||
o.m_Ref = NULL;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Perform an equality comparison between two document instances.
|
||||
*/
|
||||
bool operator == (const DbRef & o) const
|
||||
{
|
||||
return (m_Ptr == o.m_Ptr);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Perform an inequality comparison between two document instances.
|
||||
*/
|
||||
bool operator != (const DbRef & o) const
|
||||
{
|
||||
return (m_Ptr != o.m_Ptr);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to boolean for use in boolean operations.
|
||||
*/
|
||||
operator bool () const
|
||||
{
|
||||
return m_Ptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to the managed instance pointer.
|
||||
*/
|
||||
operator Pointer ()
|
||||
{
|
||||
return m_Ptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to the managed instance pointer.
|
||||
*/
|
||||
operator ConstPtr () const
|
||||
{
|
||||
return m_Ptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to the managed instance reference.
|
||||
*/
|
||||
operator Reference ()
|
||||
{
|
||||
assert(m_Ptr);
|
||||
return *m_Ptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Implicit conversion to the managed instance reference.
|
||||
*/
|
||||
operator ConstRef () const
|
||||
{
|
||||
assert(m_Ptr);
|
||||
return *m_Ptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Member operator for dereferencing the managed pointer.
|
||||
*/
|
||||
Pointer operator -> () const
|
||||
{
|
||||
assert(m_Ptr);
|
||||
return m_Ptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Indirection operator for obtaining a reference of the managed pointer.
|
||||
*/
|
||||
Reference operator * () const
|
||||
{
|
||||
assert(m_Ptr);
|
||||
return *m_Ptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the raw handle structure pointer.
|
||||
*/
|
||||
Pointer DbPtr()
|
||||
{
|
||||
return m_Ptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the raw handle structure pointer.
|
||||
*/
|
||||
Pointer DbPtr() const
|
||||
{
|
||||
return m_Ptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the number of active references to the managed instance.
|
||||
*/
|
||||
Counter Count() const
|
||||
{
|
||||
return (m_Ptr && m_Ref) ? (*m_Ref) : 0;
|
||||
}
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template < typename T > struct NumLimit;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template <> struct NumLimit< char > { static const char Min, Max; };
|
||||
template <> struct NumLimit< signed char > { static const signed char Min, Max; };
|
||||
template <> struct NumLimit< unsigned char > { static const unsigned char Min, Max; };
|
||||
template <> struct NumLimit< signed short > { static const signed short Min, Max; };
|
||||
template <> struct NumLimit< unsigned short > { static const unsigned short Min, Max; };
|
||||
template <> struct NumLimit< signed int > { static const signed int Min, Max; };
|
||||
template <> struct NumLimit< unsigned int > { static const unsigned int Min, Max; };
|
||||
template <> struct NumLimit< signed long > { static const signed long Min, Max; };
|
||||
template <> struct NumLimit< unsigned long > { static const unsigned long Min, Max; };
|
||||
template <> struct NumLimit< signed long long > { static const signed long long Min, Max; };
|
||||
template <> struct NumLimit< unsigned long long > { static const unsigned long long Min, Max; };
|
||||
template <> struct NumLimit< float > { static const float Min, Max; };
|
||||
template <> struct NumLimit< double > { static const double Min, Max; };
|
||||
template <> struct NumLimit< long double > { static const long double Min, Max; };
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template< typename T > inline bool EpsEq(const T a, const T b)
|
||||
{
|
||||
return abs(a - b) <= 0;
|
||||
}
|
||||
|
||||
template <> inline bool EpsEq(const Float32 a, const Float32 b)
|
||||
{
|
||||
return fabs(a - b) <= 0.000001f;
|
||||
}
|
||||
|
||||
template <> inline bool EpsEq(const Float64 a, const Float64 b)
|
||||
{
|
||||
return fabs(a - b) <= 0.000000001d;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template< typename T > inline bool EpsLt(const T a, const T b)
|
||||
{
|
||||
return !EpsEq(a, b) && (a < b);
|
||||
}
|
||||
|
||||
template <> inline bool EpsLt(const Float32 a, const Float32 b)
|
||||
{
|
||||
return !EpsEq(a, b) && (a - b) < 0.000001f;
|
||||
}
|
||||
|
||||
template <> inline bool EpsLt(const Float64 a, const Float64 b)
|
||||
{
|
||||
return !EpsEq(a, b) && (a - b) < 0.000000001d;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template< typename T > inline bool EpsGt(const T a, const T b)
|
||||
{
|
||||
return !EpsEq(a, b) && (a > b);
|
||||
}
|
||||
|
||||
template <> inline bool EpsGt(const Float32 a, const Float32 b)
|
||||
{
|
||||
return !EpsEq(a, b) && (a - b) > 0.000001f;
|
||||
}
|
||||
|
||||
template <> inline bool EpsGt(const Float64 a, const Float64 b)
|
||||
{
|
||||
return !EpsEq(a, b) && (a - b) > 0.000000001d;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template< typename T > inline bool EpsLtEq(const T a, const T b)
|
||||
{
|
||||
return !EpsEq(a, b) || (a < b);
|
||||
}
|
||||
|
||||
template <> inline bool EpsLtEq(const Float32 a, const Float32 b)
|
||||
{
|
||||
return !EpsEq(a, b) || (a - b) < 0.000001f;
|
||||
}
|
||||
|
||||
template <> inline bool EpsLtEq(const Float64 a, const Float64 b)
|
||||
{
|
||||
return !EpsEq(a, b) || (a - b) < 0.000000001d;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template< typename T > inline bool EpsGtEq(const T a, const T b)
|
||||
{
|
||||
return !EpsEq(a, b) || (a > b);
|
||||
}
|
||||
|
||||
template <> inline bool EpsGtEq(const Float32 a, const Float32 b)
|
||||
{
|
||||
return !EpsEq(a, b) || (a - b) > 0.000001f;
|
||||
}
|
||||
|
||||
template <> inline bool EpsGtEq(const Float64 a, const Float64 b)
|
||||
{
|
||||
return !EpsEq(a, b) || (a - b) > 0.000000001d;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template< typename T > inline T Clamp(T val, T min, T max)
|
||||
{
|
||||
return val < min ? min : (val > max ? max : val);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _SQMMDB_COMMON_HPP_
|
116
modules/mmdb/Database.cpp
Normal file
116
modules/mmdb/Database.cpp
Normal file
@ -0,0 +1,116 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Database.hpp"
|
||||
#include "SockAddr.hpp"
|
||||
#include "LookupResult.hpp"
|
||||
#include "Module.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <sqrat.h>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger Database::Typename(HSQUIRRELVM vm)
|
||||
{
|
||||
static const SQChar name[] = _SC("SqMMDBDatabase");
|
||||
sq_pushstring(vm, name, sizeof(name));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Database::Validate() const
|
||||
{
|
||||
// Is the document handle valid?
|
||||
if (!m_Db)
|
||||
SqThrowF("Invalid Maxmind database reference");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 Database::Cmp(const Database & o) const
|
||||
{
|
||||
if (m_Db == o.m_Db)
|
||||
return 0;
|
||||
else if (m_Db.m_Ptr > o.m_Db.m_Ptr)
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Database::Open(CSStr filepath)
|
||||
{
|
||||
Open(filepath, 0);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Database::Open(CSStr filepath, Uint32 flags)
|
||||
{
|
||||
// Is there a database handle available?
|
||||
if (!m_Db)
|
||||
m_Db = DbRef(true); // Create a database handle
|
||||
// Check if the database handle could be allocated one more time
|
||||
if (!m_Db)
|
||||
SqThrowF("Unable to create a Maxmind database reference");
|
||||
// Are there any other references?
|
||||
else if (m_Db.Count() > 1)
|
||||
// To load new values now, would mean to cause undefined behavior in existing references
|
||||
SqThrowF("Loading is disabled while database is referenced");
|
||||
// Validate the specified file path
|
||||
else if (!filepath || strlen(filepath) <= 0)
|
||||
SqThrowF("Invalid database file path");
|
||||
// Let's attempt to open the specified database
|
||||
const Int32 status = MMDB_open(filepath, flags, m_Db.m_Ptr);
|
||||
// Validate the result of the operation
|
||||
if (status != MMDB_SUCCESS)
|
||||
{
|
||||
// Release the database reference
|
||||
m_Db.Drop();
|
||||
// Now it's safe to throw the error
|
||||
SqThrowF("Unable to open the specified database [%s]", MMDB_strerror(status));
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
LookupResult Database::LookupString(CSStr addr)
|
||||
{
|
||||
// Validate the database handle
|
||||
Validate();
|
||||
// Validate the specified string
|
||||
if (!addr || strlen(addr) <= 0)
|
||||
SqThrowF("Invalid address string");
|
||||
// Dummy variables to obtain the status codes
|
||||
int gai_error, mmdb_error;
|
||||
// Attempt to perform the actual lookup
|
||||
MMDB_lookup_result_s result = MMDB_lookup_string(m_Db, addr, &gai_error, &mmdb_error);
|
||||
// Validate the result of the getaddrinfo() function call
|
||||
if (gai_error != 0)
|
||||
SqThrowF("Unable to resolve address (%s) because [%s]", addr, gai_strerror(gai_error));
|
||||
// Validate the lookup status code
|
||||
else if (mmdb_error != MMDB_SUCCESS)
|
||||
SqThrowF("Unable to lookup address (%s) because [%s]", addr, MMDB_strerror(mmdb_error));
|
||||
// Now it's safe to return the lookup result
|
||||
return LookupResult(m_Db, result);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
LookupResult Database::LookupSockAddr(SockAddr & addr)
|
||||
{
|
||||
// Validate the database handle
|
||||
Validate();
|
||||
// Validate the specified socket address
|
||||
if (!addr.IsValid())
|
||||
SqThrowF("Invalid address instance");
|
||||
// Dummy variable to obtain the status codes
|
||||
int mmdb_error;
|
||||
// Attempt to perform the actual lookup
|
||||
MMDB_lookup_result_s result = MMDB_lookup_sockaddr(m_Db, addr.GetHandle()->ai_addr, &mmdb_error);
|
||||
// Validate the lookup status code
|
||||
if (mmdb_error != MMDB_SUCCESS)
|
||||
SqThrowF("Unable to lookup address (%s) because [%s]",
|
||||
addr.GetAddress(), MMDB_strerror(mmdb_error));
|
||||
// Now it's safe to return the lookup result
|
||||
return LookupResult(m_Db, result);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
132
modules/mmdb/Database.hpp
Normal file
132
modules/mmdb/Database.hpp
Normal file
@ -0,0 +1,132 @@
|
||||
#ifndef _SQMMDB_DATABASE_HPP_
|
||||
#define _SQMMDB_DATABASE_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Common.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Class that can read/write and alter the contents of INI files.
|
||||
*/
|
||||
class Database
|
||||
{
|
||||
protected:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor. (disabled)
|
||||
*/
|
||||
Database(const Database &);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator. (disabled)
|
||||
*/
|
||||
Database & operator = (const Database &);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Validate the document reference and throw an error if invalid.
|
||||
*/
|
||||
void Validate() const;
|
||||
|
||||
private:
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
DbRef m_Db; /* The main INI document instance. */
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Default constructor.
|
||||
*/
|
||||
Database()
|
||||
: m_Db()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Base constructor.
|
||||
*/
|
||||
Database(CSStr filepath)
|
||||
: m_Db()
|
||||
{
|
||||
Open(filepath, 0);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Base constructor.
|
||||
*/
|
||||
Database(CSStr filepath, Uint32 flags)
|
||||
: m_Db()
|
||||
{
|
||||
Open(filepath, flags);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~Database()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to compare two instances of this type.
|
||||
*/
|
||||
Int32 Cmp(const Database & o) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const
|
||||
{
|
||||
return _SC("");
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to retrieve the name from instances of this type.
|
||||
*/
|
||||
static SQInteger Typename(HSQUIRRELVM vm);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether this instance references a valid INI document.
|
||||
*/
|
||||
bool IsValid() const
|
||||
{
|
||||
return m_Db;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Return the number of active references to this document instance.
|
||||
*/
|
||||
Uint32 GetRefCount() const
|
||||
{
|
||||
return m_Db.Count();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Attempt to open the specified database.
|
||||
*/
|
||||
void Open(CSStr filepath);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Attempt to open the specified database.
|
||||
*/
|
||||
void Open(CSStr filepath, Uint32 addr);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Look up an IP address that is passed in as a null-terminated string.
|
||||
*/
|
||||
LookupResult LookupString(CSStr addr);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Looks up an IP address that has already been resolved by getaddrinfo().
|
||||
*/
|
||||
LookupResult LookupSockAddr(SockAddr & sockaddr);
|
||||
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _SQMMDB_DATABASE_HPP_
|
382
modules/mmdb/EntryDataList.cpp
Normal file
382
modules/mmdb/EntryDataList.cpp
Normal file
@ -0,0 +1,382 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "EntryDataList.hpp"
|
||||
#include "Module.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <sqrat.h>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger EntryDataList::Typename(HSQUIRRELVM vm)
|
||||
{
|
||||
static const SQChar name[] = _SC("SqMMDBEntryDataList");
|
||||
sq_pushstring(vm, name, sizeof(name));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void EntryDataList::Validate() const
|
||||
{
|
||||
// Is the document handle valid?
|
||||
if (!m_Db)
|
||||
SqThrowF("Invalid Maxmind database reference");
|
||||
// Do we have a valid list?
|
||||
else if (!m_List)
|
||||
SqThrowF("Invalid entry data list");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void EntryDataList::ValidateElem() const
|
||||
{
|
||||
// Is the document handle valid?
|
||||
if (!m_Db)
|
||||
SqThrowF("Invalid Maxmind database reference");
|
||||
// Do we have a valid list?
|
||||
else if (!m_List)
|
||||
SqThrowF("Invalid entry data list");
|
||||
// Do we have a valid element?
|
||||
else if (!m_Elem)
|
||||
SqThrowF("Invalid entry data element");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void EntryDataList::ValidateData() const
|
||||
{
|
||||
// Is the document handle valid?
|
||||
if (!m_Db)
|
||||
SqThrowF("Invalid Maxmind database reference");
|
||||
// Do we have a valid list?
|
||||
else if (!m_List)
|
||||
SqThrowF("Invalid entry data list");
|
||||
// Do we have a valid element?
|
||||
else if (!m_Elem)
|
||||
SqThrowF("Invalid entry data element");
|
||||
// Do we have some valid data?
|
||||
else if (!m_Elem->entry_data.has_data)
|
||||
SqThrowF("Entry data element has no data");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr EntryDataList::AsTypeStr(Uint32 id)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case MMDB_DATA_TYPE_EXTENDED: return _SC("extended");
|
||||
case MMDB_DATA_TYPE_POINTER: return _SC("pointer");
|
||||
case MMDB_DATA_TYPE_UTF8_STRING: return _SC("string");
|
||||
case MMDB_DATA_TYPE_DOUBLE: return _SC("double");
|
||||
case MMDB_DATA_TYPE_BYTES: return _SC("bytes");
|
||||
case MMDB_DATA_TYPE_UINT16: return _SC("uint16");
|
||||
case MMDB_DATA_TYPE_UINT32: return _SC("uint32");
|
||||
case MMDB_DATA_TYPE_MAP: return _SC("map");
|
||||
case MMDB_DATA_TYPE_INT32: return _SC("int32");
|
||||
case MMDB_DATA_TYPE_UINT64: return _SC("uint64");
|
||||
case MMDB_DATA_TYPE_UINT128: return _SC("uint128");
|
||||
case MMDB_DATA_TYPE_ARRAY: return _SC("array");
|
||||
case MMDB_DATA_TYPE_CONTAINER: return _SC("container");
|
||||
case MMDB_DATA_TYPE_END_MARKER: return _SC("endmarker");
|
||||
case MMDB_DATA_TYPE_BOOLEAN: return _SC("boolean");
|
||||
case MMDB_DATA_TYPE_FLOAT: return _SC("float");
|
||||
default: return _SC("unknonw");
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
EntryDataList::~EntryDataList()
|
||||
{
|
||||
// Do we have to free any list?
|
||||
if (m_List)
|
||||
MMDB_free_entry_data_list(m_List);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 EntryDataList::Cmp(const EntryDataList & o) const
|
||||
{
|
||||
if (m_List == o.m_List)
|
||||
return 0;
|
||||
else if (m_List > o.m_List)
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Uint32 EntryDataList::GetCount() const
|
||||
{
|
||||
// Do we even have a list?
|
||||
if (!m_List)
|
||||
return 0;
|
||||
// Get the start of the list
|
||||
Pointer elem = m_List;
|
||||
// Prepare a counter
|
||||
Uint32 count = 1;
|
||||
// Loop through list elements
|
||||
while ((elem = elem->next)) ++count;
|
||||
// Return the counter
|
||||
return count;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool EntryDataList::Next()
|
||||
{
|
||||
// Validate the database and list handle
|
||||
Validate();
|
||||
// Do we have a valid element currently?
|
||||
if (m_Elem)
|
||||
return (m_Elem = m_Elem->next);
|
||||
// Nothing to advance
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool EntryDataList::Advance(Int32 n)
|
||||
{
|
||||
// Validate the database and list handle
|
||||
Validate();
|
||||
// Do we have a valid element currently?
|
||||
if (m_Elem)
|
||||
// Attempt to skip as many elements as possible
|
||||
while ((n > 0) && (m_Elem = m_Elem->next)) --n;
|
||||
// Return whether we have a valid element
|
||||
return m_Elem;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void EntryDataList::Reset()
|
||||
{
|
||||
// Validate the database and list handle
|
||||
Validate();
|
||||
// Go back to the first element
|
||||
m_Elem = m_List;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr EntryDataList::GetString() const
|
||||
{
|
||||
// Validate the database, list and element handle
|
||||
ValidateData();
|
||||
// Attempt to perform the requested conversion
|
||||
switch (m_Elem->entry_data.type)
|
||||
{
|
||||
case MMDB_DATA_TYPE_UTF8_STRING:
|
||||
return m_Elem->entry_data.utf8_string;
|
||||
case MMDB_DATA_TYPE_DOUBLE:
|
||||
return FmtStr("%f", m_Elem->entry_data.double_value);
|
||||
case MMDB_DATA_TYPE_UINT16:
|
||||
return FmtStr("%u", m_Elem->entry_data.uint16);
|
||||
case MMDB_DATA_TYPE_UINT32:
|
||||
return FmtStr("%u", m_Elem->entry_data.uint32);
|
||||
case MMDB_DATA_TYPE_INT32:
|
||||
return FmtStr("%d", m_Elem->entry_data.int32);
|
||||
case MMDB_DATA_TYPE_UINT64:
|
||||
return FmtStr("%llu", m_Elem->entry_data.uint64);
|
||||
case MMDB_DATA_TYPE_BOOLEAN:
|
||||
return m_Elem->entry_data.boolean ? _SC("true") : _SC("false");
|
||||
case MMDB_DATA_TYPE_FLOAT:
|
||||
return FmtStr("%f", m_Elem->entry_data.float_value);
|
||||
default:
|
||||
SqThrowF("Unsupported conversion from (%s) to (string)", AsTypeStr(m_Elem->entry_data.type));
|
||||
}
|
||||
// Shouldn't really reach this point
|
||||
return _SC("");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger EntryDataList::GetInteger() const
|
||||
{
|
||||
// Validate the database, list and element handle
|
||||
ValidateData();
|
||||
// Attempt to perform the requested conversion
|
||||
switch (m_Elem->entry_data.type)
|
||||
{
|
||||
#ifdef _SQ64
|
||||
case MMDB_DATA_TYPE_UTF8_STRING:
|
||||
return strtoll(m_Elem->entry_data.utf8_string, NULL, 10);
|
||||
case MMDB_DATA_TYPE_DOUBLE:
|
||||
return llround(m_Elem->entry_data.double_value);
|
||||
case MMDB_DATA_TYPE_UINT16:
|
||||
return m_Elem->entry_data.uint16;
|
||||
case MMDB_DATA_TYPE_UINT32:
|
||||
return m_Elem->entry_data.uint32;
|
||||
case MMDB_DATA_TYPE_INT32:
|
||||
return m_Elem->entry_data.int32;
|
||||
case MMDB_DATA_TYPE_UINT64:
|
||||
return Clamp(m_Elem->entry_data.uint64, 0, Uint64(NumLimit< SQInteger >::Max));
|
||||
case MMDB_DATA_TYPE_BOOLEAN:
|
||||
return m_Elem->entry_data.boolean ? 1 : 0;
|
||||
case MMDB_DATA_TYPE_FLOAT:
|
||||
return llround(m_Elem->entry_data.float_value);
|
||||
default:
|
||||
SqThrowF("Unsupported conversion from (%s) to (int32)", AsTypeStr(m_Elem->entry_data.type));
|
||||
#else
|
||||
case MMDB_DATA_TYPE_UTF8_STRING:
|
||||
return strtol(m_Elem->entry_data.utf8_string, NULL, 10);
|
||||
case MMDB_DATA_TYPE_DOUBLE:
|
||||
return lround(m_Elem->entry_data.double_value);
|
||||
case MMDB_DATA_TYPE_UINT16:
|
||||
return m_Elem->entry_data.uint16;
|
||||
case MMDB_DATA_TYPE_UINT32:
|
||||
return Clamp(m_Elem->entry_data.uint32, 0U, Uint32(NumLimit< SQInteger >::Max));
|
||||
case MMDB_DATA_TYPE_INT32:
|
||||
return m_Elem->entry_data.int32;
|
||||
case MMDB_DATA_TYPE_UINT64:
|
||||
return Clamp(m_Elem->entry_data.uint64, 0ULL, Uint64(NumLimit< SQInteger >::Max));
|
||||
case MMDB_DATA_TYPE_BOOLEAN:
|
||||
return m_Elem->entry_data.boolean ? 1 : 0;
|
||||
case MMDB_DATA_TYPE_FLOAT:
|
||||
return lround(m_Elem->entry_data.float_value);
|
||||
default:
|
||||
SqThrowF("Unsupported conversion from (%s) to (int64)", AsTypeStr(m_Elem->entry_data.type));
|
||||
#endif // _SQ64
|
||||
}
|
||||
// Shouldn't really reach this point
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQFloat EntryDataList::GetFloat() const
|
||||
{
|
||||
// Validate the database, list and element handle
|
||||
ValidateData();
|
||||
// Attempt to perform the requested conversion
|
||||
switch (m_Elem->entry_data.type)
|
||||
{
|
||||
#ifdef SQUSEDOUBLE
|
||||
case MMDB_DATA_TYPE_UTF8_STRING:
|
||||
return static_cast< SQFloat >(strtod(m_Elem->entry_data.utf8_string, NULL));
|
||||
#else
|
||||
return static_cast< SQFloat >(strtof(m_Elem->entry_data.utf8_string, NULL));
|
||||
#endif // SQUSEDOUBLE
|
||||
case MMDB_DATA_TYPE_DOUBLE:
|
||||
return static_cast< SQFloat >(m_Elem->entry_data.double_value);
|
||||
case MMDB_DATA_TYPE_UINT16:
|
||||
return static_cast< SQFloat >(m_Elem->entry_data.uint16);
|
||||
case MMDB_DATA_TYPE_UINT32:
|
||||
return static_cast< SQFloat >(round(m_Elem->entry_data.uint32));
|
||||
case MMDB_DATA_TYPE_INT32:
|
||||
return static_cast< SQFloat >(round(m_Elem->entry_data.int32));
|
||||
case MMDB_DATA_TYPE_UINT64:
|
||||
return static_cast< SQFloat >(round(m_Elem->entry_data.uint64));
|
||||
case MMDB_DATA_TYPE_BOOLEAN:
|
||||
return m_Elem->entry_data.boolean ? 1.0 : 0.0;
|
||||
case MMDB_DATA_TYPE_FLOAT:
|
||||
return static_cast< SQFloat >(m_Elem->entry_data.float_value);
|
||||
default:
|
||||
SqThrowF("Unsupported conversion from (%s) to (float)", AsTypeStr(m_Elem->entry_data.type));
|
||||
}
|
||||
// Shouldn't really reach this point
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Object EntryDataList::GetLong() const
|
||||
{
|
||||
// Validate the database, list and element handle
|
||||
ValidateData();
|
||||
// Where the long number is retrieved
|
||||
Uint64 longint = 0;
|
||||
Int64 slong = 0;
|
||||
// Attempt to perform the requested conversion
|
||||
switch (m_Elem->entry_data.type)
|
||||
{
|
||||
case MMDB_DATA_TYPE_UTF8_STRING:
|
||||
longint = strtoull(m_Elem->entry_data.utf8_string, NULL, 10);
|
||||
break;
|
||||
case MMDB_DATA_TYPE_DOUBLE:
|
||||
{
|
||||
slong = llround(m_Elem->entry_data.double_value);
|
||||
longint = slong >= 0 ? slong : 0;
|
||||
} break;
|
||||
case MMDB_DATA_TYPE_UINT16:
|
||||
longint = m_Elem->entry_data.uint16;
|
||||
break;
|
||||
case MMDB_DATA_TYPE_UINT32:
|
||||
longint = m_Elem->entry_data.uint32;
|
||||
break;
|
||||
case MMDB_DATA_TYPE_INT32:
|
||||
longint = m_Elem->entry_data.int32 >= 0 ? m_Elem->entry_data.int32 : 0;
|
||||
break;
|
||||
case MMDB_DATA_TYPE_UINT64:
|
||||
longint = m_Elem->entry_data.uint64;
|
||||
break;
|
||||
case MMDB_DATA_TYPE_BOOLEAN:
|
||||
longint = m_Elem->entry_data.boolean ? 1 : 0;
|
||||
break;
|
||||
case MMDB_DATA_TYPE_FLOAT:
|
||||
{
|
||||
slong = llround(m_Elem->entry_data.float_value);
|
||||
longint = slong >= 0 ? slong : 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
SqThrowF("Unsupported conversion from (%s) to (uint64)", AsTypeStr(m_Elem->entry_data.type));
|
||||
}
|
||||
// Obtain the initial stack size
|
||||
const StackGuard sg(_SqVM);
|
||||
// Push a long integer instance with the requested value on the stack
|
||||
_SqMod->PushULongObject(_SqVM, longint);
|
||||
// Get the object from the stack and return it
|
||||
return Var< Object >(_SqVM, -1).value;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool EntryDataList::GetBool() const
|
||||
{
|
||||
// Validate the database, list and element handle
|
||||
ValidateData();
|
||||
// Attempt to perform the requested conversion
|
||||
switch (m_Elem->entry_data.type)
|
||||
{
|
||||
case MMDB_DATA_TYPE_UTF8_STRING:
|
||||
return !!(m_Elem->entry_data.utf8_string);
|
||||
case MMDB_DATA_TYPE_DOUBLE:
|
||||
return EpsGt(m_Elem->entry_data.double_value, 0.0d);
|
||||
case MMDB_DATA_TYPE_UINT16:
|
||||
return (m_Elem->entry_data.uint16 > 0);
|
||||
case MMDB_DATA_TYPE_UINT32:
|
||||
return (m_Elem->entry_data.uint32 > 0);
|
||||
case MMDB_DATA_TYPE_INT32:
|
||||
return (m_Elem->entry_data.int32 > 0);
|
||||
case MMDB_DATA_TYPE_UINT64:
|
||||
return (m_Elem->entry_data.uint64 > 0);
|
||||
case MMDB_DATA_TYPE_BOOLEAN:
|
||||
return m_Elem->entry_data.boolean;
|
||||
case MMDB_DATA_TYPE_FLOAT:
|
||||
return EpsGt(m_Elem->entry_data.float_value, 0.0f);
|
||||
default:
|
||||
SqThrowF("Unsupported conversion from (%s) to (boolean)", AsTypeStr(m_Elem->entry_data.type));
|
||||
}
|
||||
// Shouldn't really reach this point
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void EntryDataList::DumpTo(CSStr filepath, Int32 indent) const
|
||||
{
|
||||
// Validate the database and list handle
|
||||
Validate();
|
||||
// Validate the specified file path
|
||||
if (!filepath || strlen(filepath) <= 0)
|
||||
SqThrowF("Invalid file path");
|
||||
// Attempt to open the specified file
|
||||
FILE * fp = fopen(filepath, "w");
|
||||
// Validate the file handle
|
||||
if (!fp)
|
||||
SqThrowF("Unable to open file %s", filepath);
|
||||
// Attempt to dump the entry data list
|
||||
Int32 status = MMDB_dump_entry_data_list(fp, m_List, indent);
|
||||
// Close the file handle
|
||||
fclose(fp);
|
||||
// Validate the result of the operation
|
||||
if (status != MMDB_SUCCESS)
|
||||
// Now it's safe to throw the error
|
||||
SqThrowF("Unable to dump the list [%s]", MMDB_strerror(status));
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
291
modules/mmdb/EntryDataList.hpp
Normal file
291
modules/mmdb/EntryDataList.hpp
Normal file
@ -0,0 +1,291 @@
|
||||
#ifndef _SQMMDB_LOOKUPRESULT_HPP_
|
||||
#define _SQMMDB_LOOKUPRESULT_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Common.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Class that can be used to traverse a list of results.
|
||||
*/
|
||||
class EntryDataList
|
||||
{
|
||||
protected:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef MMDB_entry_data_list_s Type; // The managed type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Type* Pointer; // Pointer to the managed type.
|
||||
typedef const Type* ConstPtr; // Constant pointer to the managed type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Type& Reference; // Reference to the managed type.
|
||||
typedef const Type& ConstRef; // Constant reference to the managed type.
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Validate the database pointer and list handle and throw an error if invalid.
|
||||
*/
|
||||
void Validate() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Do a regular validation and also validate the currently processed element.
|
||||
*/
|
||||
void ValidateElem() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Do a regular validation and also validate the currently processed element data.
|
||||
*/
|
||||
void ValidateData() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used to retrieve the string representation of the specified type identifier.
|
||||
*/
|
||||
static CSStr AsTypeStr(Uint32 id);
|
||||
|
||||
private:
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
DbRef m_Db; /* The database from which this list comes from. */
|
||||
Pointer m_List; /* The managed entry data list. */
|
||||
Pointer m_Elem; /* The currently processed element from the list. */
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Base constructor.
|
||||
*/
|
||||
EntryDataList(const DbRef & db, Pointer list)
|
||||
: m_Db(db), m_List(list), m_Elem(list)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Default constructor.
|
||||
*/
|
||||
EntryDataList();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor. (disabled)
|
||||
*/
|
||||
EntryDataList(const EntryDataList &) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move constructor.
|
||||
*/
|
||||
EntryDataList(EntryDataList && o)
|
||||
: m_Db(o.m_Db)
|
||||
, m_List(o.m_List)
|
||||
, m_Elem(o.m_Elem)
|
||||
{
|
||||
o.m_List = nullptr;
|
||||
o.m_Elem = nullptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~EntryDataList();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator. (disabled)
|
||||
*/
|
||||
EntryDataList & operator = (const EntryDataList &) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
EntryDataList & operator = (EntryDataList && o)
|
||||
{
|
||||
if (m_List != o.m_List)
|
||||
{
|
||||
m_Db = o.m_Db;
|
||||
m_List = o.m_List;
|
||||
m_Elem = o.m_Elem;
|
||||
o.m_List = nullptr;
|
||||
o.m_Elem = nullptr;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the internal entry data list structure pointer.
|
||||
*/
|
||||
Pointer GetHandle()
|
||||
{
|
||||
return m_List;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the internal entry data list structure pointer.
|
||||
*/
|
||||
Pointer GetHandle() const
|
||||
{
|
||||
return m_List;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to compare two instances of this type.
|
||||
*/
|
||||
Int32 Cmp(const EntryDataList & o) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const
|
||||
{
|
||||
return m_Elem ? AsTypeStr(m_Elem->entry_data.type) : _SC("invalid");
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to retrieve the name from instances of this type.
|
||||
*/
|
||||
static SQInteger Typename(HSQUIRRELVM vm);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether this instance references a valid database and entry data list structure.
|
||||
*/
|
||||
bool IsValid() const
|
||||
{
|
||||
return m_Db && m_List;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether a valid element is currently processed.
|
||||
*/
|
||||
bool HaveElement() const
|
||||
{
|
||||
return m_Elem;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used to retrieve the type of the current element as a string.
|
||||
*/
|
||||
CSStr TypeStr() const
|
||||
{
|
||||
// Validate the database and list handle
|
||||
Validate();
|
||||
// return the requested information
|
||||
return m_Elem ? AsTypeStr(m_Elem->entry_data.type) : _SC("invalid");
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Return the total entries in the list.
|
||||
*/
|
||||
Uint32 GetCount() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Go to the next element.
|
||||
*/
|
||||
bool Next();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Advance a certain number of elements.
|
||||
*/
|
||||
bool Advance(Int32 n);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Go back to the first element in the list.
|
||||
*/
|
||||
void Reset();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether a valid element is currently processed.
|
||||
*/
|
||||
bool HasData() const
|
||||
{
|
||||
// Validate the database, list and element handle
|
||||
ValidateElem();
|
||||
// Return the requested information
|
||||
return m_Elem->entry_data.has_data;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the type identifier of the current element.
|
||||
*/
|
||||
SQInteger GetType() const
|
||||
{
|
||||
// Validate the database, list and element handle
|
||||
ValidateElem();
|
||||
// Return the requested information
|
||||
return static_cast< SQInteger >(m_Elem->entry_data.type);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the offset of the current element.
|
||||
*/
|
||||
SQInteger GetOffset() const
|
||||
{
|
||||
// Validate the database, list and element handle
|
||||
ValidateElem();
|
||||
// Return the requested information
|
||||
return static_cast< SQInteger >(m_Elem->entry_data.offset);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the offset of the next element.
|
||||
*/
|
||||
SQInteger GetOffsetToNext() const
|
||||
{
|
||||
// Validate the database, list and element handle
|
||||
ValidateElem();
|
||||
// Return the requested information
|
||||
return static_cast< SQInteger >(m_Elem->entry_data.offset_to_next);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the offset of the next element.
|
||||
*/
|
||||
SQInteger DataSize() const
|
||||
{
|
||||
// Validate the database, list and element handle
|
||||
ValidateElem();
|
||||
// Return the requested information
|
||||
return static_cast< SQInteger >(m_Elem->entry_data.data_size);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the value from the current element as a string.
|
||||
*/
|
||||
CSStr GetString() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the value from the current element as a native integer.
|
||||
*/
|
||||
SQInteger GetInteger() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the value from the current element as a floating point.
|
||||
*/
|
||||
SQFloat GetFloat() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the value from the current element as a long integer.
|
||||
*/
|
||||
Object GetLong() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the value from the current element as a boolean.
|
||||
*/
|
||||
bool GetBool() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Dumpt the contents of the list to the specified list.
|
||||
*/
|
||||
void DumpTo(CSStr filepath)
|
||||
{
|
||||
DumpTo(filepath, 0);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Dumpt the contents of the list to the specified list.
|
||||
*/
|
||||
void DumpTo(CSStr filepath, Int32 indent) const;
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _SQMMDB_LOOKUPRESULT_HPP_
|
54
modules/mmdb/LookupResult.cpp
Normal file
54
modules/mmdb/LookupResult.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "LookupResult.hpp"
|
||||
#include "Module.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger LookupResult::Typename(HSQUIRRELVM vm)
|
||||
{
|
||||
static const SQChar name[] = _SC("SqMMDBLookupResult");
|
||||
sq_pushstring(vm, name, sizeof(name));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void LookupResult::Validate() const
|
||||
{
|
||||
// Is the document handle valid?
|
||||
if (!m_Db)
|
||||
SqThrowF("Invalid Maxmind database reference");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
LookupResult::LookupResult()
|
||||
: m_Db(), m_Result()
|
||||
{
|
||||
memset(&m_Result, 0, sizeof(Type));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 LookupResult::Cmp(const LookupResult & o) const
|
||||
{
|
||||
if (m_Db == o.m_Db)
|
||||
return 0;
|
||||
else if (m_Db.DbPtr() > o.m_Db.DbPtr())
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
EntryDataList LookupResult::GetValueA(CSStr path, Array & arr) const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
EntryDataList LookupResult::GetValueT(CSStr path, Table & tbl) const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
164
modules/mmdb/LookupResult.hpp
Normal file
164
modules/mmdb/LookupResult.hpp
Normal file
@ -0,0 +1,164 @@
|
||||
#ifndef _SQMMDB_LOOKUPRESULT_HPP_
|
||||
#define _SQMMDB_LOOKUPRESULT_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Common.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Class that can hold and be used to work with lookup results.
|
||||
*/
|
||||
class LookupResult
|
||||
{
|
||||
// --------------------------------------------------------------------------------------------
|
||||
friend class Database; // Only a valid database instance can construct this type.
|
||||
|
||||
protected:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef MMDB_lookup_result_s Type; // The managed type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Type* Pointer; // Pointer to the managed type.
|
||||
typedef const Type* ConstPtr; // Constant pointer to the managed type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Type& Reference; // Reference to the managed type.
|
||||
typedef const Type& ConstRef; // Constant reference to the managed type.
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Validate the database pointer and throw an error if invalid.
|
||||
*/
|
||||
void Validate() const;
|
||||
|
||||
private:
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
DbRef m_Db; /* The database from which this result comes from. */
|
||||
Type m_Result; /* The managed result structure. */
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Construct and take ownership of a certain result.
|
||||
*/
|
||||
LookupResult(const DbRef & db, Reference result)
|
||||
: m_Db(db), m_Result(result)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Default constructor. (null)
|
||||
*/
|
||||
LookupResult();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor.
|
||||
*/
|
||||
LookupResult(const LookupResult &) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move constructor.
|
||||
*/
|
||||
LookupResult(LookupResult &&) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~LookupResult()
|
||||
{
|
||||
/* We let the smart reference deal with deallocations if necessary. */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
LookupResult & operator = (const LookupResult &) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
LookupResult & operator = (LookupResult &&) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the internal result structure reference.
|
||||
*/
|
||||
Reference GetHandle()
|
||||
{
|
||||
return m_Result;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the internal result structure reference.
|
||||
*/
|
||||
ConstRef GetHandle() const
|
||||
{
|
||||
return m_Result;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to compare two instances of this type.
|
||||
*/
|
||||
Int32 Cmp(const LookupResult & o) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const
|
||||
{
|
||||
return FmtStr("%u", m_Result.entry.offset);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to retrieve the name from instances of this type.
|
||||
*/
|
||||
static SQInteger Typename(HSQUIRRELVM vm);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether this instance references a valid database and result structure.
|
||||
*/
|
||||
bool IsValid() const
|
||||
{
|
||||
return m_Db && m_Result.found_entry;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether the result contains a valid entry in the associated database.
|
||||
*/
|
||||
bool FoundEntry() const
|
||||
{
|
||||
// Validate the database handle
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return m_Result.found_entry;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the net-mask from the result structure.
|
||||
*/
|
||||
SQInteger GetNetMask() const
|
||||
{
|
||||
// Validate the database handle
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return static_cast< SQInteger >(m_Result.netmask);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Lookup data in the associated result using an array as the path.
|
||||
*/
|
||||
EntryDataList GetValueA(CSStr path, Array & arr) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Lookup data in the associated result using a table as the path.
|
||||
*/
|
||||
EntryDataList GetValueT(CSStr path, Table & tbl) const;
|
||||
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _SQMMDB_LOOKUPRESULT_HPP_
|
302
modules/mmdb/Module.cpp
Normal file
302
modules/mmdb/Module.cpp
Normal file
@ -0,0 +1,302 @@
|
||||
// --------------------------------------------------------------------------------------------
|
||||
#include "Module.hpp"
|
||||
#include "Common.hpp"
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
#include <sqrat.h>
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
namespace SqMod {
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
PluginFuncs* _Func = NULL;
|
||||
PluginCallbacks* _Clbk = NULL;
|
||||
PluginInfo* _Info = NULL;
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
HSQAPI _SqAPI = NULL;
|
||||
HSQEXPORTS _SqMod = NULL;
|
||||
HSQUIRRELVM _SqVM = NULL;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Bind speciffic functions to certain server events.
|
||||
*/
|
||||
void BindCallbacks();
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Undo changes made with BindCallbacks().
|
||||
*/
|
||||
void UnbindCallbacks();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Register the module API under the specified virtual machine.
|
||||
*/
|
||||
void RegisterAPI(HSQUIRRELVM vm);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Initialize the plugin by obtaining the API provided by the host plugin.
|
||||
*/
|
||||
void OnSquirrelInitialize()
|
||||
{
|
||||
// Attempt to import the plugin API exported by the host plugin
|
||||
_SqMod = sq_api_import(_Func);
|
||||
// Did we failed to obtain the plugin exports?
|
||||
if(!_SqMod)
|
||||
OutputError("Failed to attach [%s] on host plugin.", SQMMDB_NAME);
|
||||
else
|
||||
{
|
||||
// Obtain the Squirrel API
|
||||
_SqAPI = _SqMod->GetSquirrelAPI();
|
||||
// Expand the Squirrel API into global functions
|
||||
sq_api_expand(_SqAPI);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Load the module on the virtual machine provided by the host module.
|
||||
*/
|
||||
void OnSquirrelLoad()
|
||||
{
|
||||
// Make sure that we have a valid plugin API
|
||||
if (!_SqMod)
|
||||
return; /* Unable to proceed. */
|
||||
// Obtain the Squirrel API and VM
|
||||
_SqVM = _SqMod->GetSquirrelVM();
|
||||
// Make sure that a valid virtual machine exists
|
||||
if (!_SqVM)
|
||||
return; /* Unable to proceed. */
|
||||
// Set this as the default database
|
||||
DefaultVM::Set(_SqVM);
|
||||
// Register the module API
|
||||
RegisterAPI(_SqVM);
|
||||
// Notify about the current status
|
||||
OutputMessage("Registered: %s", SQMMDB_NAME);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* The virtual machine is about to be terminated and script resources should be released.
|
||||
*/
|
||||
void OnSquirrelTerminate()
|
||||
{
|
||||
OutputMessage("Terminating: %s", SQMMDB_NAME);
|
||||
// Release the current database (if any)
|
||||
DefaultVM::Set(NULL);
|
||||
// Release script resources...
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Validate the module API to make sure we don't run into issues.
|
||||
*/
|
||||
bool CheckAPIVer(CCStr ver)
|
||||
{
|
||||
// Obtain the numeric representation of the API version
|
||||
long vernum = strtol(ver, NULL, 10);
|
||||
// Check against version mismatch
|
||||
if (vernum == SQMOD_API_VER)
|
||||
return true;
|
||||
// Log the incident
|
||||
OutputError("API version mismatch on %s", SQMMDB_NAME);
|
||||
OutputMessage("=> Requested: %ld Have: %ld", vernum, SQMOD_API_VER);
|
||||
// Invoker should not attempt to communicate through the module API
|
||||
return false;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* React to command sent by other plugins.
|
||||
*/
|
||||
static int OnInternalCommand(unsigned int type, const char * text)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case SQMOD_INITIALIZE_CMD:
|
||||
if (CheckAPIVer(text))
|
||||
OnSquirrelInitialize();
|
||||
break;
|
||||
case SQMOD_LOAD_CMD:
|
||||
OnSquirrelLoad();
|
||||
break;
|
||||
case SQMOD_TERMINATE_CMD:
|
||||
OnSquirrelTerminate();
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* The server was initialized and this plugin was loaded successfully.
|
||||
*/
|
||||
static int OnInitServer()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void OnShutdownServer(void)
|
||||
{
|
||||
// The server may still send callbacks
|
||||
UnbindCallbacks();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void BindCallbacks()
|
||||
{
|
||||
_Clbk->OnInitServer = OnInitServer;
|
||||
_Clbk->OnInternalCommand = OnInternalCommand;
|
||||
_Clbk->OnShutdownServer = OnShutdownServer;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void UnbindCallbacks()
|
||||
{
|
||||
_Clbk->OnInitServer = NULL;
|
||||
_Clbk->OnInternalCommand = NULL;
|
||||
_Clbk->OnShutdownServer = NULL;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void RegisterAPI(HSQUIRRELVM vm)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void OutputMessageImpl(const char * msg, va_list args)
|
||||
{
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
HANDLE hstdout = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
|
||||
CONSOLE_SCREEN_BUFFER_INFO csb_before;
|
||||
GetConsoleScreenBufferInfo( hstdout, &csb_before);
|
||||
SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN);
|
||||
printf("[SQMOD] ");
|
||||
|
||||
SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY);
|
||||
vprintf(msg, args);
|
||||
puts("");
|
||||
|
||||
SetConsoleTextAttribute(hstdout, csb_before.wAttributes);
|
||||
#else
|
||||
printf("%c[0;32m[SQMOD]%c[0;37m", 27, 27, msg);
|
||||
vprintf(msg, args);
|
||||
puts("");
|
||||
#endif
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void OutputErrorImpl(const char * msg, va_list args)
|
||||
{
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
HANDLE hstdout = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
|
||||
CONSOLE_SCREEN_BUFFER_INFO csb_before;
|
||||
GetConsoleScreenBufferInfo( hstdout, &csb_before);
|
||||
SetConsoleTextAttribute(hstdout, FOREGROUND_RED | FOREGROUND_INTENSITY);
|
||||
printf("[SQMOD] ");
|
||||
|
||||
SetConsoleTextAttribute(hstdout, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY);
|
||||
vprintf(msg, args);
|
||||
puts("");
|
||||
|
||||
SetConsoleTextAttribute(hstdout, csb_before.wAttributes);
|
||||
#else
|
||||
printf("%c[0;32m[SQMOD]%c[0;37m", 27, 27, msg);
|
||||
vprintf(msg, args);
|
||||
puts("");
|
||||
#endif
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void OutputDebug(const char * msg, ...)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
// Initialize the arguments list
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
// Call the output function
|
||||
OutputMessageImpl(msg, args);
|
||||
// Finalize the arguments list
|
||||
va_end(args);
|
||||
#else
|
||||
SQMOD_UNUSED_VAR(msg);
|
||||
#endif
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void OutputMessage(const char * msg, ...)
|
||||
{
|
||||
// Initialize the arguments list
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
// Call the output function
|
||||
OutputMessageImpl(msg, args);
|
||||
// Finalize the arguments list
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
void OutputError(const char * msg, ...)
|
||||
{
|
||||
// Initialize the arguments list
|
||||
va_list args;
|
||||
va_start(args, msg);
|
||||
// Call the output function
|
||||
OutputErrorImpl(msg, args);
|
||||
// Finalize the arguments list
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs* functions, PluginCallbacks* callbacks, PluginInfo* info)
|
||||
{
|
||||
using namespace SqMod;
|
||||
// Output plugin header
|
||||
puts("");
|
||||
OutputMessage("--------------------------------------------------------------------");
|
||||
OutputMessage("Plugin: %s", SQMMDB_NAME);
|
||||
OutputMessage("Author: %s", SQMMDB_AUTHOR);
|
||||
OutputMessage("Legal: %s", SQMMDB_COPYRIGHT);
|
||||
OutputMessage("--------------------------------------------------------------------");
|
||||
puts("");
|
||||
// Attempt to find the host plugin ID
|
||||
int host_plugin_id = functions->FindPlugin((char *)(SQMOD_HOST_NAME));
|
||||
// See if our plugin was loaded after the host plugin
|
||||
if (host_plugin_id < 0)
|
||||
{
|
||||
OutputError("%s could find the host plugin", SQMMDB_NAME);
|
||||
// Don't load!
|
||||
return SQMOD_FAILURE;
|
||||
}
|
||||
// Should never reach this point but just in case
|
||||
else if (host_plugin_id > (info->nPluginId))
|
||||
{
|
||||
OutputError("%s loaded after the host plugin", SQMMDB_NAME);
|
||||
// Don't load!
|
||||
return SQMOD_FAILURE;
|
||||
}
|
||||
// Store server proxies
|
||||
_Func = functions;
|
||||
_Clbk = callbacks;
|
||||
_Info = info;
|
||||
// Assign plugin information
|
||||
_Info->uPluginVer = SQMMDB_VERSION;
|
||||
strcpy(_Info->szName, SQMMDB_HOST_NAME);
|
||||
// Bind callbacks
|
||||
BindCallbacks();
|
||||
// Notify that the plugin was successfully loaded
|
||||
OutputMessage("Successfully loaded %s", SQMMDB_NAME);
|
||||
// Dummy spacing
|
||||
puts("");
|
||||
// Done!
|
||||
return SQMOD_SUCCESS;
|
||||
}
|
41
modules/mmdb/Module.hpp
Normal file
41
modules/mmdb/Module.hpp
Normal file
@ -0,0 +1,41 @@
|
||||
#ifndef _SQMMDB_MODULE_HPP_
|
||||
#define _SQMMDB_MODULE_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "SqMod.h"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Proxies to comunicate with the server.
|
||||
*/
|
||||
extern PluginFuncs* _Func;
|
||||
extern PluginCallbacks* _Clbk;
|
||||
extern PluginInfo* _Info;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Proxies to comunicate with the Squirrel plugin.
|
||||
*/
|
||||
extern HSQAPI _SqAPI;
|
||||
extern HSQEXPORTS _SqMod;
|
||||
extern HSQUIRRELVM _SqVM;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Output a message only if the _DEBUG was defined.
|
||||
*/
|
||||
void OutputDebug(const char * msg, ...);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Output a formatted user message to the console.
|
||||
*/
|
||||
void OutputMessage(const char * msg, ...);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Output a formatted error message to the console.
|
||||
*/
|
||||
void OutputError(const char * msg, ...);
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _SQMMDB_MODULE_HPP_
|
68
modules/mmdb/SockAddr.cpp
Normal file
68
modules/mmdb/SockAddr.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Sockaddr.hpp"
|
||||
#include "Module.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger SockAddr::Typename(HSQUIRRELVM vm)
|
||||
{
|
||||
static const SQChar name[] = _SC("SqMMDBSockAddr");
|
||||
sq_pushstring(vm, name, sizeof(name));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void SockAddr::Validate() const
|
||||
{
|
||||
// Is the document handle valid?
|
||||
if (!m_Handle)
|
||||
SqThrowF("Invalid sockaddr structure handle");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SockAddr::SockAddr(CSStr addr)
|
||||
: m_Handle(NULL), m_Addres(_SC(""))
|
||||
{
|
||||
struct addrinfo hints;
|
||||
// Configure the hints structure
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_flags = AI_NUMERICHOST;
|
||||
// We set ai_socktype so that we only get one result back
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
// Attempt to obtain information about the specified address
|
||||
Int32 status = getaddrinfo(addr, NULL, &hints, &m_Handle);
|
||||
// Validate the success of the operation
|
||||
if (!status)
|
||||
{
|
||||
// See if we must free any handles (just in case)
|
||||
if (m_Handle)
|
||||
freeaddrinfo(m_Handle);
|
||||
// Now it's safe to throw the error
|
||||
SqThrowF("Unable to query the specified address for information [%s]", gai_strerror(status));
|
||||
}
|
||||
// Save the specified string address
|
||||
m_Addres.assign(addr ? addr : _SC(""));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SockAddr::~SockAddr()
|
||||
{
|
||||
if (m_Handle)
|
||||
freeaddrinfo(m_Handle);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 SockAddr::Cmp(const SockAddr & o) const
|
||||
{
|
||||
if (m_Handle == o.m_Handle)
|
||||
return 0;
|
||||
else if (m_Handle > o.m_Handle)
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
} // Namespace:: SqMod
|
147
modules/mmdb/Sockaddr.hpp
Normal file
147
modules/mmdb/Sockaddr.hpp
Normal file
@ -0,0 +1,147 @@
|
||||
#ifndef _SQMMDB_SOCKADDR_HPP_
|
||||
#define _SQMMDB_SOCKADDR_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Common.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Class that can obtain information from string addresses and be used repeatedly thereafter.
|
||||
*/
|
||||
class SockAddr
|
||||
{
|
||||
protected:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef struct addrinfo Type; // The managed type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Type* Pointer; // Pointer to the managed type.
|
||||
typedef const Type* ConstPtr; // Constant pointer to the managed type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Type& Reference; // Reference to the managed type.
|
||||
typedef const Type& ConstRef; // Constant reference to the managed type.
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Validate the sockaddr pointer and throw an error if invalid.
|
||||
*/
|
||||
void Validate() const;
|
||||
|
||||
private:
|
||||
|
||||
// ---------------------------------------------------------------------------------------------
|
||||
Pointer m_Handle; /* The managed sockaddr structure. */
|
||||
String m_Addres; /* The address that was queried for information. */
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Default constructor.
|
||||
*/
|
||||
SockAddr()
|
||||
: m_Handle(NULL), m_Addres(_SC(""))
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Base constructor.
|
||||
*/
|
||||
SockAddr(CSStr addr);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor. (disabled)
|
||||
*/
|
||||
SockAddr(const SockAddr &) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move constructor.
|
||||
*/
|
||||
SockAddr(SockAddr && o)
|
||||
: m_Handle(o.m_Handle)
|
||||
, m_Addres(o.m_Addres)
|
||||
{
|
||||
o.m_Handle = nullptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~SockAddr();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator. (disabled)
|
||||
*/
|
||||
SockAddr & operator = (const SockAddr &) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
SockAddr & operator = (SockAddr && o)
|
||||
{
|
||||
if (m_Handle != o.m_Handle)
|
||||
{
|
||||
m_Handle = o.m_Handle;
|
||||
m_Addres = o.m_Addres;
|
||||
o.m_Handle = nullptr;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the internal addrinfo structure pointer.
|
||||
*/
|
||||
Pointer GetHandle()
|
||||
{
|
||||
return m_Handle;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the internal addrinfo structure pointer.
|
||||
*/
|
||||
Pointer GetHandle() const
|
||||
{
|
||||
return m_Handle;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to compare two instances of this type.
|
||||
*/
|
||||
Int32 Cmp(const SockAddr & o) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const
|
||||
{
|
||||
return m_Addres.c_str();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to retrieve the name from instances of this type.
|
||||
*/
|
||||
static SQInteger Typename(HSQUIRRELVM vm);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether this instance references a valid addrinfo structure.
|
||||
*/
|
||||
bool IsValid() const
|
||||
{
|
||||
return m_Handle;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the associated string address.
|
||||
*/
|
||||
CSStr GetAddress() const
|
||||
{
|
||||
return m_Addres.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _SQMMDB_SOCKADDR_HPP_
|
@ -389,7 +389,7 @@ SQInteger Connection::ExecF(HSQUIRRELVM vm)
|
||||
SQRESULT ret = sqstd_format(vm, 3, &len, &sql);
|
||||
// Did the format failed?
|
||||
if (SQ_FAILED(ret))
|
||||
return ret;
|
||||
return ret; // Propagate the exception
|
||||
// Attempt to execute the resulted query
|
||||
if ((inst.value->m_Handle = sqlite3_exec(inst.value->m_Handle, sql, NULL, NULL, NULL)) != SQLITE_OK)
|
||||
{
|
||||
@ -399,7 +399,7 @@ SQInteger Connection::ExecF(HSQUIRRELVM vm)
|
||||
// Push the result onto the stack
|
||||
sq_pushinteger(vm, sqlite3_changes(inst.value->m_Handle));
|
||||
}
|
||||
// All methods of retrieving the message value failed
|
||||
// All methods of retrieving the string value failed
|
||||
else
|
||||
return sq_throwerror(vm, "Unable to extract the query string");
|
||||
// At this point we should have a return value on the stack
|
||||
@ -455,14 +455,14 @@ SQInteger Connection::QueueF(HSQUIRRELVM vm)
|
||||
SQRESULT ret = sqstd_format(vm, 3, &len, &sql);
|
||||
// Did the format failed?
|
||||
if (SQ_FAILED(ret))
|
||||
return ret;
|
||||
return ret; // Propagate the exception
|
||||
// Is there even a query to queue?
|
||||
else if (IsQueryEmpty(sql))
|
||||
return sq_throwerror(vm,"No query to queue");
|
||||
// Attempt to queue the specified query
|
||||
inst.value->m_Handle->mQueue.push_back(sql);
|
||||
}
|
||||
// All methods of retrieving the message value failed
|
||||
// All methods of retrieving the string value failed
|
||||
else
|
||||
return sq_throwerror(vm, "Unable to extract the query string");
|
||||
// This function does not return a value
|
||||
@ -519,7 +519,7 @@ SQInteger Connection::QueryF(HSQUIRRELVM vm)
|
||||
SQRESULT ret = sqstd_format(vm, 3, &len, &sql);
|
||||
// Did the format failed?
|
||||
if (SQ_FAILED(ret))
|
||||
return ret;
|
||||
return ret; // Propagate the exception
|
||||
// Attempt to create a statement with the specified query
|
||||
try
|
||||
{
|
||||
@ -530,7 +530,7 @@ SQInteger Connection::QueryF(HSQUIRRELVM vm)
|
||||
return sq_throwerror(vm, e.Message().c_str());
|
||||
}
|
||||
}
|
||||
// All methods of retrieving the message value failed
|
||||
// All methods of retrieving the string value failed
|
||||
else
|
||||
return sq_throwerror(vm, "Unable to extract the query string");
|
||||
// At this point we should have a return value on the stack
|
||||
|
@ -58,17 +58,19 @@ extern "C" {
|
||||
#define SQMOD_TERMINATE_CMD 0xDEADC0DE
|
||||
#define SQMOD_API_VER 1
|
||||
|
||||
/*primitive functions*/
|
||||
//primitive functions
|
||||
typedef HSQAPI (*SqEx_GetSquirrelAPI) (void);
|
||||
typedef HSQUIRRELVM (*SqEx_GetSquirrelVM) (void);
|
||||
/*logging utilities*/
|
||||
//logging utilities
|
||||
typedef void (*SqEx_LogMessage) (const SQChar * fmt, ...);
|
||||
/*long numbers*/
|
||||
//script loading
|
||||
typedef SQRESULT (*SqEx_LoadScript) (const SQChar * filepath);
|
||||
//long numbers
|
||||
typedef SQRESULT (*SqEx_GetSLongValue) (HSQUIRRELVM vm, SQInteger idx, SqInt64 * num);
|
||||
typedef void (*SqEx_PushSLongObject) (HSQUIRRELVM vm, SqInt64 num);
|
||||
typedef SQRESULT (*SqEx_GetULongValue) (HSQUIRRELVM vm, SQInteger idx, SqUint64 * num);
|
||||
typedef void (*SqEx_PushULongObject) (HSQUIRRELVM vm, SqUint64 num);
|
||||
/*time utilities*/
|
||||
//time utilities
|
||||
typedef SqInt64 (*SqEx_GetCurrentSysTime) (void);
|
||||
typedef SqInt64 (*SqEx_GetEpochTimeMicro) (void);
|
||||
typedef SqInt64 (*SqEx_GetEpochTimeMilli) (void);
|
||||
@ -80,11 +82,11 @@ extern "C" {
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
unsigned int uStructSize;
|
||||
/*primitive functions*/
|
||||
unsigned int StructSize;
|
||||
//primitive functions
|
||||
SqEx_GetSquirrelAPI GetSquirrelAPI;
|
||||
SqEx_GetSquirrelVM GetSquirrelVM;
|
||||
/*logging utilities*/
|
||||
//logging utilities
|
||||
SqEx_LogMessage LogDbg;
|
||||
SqEx_LogMessage LogUsr;
|
||||
SqEx_LogMessage LogScs;
|
||||
@ -99,6 +101,8 @@ extern "C" {
|
||||
SqEx_LogMessage LogSWrn;
|
||||
SqEx_LogMessage LogSErr;
|
||||
SqEx_LogMessage LogSFtl;
|
||||
//script loading
|
||||
SqEx_LoadScript LoadScript;
|
||||
/*long numbers*/
|
||||
SqEx_GetSLongValue GetSLongValue;
|
||||
SqEx_PushSLongObject PushSLongObject;
|
||||
|
@ -14,6 +14,14 @@ const AABB AABB::MAX = AABB(Vector3::MIN, Vector3::MAX);
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQChar AABB::Delim = ',';
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger AABB::Typename(HSQUIRRELVM vm)
|
||||
{
|
||||
static SQChar name[] = _SC("AABB");
|
||||
sq_pushstring(vm, name, sizeof(name));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AABB::AABB()
|
||||
: min(-1.0), max(1.0)
|
||||
@ -49,27 +57,6 @@ AABB::AABB(const Vector3 & vmin, const Vector3 & vmax)
|
||||
/* ... */
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AABB::AABB(const AABB & b)
|
||||
: min(b.min), max(b.max)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AABB::~AABB()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AABB & AABB::operator = (const AABB & b)
|
||||
{
|
||||
min = b.min;
|
||||
max = b.max;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AABB & AABB::operator = (Value s)
|
||||
{
|
||||
@ -304,7 +291,7 @@ Int32 AABB::Cmp(const AABB & o) const
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr AABB::ToString() const
|
||||
{
|
||||
return ToStringF("%f,%f,%f,%f,%f,%f", min.x, min.y, min.z, max.x, max.y, max.z);
|
||||
return ToStrF("%f,%f,%f,%f,%f,%f", min.x, min.y, min.z, max.x, max.y, max.z);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -392,6 +379,7 @@ void Register_AABB(HSQUIRRELVM vm)
|
||||
.Prop(_SC("abs"), &AABB::Abs)
|
||||
/* Core Metamethods */
|
||||
.Func(_SC("_tostring"), &AABB::ToString)
|
||||
.SquirrelFunc(_SC("_typename"), &AABB::Typename)
|
||||
.Func(_SC("_cmp"), &AABB::Cmp)
|
||||
/* Metamethods */
|
||||
.Func<AABB (AABB::*)(const AABB &) const>(_SC("_add"), &AABB::operator +)
|
||||
|
@ -8,304 +8,328 @@
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Class used to represent an axis aligned bounding box in three-dimensional space.
|
||||
*/
|
||||
struct AABB
|
||||
{
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* The type of value used by components of type.
|
||||
*/
|
||||
typedef float Value;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Helper instances for common values mostly used as return types or comparison.
|
||||
*/
|
||||
static const AABB NIL;
|
||||
static const AABB MIN;
|
||||
static const AABB MAX;
|
||||
static const AABB MIN;
|
||||
static const AABB MAX;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* The delimiter character to be used when extracting values from strings.
|
||||
*/
|
||||
static SQChar Delim;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* The minimum and maximum components of this type.
|
||||
*/
|
||||
Vector3 min, max;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Default constructor.
|
||||
*/
|
||||
AABB();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Construct a an equally sized and perfectly shaped box from a scalar value.
|
||||
*/
|
||||
AABB(Value sv);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Construct a an equally sized but imperfectly shaped box from individual components of a
|
||||
* three-dimensional point.
|
||||
*/
|
||||
AABB(Value xv, Value yv, Value zv);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Construct a an unequally sized and imperfectly shaped box from individual components of two
|
||||
* three-dimensional points.
|
||||
*/
|
||||
AABB(Value xmin, Value ymin, Value zmin, Value xmax, Value ymax, Value zmax);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Construct a an unequally sized and imperfectly shaped box from two three-dimensional
|
||||
* vectors representing two three-dimensional points.
|
||||
*/
|
||||
AABB(const Vector3 & vmin, const Vector3 & vmax);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Copy constructor.
|
||||
*/
|
||||
AABB(const AABB & o);
|
||||
AABB(const AABB & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Move constructor.
|
||||
*/
|
||||
~AABB();
|
||||
AABB(AABB && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Destructor.
|
||||
*/
|
||||
AABB & operator = (const AABB & o);
|
||||
~AABB() = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
AABB & operator = (const AABB & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
AABB & operator = (AABB && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Scalar value assignment operator.
|
||||
*/
|
||||
AABB & operator = (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Three-dimensional vector assignment operator.
|
||||
*/
|
||||
AABB & operator = (const Vector3 & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Four-dimensional vector assignment operator threated as a three-dimensional vector.
|
||||
*/
|
||||
AABB & operator = (const Vector4 & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Addition assignment operator.
|
||||
*/
|
||||
AABB & operator += (const AABB & b);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Subtraction assignment operator.
|
||||
*/
|
||||
AABB & operator -= (const AABB & b);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Multiplication assignment operator.
|
||||
*/
|
||||
AABB & operator *= (const AABB & b);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Division assignment operator.
|
||||
*/
|
||||
AABB & operator /= (const AABB & b);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Modulo assignment operator.
|
||||
*/
|
||||
AABB & operator %= (const AABB & b);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value addition assignment operator.
|
||||
*/
|
||||
AABB & operator += (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value subtraction assignment operator.
|
||||
*/
|
||||
AABB & operator -= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value multiplication assignment operator.
|
||||
*/
|
||||
AABB & operator *= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value division assignment operator.
|
||||
*/
|
||||
AABB & operator /= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value modulo assignment operator.
|
||||
*/
|
||||
AABB & operator %= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Pre-increment operator.
|
||||
*/
|
||||
AABB & operator ++ ();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Pre-decrement operator.
|
||||
*/
|
||||
AABB & operator -- ();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Post-increment operator.
|
||||
*/
|
||||
AABB operator ++ (int);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Post-decrement operator.
|
||||
*/
|
||||
AABB operator -- (int);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Addition operator.
|
||||
*/
|
||||
AABB operator + (const AABB & b) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Subtraction operator.
|
||||
*/
|
||||
AABB operator - (const AABB & b) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Multiplication operator.
|
||||
*/
|
||||
AABB operator * (const AABB & b) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Division operator.
|
||||
*/
|
||||
AABB operator / (const AABB & b) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Modulo operator.
|
||||
*/
|
||||
AABB operator % (const AABB & b) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value addition operator.
|
||||
*/
|
||||
AABB operator + (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value subtraction operator.
|
||||
*/
|
||||
AABB operator - (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value multiplication operator.
|
||||
*/
|
||||
AABB operator * (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value division operator.
|
||||
*/
|
||||
AABB operator / (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value modulo operator.
|
||||
*/
|
||||
AABB operator % (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Unary plus operator.
|
||||
*/
|
||||
AABB operator + () const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Unary minus operator.
|
||||
*/
|
||||
AABB operator - () const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Equality comparison operator.
|
||||
*/
|
||||
bool operator == (const AABB & b) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Inequality comparison operator.
|
||||
*/
|
||||
bool operator != (const AABB & b) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Less than comparison operator.
|
||||
*/
|
||||
bool operator < (const AABB & b) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Greater than comparison operator.
|
||||
*/
|
||||
bool operator > (const AABB & b) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Less than or equal comparison operator.
|
||||
*/
|
||||
bool operator <= (const AABB & b) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Greater than or equal comparison operator.
|
||||
*/
|
||||
bool operator >= (const AABB & b) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Used by the script engine to compare two instances of this type.
|
||||
*/
|
||||
Int32 Cmp(const AABB & b) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Used by the script engine to retrieve the name from instances of this type.
|
||||
*/
|
||||
static SQInteger Typename(HSQUIRRELVM vm);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Set an equally sized and perfectly shaped box from a scalar value.
|
||||
*/
|
||||
void Set(Value ns);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set an equally sized but imperfectly shaped box from individual components of a
|
||||
* three-dimensional point.
|
||||
*/
|
||||
void Set(Value nx, Value ny, Value nz);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set an unequally sized and imperfectly shaped box from individual components of two
|
||||
* three-dimensional points.
|
||||
*/
|
||||
void Set(Value xmin, Value ymin, Value zmin, Value xmax, Value ymax, Value zmax);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set the same box from another instance of this type.
|
||||
*/
|
||||
void Set(const AABB & b);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set an equally sized and imperfectly shaped box from a single three-dimensional vector
|
||||
* representing a single three-dimensional point.
|
||||
*/
|
||||
void Set(const Vector3 & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set an unequally sized and imperfectly shaped box from two three-dimensional vectors
|
||||
* representing two three-dimensional points.
|
||||
*/
|
||||
void Set(const Vector3 & nmin, const Vector3 & nmax);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set an equally sized and imperfectly shaped box from a single four-dimensional vector
|
||||
* representing a single three-dimensional point.
|
||||
*/
|
||||
void Set(const Vector4 & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set an unequally sized and imperfectly shaped box from two four-dimensional vectors
|
||||
* representing two three-dimensional points.
|
||||
*/
|
||||
void Set(const Vector4 & nmin, const Vector4 & nmax);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set the values extracted from the specified string using the specified delimiter.
|
||||
*/
|
||||
void Set(CSStr values, SQChar delim);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Clear the component values to default.
|
||||
*/
|
||||
void Clear()
|
||||
{
|
||||
@ -314,7 +338,7 @@ static const AABB MAX;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Retrieve a new instance of this type with absolute component values.
|
||||
*/
|
||||
AABB Abs() const;
|
||||
};
|
||||
|
@ -1,10 +1,10 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Base/Buffer.hpp"
|
||||
#include "Buffer.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cstdarg>
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
|
||||
@ -14,7 +14,7 @@ namespace SqMod {
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Compute the next power of two for the specified number.
|
||||
*/
|
||||
static inline unsigned int NPow2(unsigned int num)
|
||||
inline unsigned int NextPow2(unsigned int num)
|
||||
{
|
||||
--num;
|
||||
num |= num >> 1;
|
||||
@ -40,9 +40,7 @@ void ThrowMemExcept(const char * msg, ...)
|
||||
int ret = vsnprintf(buffer, sizeof(buffer), msg, args);
|
||||
// Check for formatting errors
|
||||
if (ret < 0)
|
||||
{
|
||||
throw std::runtime_error("Unknown memory error");
|
||||
}
|
||||
// Throw the actual exception
|
||||
throw std::runtime_error(buffer);
|
||||
}
|
||||
@ -53,12 +51,10 @@ void ThrowMemExcept(const char * msg, ...)
|
||||
static Buffer::Pointer AllocMem(Buffer::SzType size)
|
||||
{
|
||||
// Attempt to allocate memory directly
|
||||
Buffer::Pointer ptr = (Buffer::Pointer)malloc(size);
|
||||
Buffer::Pointer ptr = reinterpret_cast< Buffer::Pointer >(malloc(size));
|
||||
// Validate the allocated memory
|
||||
if (!ptr)
|
||||
{
|
||||
ThrowMemExcept("Unable to allocate (%u) bytes of memory", size);
|
||||
}
|
||||
// Return the allocated memory
|
||||
return ptr;
|
||||
}
|
||||
@ -75,36 +71,36 @@ class MemCat
|
||||
public:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Buffer::Value Value;
|
||||
typedef Buffer::Value Value; // The type of value used to represent a byte.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Buffer::Reference Reference;
|
||||
typedef Buffer::ConstRef ConstRef;
|
||||
typedef Buffer::Reference Reference; // A reference to the stored value type.
|
||||
typedef Buffer::ConstRef ConstRef; // A const reference to the stored value type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Buffer::Pointer Pointer;
|
||||
typedef Buffer::ConstPtr ConstPtr;
|
||||
typedef Buffer::Pointer Pointer; // A pointer to the stored value type.
|
||||
typedef Buffer::ConstPtr ConstPtr; // A const pointer to the stored value type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Buffer::SzType SzType;
|
||||
typedef Buffer::SzType SzType; // The type used to represent size in general.
|
||||
|
||||
private:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Structure used to store a memory chunk in the linked list.
|
||||
*/
|
||||
struct Node
|
||||
{
|
||||
// ----------------------------------------------------------------------------------------
|
||||
SzType mCap;
|
||||
Pointer mPtr;
|
||||
Node* mNext;
|
||||
SzType mCap; /* The size of the memory chunk. */
|
||||
Pointer mPtr; /* Pointer to the memory chunk. */
|
||||
Node* mNext; /* The next node in the list. */
|
||||
|
||||
/* ----------------------------------------------------------------------------------------
|
||||
* Base constructor.
|
||||
*/
|
||||
Node(Node * next)
|
||||
: mCap(0), mPtr(NULL), mNext(next)
|
||||
: mCap(0), mPtr(nullptr), mNext(next)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
@ -120,7 +116,7 @@ private:
|
||||
* Default constructor.
|
||||
*/
|
||||
MemCat()
|
||||
: m_Head(NULL)
|
||||
: m_Head(nullptr)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
@ -130,20 +126,18 @@ private:
|
||||
*/
|
||||
~MemCat()
|
||||
{
|
||||
for (Node * node = m_Head, * next = NULL; node; node = next)
|
||||
for (Node * node = m_Head, * next = nullptr; node; node = next)
|
||||
{
|
||||
// Free the memory (if any)
|
||||
if (node->mPtr)
|
||||
{
|
||||
free(node->mPtr);
|
||||
}
|
||||
// Save the next node
|
||||
next = node->mNext;
|
||||
// Release the node instance
|
||||
delete node;
|
||||
}
|
||||
// Explicitly set the head node to null
|
||||
m_Head = NULL;
|
||||
m_Head = nullptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
@ -151,20 +145,18 @@ private:
|
||||
*/
|
||||
void Clear()
|
||||
{
|
||||
for (Node * node = m_Head, * next = NULL; node; node = next)
|
||||
for (Node * node = m_Head, * next = nullptr; node; node = next)
|
||||
{
|
||||
// Free the memory (if any)
|
||||
if (node->mPtr)
|
||||
{
|
||||
free(node->mPtr);
|
||||
}
|
||||
// Save the next node
|
||||
next = node->mNext;
|
||||
// Release the node instance
|
||||
Push(node);
|
||||
}
|
||||
// Explicitly set the head node to null
|
||||
m_Head = NULL;
|
||||
m_Head = nullptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
@ -174,21 +166,17 @@ private:
|
||||
{
|
||||
// NOTE: Function assumes (size > 0)
|
||||
// Find a buffer large enough to satisfy the requested size
|
||||
for (Node * node = m_Head, * prev = NULL; node; prev = node, node = node->mNext)
|
||||
for (Node * node = m_Head, * prev = nullptr; node; prev = node, node = node->mNext)
|
||||
{
|
||||
// Is this buffer large enough?
|
||||
if (node->mCap >= size)
|
||||
{
|
||||
// Was there a previous node?
|
||||
if (prev)
|
||||
{
|
||||
prev->mNext = node->mNext;
|
||||
}
|
||||
// Probably this was the head
|
||||
else
|
||||
{
|
||||
m_Head = node->mNext;
|
||||
}
|
||||
// Assign the memory
|
||||
ptr = node->mPtr;
|
||||
// Assign the size
|
||||
@ -200,10 +188,11 @@ private:
|
||||
}
|
||||
}
|
||||
// Round up the size to a power of two number
|
||||
size = (size & (size - 1)) ? NPow2(size) : size;
|
||||
size = (size & (size - 1)) ? NextPow2(size) : size;
|
||||
// Allocate the memory directly
|
||||
ptr = AllocMem(size);
|
||||
// See if the memory could be allocated
|
||||
// (shouldn't reach this point if allocation failed)
|
||||
if (!ptr)
|
||||
{
|
||||
// Revert the size
|
||||
@ -219,9 +208,7 @@ private:
|
||||
void Drop(Pointer & ptr, SzType & size)
|
||||
{
|
||||
if (!ptr)
|
||||
{
|
||||
ThrowMemExcept("Cannot store invalid memory buffer");
|
||||
}
|
||||
// Request a node instance
|
||||
Node * node = Pull();
|
||||
// Assign the specified memory
|
||||
@ -245,9 +232,7 @@ private:
|
||||
s_Nodes = new Node(s_Nodes);
|
||||
// Validate the head node
|
||||
if (!s_Nodes)
|
||||
{
|
||||
ThrowMemExcept("Unable to allocate memory nodes");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -256,10 +241,9 @@ private:
|
||||
*/
|
||||
static Node * Pull()
|
||||
{
|
||||
// Are there any nodes available?
|
||||
if (!s_Nodes)
|
||||
{
|
||||
Make();
|
||||
}
|
||||
Make(); // Make some!
|
||||
// Grab the head node
|
||||
Node * node = s_Nodes;
|
||||
// Promote the next node as the head
|
||||
@ -275,9 +259,7 @@ private:
|
||||
{
|
||||
// See if the node is even valid
|
||||
if (!node)
|
||||
{
|
||||
ThrowMemExcept("Attempting to push invalid node");
|
||||
}
|
||||
// Demote the current head node
|
||||
node->mNext = s_Nodes;
|
||||
// Promote as the head node
|
||||
@ -286,7 +268,7 @@ private:
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
MemCat::Node * MemCat::s_Nodes = NULL;
|
||||
MemCat::Node * MemCat::s_Nodes = nullptr;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Lightweight memory allocator to reduce the overhead of small allocations.
|
||||
@ -294,8 +276,8 @@ MemCat::Node * MemCat::s_Nodes = NULL;
|
||||
class Memory
|
||||
{
|
||||
// --------------------------------------------------------------------------------------------
|
||||
friend class Buffer;
|
||||
friend class MemRef;
|
||||
friend class Buffer; // Allow the buffer type to access the memory categories.
|
||||
friend class MemRef; // Allow the memory manager reference to create new instances.
|
||||
|
||||
private:
|
||||
|
||||
@ -316,7 +298,7 @@ private:
|
||||
*/
|
||||
~Memory()
|
||||
{
|
||||
for (MemCat::Node * node = MemCat::s_Nodes, * next = NULL; node; node = next)
|
||||
for (MemCat::Node * node = MemCat::s_Nodes, * next = nullptr; node; node = next)
|
||||
{
|
||||
// Save the next node
|
||||
next = node->mNext;
|
||||
@ -324,13 +306,15 @@ private:
|
||||
delete node;
|
||||
}
|
||||
// Explicitly set the head node to null
|
||||
MemCat::s_Nodes = NULL;
|
||||
MemCat::s_Nodes = nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
MemCat m_Small, m_Medium, m_Large;
|
||||
MemCat m_Small; // Small memory allocations of <= 1024 bytes.
|
||||
MemCat m_Medium; // Medium memory allocations of <= 4096 bytes.
|
||||
MemCat m_Large; // Large memory allocations of <= 4096 bytes.
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -340,9 +324,7 @@ MemRef MemRef::s_Mem;
|
||||
void MemRef::Grab()
|
||||
{
|
||||
if (m_Ptr)
|
||||
{
|
||||
++(*m_Ref);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -352,8 +334,8 @@ void MemRef::Drop()
|
||||
{
|
||||
delete m_Ptr;
|
||||
delete m_Ref;
|
||||
m_Ptr = NULL;
|
||||
m_Ref = NULL;
|
||||
m_Ptr = nullptr;
|
||||
m_Ref = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@ -369,13 +351,9 @@ const MemRef & MemRef::Get()
|
||||
return s_Mem;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Buffer::Pointer Buffer::s_Ptr = NULL;
|
||||
Buffer::SzType Buffer::s_Cap = 0;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Buffer::Buffer(const Buffer & o)
|
||||
: m_Ptr(NULL)
|
||||
: m_Ptr(nullptr)
|
||||
, m_Cap(0)
|
||||
, m_Mem(o.m_Mem)
|
||||
{
|
||||
@ -389,10 +367,9 @@ Buffer::Buffer(const Buffer & o)
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Buffer::~Buffer()
|
||||
{
|
||||
// Do we have a buffer?
|
||||
if (m_Ptr)
|
||||
{
|
||||
Release();
|
||||
}
|
||||
Release(); // Release it!
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -400,24 +377,25 @@ Buffer & Buffer::operator = (const Buffer & o)
|
||||
{
|
||||
if (m_Ptr != o.m_Ptr)
|
||||
{
|
||||
// Can we work in the current buffer?
|
||||
if (m_Cap && o.m_Cap <= m_Cap)
|
||||
{
|
||||
// It's safe to copy the data
|
||||
memcpy(m_Ptr, o.m_Ptr, m_Cap);
|
||||
}
|
||||
// Do we even have data to copy?
|
||||
else if (!o.m_Cap)
|
||||
{
|
||||
// Do we have a buffer?
|
||||
if (m_Ptr)
|
||||
{
|
||||
Release();
|
||||
}
|
||||
Release(); // Release it!
|
||||
}
|
||||
else
|
||||
{
|
||||
// Do we have a buffer?
|
||||
if (m_Ptr)
|
||||
{
|
||||
Release();
|
||||
}
|
||||
Release(); // Release it!
|
||||
// Request a larger buffer
|
||||
Request(o.m_Cap);
|
||||
// Now it's safe to copy the data
|
||||
memcpy(m_Ptr, o.m_Ptr, o.m_Cap);
|
||||
}
|
||||
}
|
||||
@ -433,67 +411,51 @@ void Buffer::Request(SzType n)
|
||||
if (!m_Mem)
|
||||
{
|
||||
// Round up the size to a power of two number
|
||||
n = (n & (n - 1)) ? NPow2(n) : n;
|
||||
n = (n & (n - 1)) ? NextPow2(n) : n;
|
||||
// Allocate the memory directly
|
||||
m_Ptr = AllocMem(n);
|
||||
}
|
||||
// Find out in which category does this buffer reside
|
||||
else if (n <= 1024)
|
||||
{
|
||||
m_Mem->m_Small.Grab(m_Ptr, n);
|
||||
}
|
||||
else if (n <= 4096)
|
||||
{
|
||||
m_Mem->m_Medium.Grab(m_Ptr, n);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Mem->m_Large.Grab(m_Ptr, n);
|
||||
}
|
||||
// If no errors occured then we can set the size
|
||||
m_Cap= n;
|
||||
// If no errors occurred then we can set the size
|
||||
m_Cap = n;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Buffer::Release()
|
||||
{
|
||||
// TODO: Implement a limit on how much memory can actually be pooled.
|
||||
// Is there a memory manager available?
|
||||
if (!m_Mem)
|
||||
{
|
||||
// Deallocate the memory directly
|
||||
free(m_Ptr);
|
||||
}
|
||||
free(m_Ptr); // Deallocate the memory directly
|
||||
// Find out to which category does this buffer belong
|
||||
else if (m_Cap <= 1024)
|
||||
{
|
||||
m_Mem->m_Small.Drop(m_Ptr, m_Cap);
|
||||
}
|
||||
else if (m_Cap <= 4096)
|
||||
{
|
||||
m_Mem->m_Medium.Drop(m_Ptr, m_Cap);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Mem->m_Large.Drop(m_Ptr, m_Cap);
|
||||
}
|
||||
// Explicitly reset the buffer
|
||||
m_Ptr = NULL;
|
||||
m_Ptr = nullptr;
|
||||
m_Cap = 0;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Buffer::SzType Buffer::Write(SzType pos, ConstPtr data, SzType size)
|
||||
{
|
||||
// Make sure the pos is not out of bounds
|
||||
// Make sure the position is not out of bounds
|
||||
if (pos > m_Cap || !data || !size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
// See if the buffer size must be adjusted
|
||||
else if ((pos + size) >= m_Cap)
|
||||
{
|
||||
// Backup current data
|
||||
Buffer bkp = Adjust< Value >(pos + size);
|
||||
// Allocate a larger memory chunk and backup old data
|
||||
Buffer bkp(Adjust< Value >(NextPow2(pos + size)));
|
||||
// Copy data back from the old buffer
|
||||
memcpy(m_Ptr, bkp.m_Ptr, bkp.m_Cap);
|
||||
}
|
||||
@ -506,48 +468,44 @@ Buffer::SzType Buffer::Write(SzType pos, ConstPtr data, SzType size)
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Buffer::SzType Buffer::WriteF(SzType pos, const char * fmt, ...)
|
||||
{
|
||||
// Make sure the pos is not out of bounds
|
||||
if (pos > m_Cap)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
// Initialize the arguments list
|
||||
// Initialize the variable argument list
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
// Initial attempt to write to the current buffer
|
||||
// (if empty, it should tell us the necessary size)
|
||||
int ret = vsnprintf(m_Ptr + pos, m_Cap - pos, fmt, args);
|
||||
// Do we need a bigger buffer?
|
||||
if ((pos + ret) >= m_Cap)
|
||||
{
|
||||
// Backup current data
|
||||
Buffer bkp = Adjust< Value >(pos + ret);
|
||||
// Copy data back from the old buffer
|
||||
memcpy(m_Ptr, bkp.m_Ptr, bkp.m_Cap);
|
||||
// Argument list was modified during the initial format
|
||||
va_end(args);
|
||||
va_start(args, fmt);
|
||||
// Resume writting the requested information
|
||||
ret = vsnprintf(m_Ptr + pos, m_Cap - pos, fmt, args);
|
||||
}
|
||||
// Finalize the arguments list
|
||||
// Call the function that takes the variable argument list
|
||||
SzType ret = WriteF(pos, fmt, args);
|
||||
// Finalize the variable argument list
|
||||
va_end(args);
|
||||
// Return the size of the written data in bytes
|
||||
return (ret < 0) ? 0 : (SzType)ret;
|
||||
// Return the result
|
||||
return ret;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Buffer::SzType Buffer::WriteF(SzType pos, const char * fmt, va_list args)
|
||||
{
|
||||
// Make sure the pos is not out of bounds
|
||||
// Make sure the position is not out of bounds
|
||||
if (pos > m_Cap)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
// Backup the variable argument list
|
||||
va_list args_cpy;
|
||||
va_copy(args_cpy, args);
|
||||
// Attempt to write to the current buffer
|
||||
int ret = vsnprintf(m_Ptr + pos, m_Cap - pos, fmt, args);
|
||||
// Return the size of the written data in bytes
|
||||
return (ret < 0) ? 0 : (SzType)ret;
|
||||
// (if empty, it should tell us the necessary size)
|
||||
int ret = vsnprintf(m_Ptr + pos, m_Cap, fmt, args);
|
||||
// Do we need a bigger buffer?
|
||||
if ((pos + ret) >= m_Cap)
|
||||
{
|
||||
// Allocate a larger memory chunk and backup old data
|
||||
Buffer bkp(Adjust< Value >(NextPow2(pos + ret)));
|
||||
// Copy data back from the old buffer
|
||||
memcpy(m_Ptr, bkp.m_Ptr, bkp.m_Cap);
|
||||
// Retry writing the requested information
|
||||
ret = vsnprintf(m_Ptr + pos, m_Cap, fmt, args_cpy);
|
||||
}
|
||||
// Return the value 0 if data could not be written
|
||||
if (ret < 0)
|
||||
return 0;
|
||||
// Return the number of written characters
|
||||
return static_cast< SzType >(ret);
|
||||
}
|
||||
|
||||
} // Namespace:: SQMod
|
||||
} // Namespace:: SqMod
|
||||
|
@ -2,7 +2,10 @@
|
||||
#define _BASE_BUFFER_HPP_
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <assert.h>
|
||||
#include <cassert>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <utility>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
@ -64,6 +67,17 @@ public:
|
||||
Grab();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move constructor.
|
||||
*/
|
||||
MemRef(MemRef && o)
|
||||
: m_Ptr(o.m_Ptr), m_Ref(o.m_Ref)
|
||||
|
||||
{
|
||||
o.m_Ptr = nullptr;
|
||||
o.m_Ref = nullptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
@ -87,6 +101,22 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
MemRef & operator = (MemRef && o)
|
||||
{
|
||||
if (m_Ptr != o.m_Ptr)
|
||||
{
|
||||
Drop();
|
||||
m_Ptr = o.m_Ptr;
|
||||
m_Ref = o.m_Ref;
|
||||
o.m_Ptr = nullptr;
|
||||
o.m_Ref = nullptr;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Perform an equality comparison between two memory managers.
|
||||
*/
|
||||
@ -116,7 +146,7 @@ public:
|
||||
*/
|
||||
Memory * operator -> () const
|
||||
{
|
||||
assert(m_Ptr != NULL);
|
||||
assert(m_Ptr);
|
||||
return m_Ptr;
|
||||
}
|
||||
|
||||
@ -125,7 +155,7 @@ public:
|
||||
*/
|
||||
Memory & operator * () const
|
||||
{
|
||||
assert(m_Ptr != NULL);
|
||||
assert(m_Ptr);
|
||||
return *m_Ptr;
|
||||
}
|
||||
};
|
||||
@ -134,43 +164,58 @@ public:
|
||||
void ThrowMemExcept(const char * msg, ...);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Reusable buffer memory for quick allocations.
|
||||
* Reusable and re-scalable buffer memory for quick memory allocations.
|
||||
*/
|
||||
class Buffer
|
||||
{
|
||||
public:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef char Value; /* The type of value used to represent a byte. */
|
||||
typedef char Value; // The type of value used to represent a byte.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Value & Reference; /* A reference to the stored value type. */
|
||||
typedef const Value & ConstRef; /* A const reference to the stored value type. */
|
||||
typedef Value & Reference; // A reference to the stored value type.
|
||||
typedef const Value & ConstRef; // A const reference to the stored value type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef Value * Pointer; /* A pointer to the stored value type. */
|
||||
typedef const Value * ConstPtr; /* A const pointer to the stored value type. */
|
||||
typedef Value * Pointer; // A pointer to the stored value type.
|
||||
typedef const Value * ConstPtr; // A const pointer to the stored value type.
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef unsigned int SzType; /* The type used to represent size in general. */
|
||||
typedef unsigned int SzType; // The type used to represent size in general.
|
||||
|
||||
private:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Construct and take ownership of the specified buffer.
|
||||
*/
|
||||
Buffer(Pointer & ptr, SzType & cap, const MemRef & mem)
|
||||
: m_Ptr(ptr)
|
||||
, m_Cap(cap)
|
||||
, m_Mem(mem)
|
||||
{
|
||||
ptr = nullptr;
|
||||
cap = 0;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Default constructor (null). Not null of a previous buffer was marked as movable.
|
||||
*/
|
||||
Buffer()
|
||||
: m_Ptr(s_Ptr)
|
||||
, m_Cap(s_Cap)
|
||||
: m_Ptr(nullptr)
|
||||
, m_Cap(0)
|
||||
, m_Mem(MemRef::Get())
|
||||
{
|
||||
s_Ptr = NULL;
|
||||
s_Cap = 0;
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Explicit size constructor.
|
||||
*/
|
||||
Buffer(SzType n)
|
||||
: m_Ptr(NULL)
|
||||
: m_Ptr(nullptr)
|
||||
, m_Cap(0)
|
||||
, m_Mem(MemRef::Get())
|
||||
{
|
||||
@ -182,6 +227,15 @@ public:
|
||||
*/
|
||||
Buffer(const Buffer & o);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move constructor.
|
||||
*/
|
||||
Buffer(Buffer && o)
|
||||
: m_Ptr(o.m_Ptr), m_Cap(o.m_Cap), m_Mem(o.m_Mem)
|
||||
{
|
||||
o.m_Ptr = nullptr;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
@ -192,6 +246,23 @@ public:
|
||||
*/
|
||||
Buffer & operator = (const Buffer & o);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
Buffer & operator = (Buffer && o)
|
||||
{
|
||||
if (m_Ptr != o.m_Ptr)
|
||||
{
|
||||
if (m_Ptr)
|
||||
Release();
|
||||
m_Ptr = o.m_Ptr;
|
||||
m_Cap = o.m_Cap;
|
||||
m_Mem = o.m_Mem;
|
||||
o.m_Ptr = nullptr;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Equality comparison operator.
|
||||
*/
|
||||
@ -251,7 +322,7 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the internal buffer casted as a different type.
|
||||
*/
|
||||
template < typename T > T * Get()
|
||||
template < typename T = Value> T * Get()
|
||||
{
|
||||
return reinterpret_cast< T * >(m_Ptr);
|
||||
}
|
||||
@ -259,7 +330,7 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the internal buffer casted as a different type.
|
||||
*/
|
||||
template < typename T > const T * Get() const
|
||||
template < typename T = Value> const T * Get() const
|
||||
{
|
||||
return reinterpret_cast< const T * >(m_Ptr);
|
||||
}
|
||||
@ -267,7 +338,7 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the a certain element.
|
||||
*/
|
||||
template < typename T > T & At(SzType n)
|
||||
template < typename T = Value> T & At(SzType n)
|
||||
{
|
||||
assert(n < m_Cap);
|
||||
return reinterpret_cast< T * >(m_Ptr)[n];
|
||||
@ -276,7 +347,7 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the a certain element.
|
||||
*/
|
||||
template < typename T > const T & At(SzType n) const
|
||||
template < typename T = Value> const T & At(SzType n) const
|
||||
{
|
||||
assert(n < m_Cap);
|
||||
return reinterpret_cast< const T * >(m_Ptr)[n];
|
||||
@ -285,7 +356,7 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the internal buffer casted as a different type.
|
||||
*/
|
||||
template < typename T > T * Begin()
|
||||
template < typename T = Value> T * Begin()
|
||||
{
|
||||
return reinterpret_cast< T * >(m_Ptr);
|
||||
}
|
||||
@ -293,7 +364,7 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the internal buffer casted as a different type.
|
||||
*/
|
||||
template < typename T > const T * Begin() const
|
||||
template < typename T = Value> const T * Begin() const
|
||||
{
|
||||
return reinterpret_cast< const T * >(m_Ptr);
|
||||
}
|
||||
@ -301,7 +372,7 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the internal buffer casted as a different type.
|
||||
*/
|
||||
template < typename T > T * End()
|
||||
template < typename T = Value> T * End()
|
||||
{
|
||||
return reinterpret_cast< T * >(m_Ptr) + (m_Cap / sizeof(T));
|
||||
}
|
||||
@ -309,7 +380,7 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the internal buffer casted as a different type.
|
||||
*/
|
||||
template < typename T > const T * End() const
|
||||
template < typename T = Value> const T * End() const
|
||||
{
|
||||
return reinterpret_cast< const T * >(m_Ptr) + (m_Cap / sizeof(T));
|
||||
}
|
||||
@ -333,7 +404,7 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve maximum elements it can hold for a certain type.
|
||||
*/
|
||||
template < typename T > static SzType Max()
|
||||
template < typename T = Value> static SzType Max()
|
||||
{
|
||||
return (0xFFFFFFFF / sizeof(T));
|
||||
}
|
||||
@ -341,7 +412,7 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the current buffer capacity in element count.
|
||||
*/
|
||||
template < typename T > SzType Size() const
|
||||
template < typename T = Value> SzType Size() const
|
||||
{
|
||||
return (m_Cap / sizeof(T));
|
||||
}
|
||||
@ -357,32 +428,28 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Makes sure there is enough capacity to hold the specified element count.
|
||||
*/
|
||||
template < typename T > Buffer Adjust(SzType n)
|
||||
template < typename T = Value> Buffer Adjust(SzType n)
|
||||
{
|
||||
// Do we meet the minimum size?
|
||||
if (n < 8)
|
||||
{
|
||||
n = 8;
|
||||
}
|
||||
n = 8; // Adjust to minimum size
|
||||
// See if the requested capacity doesn't exceed the limit
|
||||
if (n > Max< T >())
|
||||
{
|
||||
ThrowMemExcept("Requested buffer of (%u) elements exceeds the (%u) limit", n, Max< T >());
|
||||
}
|
||||
// Is there an existing buffer?
|
||||
else if (n && !m_Cap)
|
||||
{
|
||||
// Request the memory
|
||||
Request(n * sizeof(T));
|
||||
}
|
||||
Request(n * sizeof(T)); // Request the memory
|
||||
// Should the size be increased?
|
||||
else if (n > m_Cap)
|
||||
{
|
||||
// Backup the current memory
|
||||
Move();
|
||||
Buffer bkp(m_Ptr, m_Cap, m_Mem);
|
||||
// Request the memory
|
||||
Request(n * sizeof(T));
|
||||
// Return the backup
|
||||
return std::move(bkp);
|
||||
}
|
||||
// Return an empty buffer or the backup (if any)
|
||||
// Return an empty buffer
|
||||
return Buffer();
|
||||
}
|
||||
|
||||
@ -392,9 +459,7 @@ public:
|
||||
void Reset()
|
||||
{
|
||||
if (m_Ptr)
|
||||
{
|
||||
Release();
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
@ -437,17 +502,6 @@ protected:
|
||||
*/
|
||||
void Release();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Moves the internal buffer to the global members to be taken over by the next instance.
|
||||
*/
|
||||
void Move()
|
||||
{
|
||||
s_Ptr = m_Ptr;
|
||||
s_Cap = m_Cap;
|
||||
m_Ptr = NULL;
|
||||
m_Cap = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
@ -456,10 +510,6 @@ private:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
MemRef m_Mem;
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
static Pointer s_Ptr; /* Pointer to a moved memory buffer. */
|
||||
static SzType s_Cap; /* The total size of the moved buffer. */
|
||||
};
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
@ -14,6 +14,14 @@ const Circle Circle::MAX = Circle(NumLimit< Circle::Value >::Max);
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQChar Circle::Delim = ',';
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger Circle::Typename(HSQUIRRELVM vm)
|
||||
{
|
||||
static SQChar name[] = _SC("Circle");
|
||||
sq_pushstring(vm, name, sizeof(name));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Circle::Circle()
|
||||
: pos(0.0, 0.0), rad(0.0)
|
||||
@ -42,27 +50,6 @@ Circle::Circle(Value xv, Value yv, Value rv)
|
||||
/* ... */
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Circle::Circle(const Circle & o)
|
||||
: pos(o.pos), rad(o.rad)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Circle::~Circle()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Circle & Circle::operator = (const Circle & o)
|
||||
{
|
||||
pos = o.pos;
|
||||
rad = o.rad;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Circle & Circle::operator = (Value r)
|
||||
{
|
||||
@ -341,7 +328,7 @@ Int32 Circle::Cmp(const Circle & o) const
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr Circle::ToString() const
|
||||
{
|
||||
return ToStringF("%f,%f,%f", pos.x, pos.y, rad);
|
||||
return ToStrF("%f,%f,%f", pos.x, pos.y, rad);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -395,35 +382,28 @@ void Circle::Generate()
|
||||
void Circle::Generate(Value min, Value max, bool r)
|
||||
{
|
||||
if (EpsLt(max, min))
|
||||
{
|
||||
SqThrow("max value is lower than min value");
|
||||
}
|
||||
SqThrowF("max value is lower than min value");
|
||||
else if (r)
|
||||
{
|
||||
rad = GetRandomFloat32(min, max);
|
||||
}
|
||||
else
|
||||
{
|
||||
pos.Generate(min, max);
|
||||
}
|
||||
}
|
||||
|
||||
void Circle::Generate(Value xmin, Value xmax, Value ymin, Value ymax)
|
||||
{
|
||||
if (EpsLt(xmax, xmin) || EpsLt(ymax, ymin))
|
||||
SqThrowF("max value is lower than min value");
|
||||
|
||||
pos.Generate(xmin, xmax, ymin, ymax);
|
||||
}
|
||||
|
||||
void Circle::Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value rmin, Value rmax)
|
||||
{
|
||||
if (EpsLt(rmax, rmin))
|
||||
{
|
||||
SqThrow("max value is lower than min value");
|
||||
}
|
||||
else
|
||||
{
|
||||
pos.Generate(xmin, xmax, ymin, ymax);
|
||||
rad = GetRandomFloat32(rmin, rmax);
|
||||
}
|
||||
if (EpsLt(xmax, xmin) || EpsLt(ymax, ymin) || EpsLt(rmax, rmin))
|
||||
SqThrowF("max value is lower than min value");
|
||||
|
||||
pos.Generate(xmin, xmax, ymin, ymax);
|
||||
rad = GetRandomFloat32(rmin, rmax);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -452,6 +432,7 @@ void Register_Circle(HSQUIRRELVM vm)
|
||||
.Prop(_SC("abs"), &Circle::Abs)
|
||||
/* Core Metamethods */
|
||||
.Func(_SC("_tostring"), &Circle::ToString)
|
||||
.SquirrelFunc(_SC("_typename"), &Circle::Typename)
|
||||
.Func(_SC("_cmp"), &Circle::Cmp)
|
||||
/* Metamethods */
|
||||
.Func<Circle (Circle::*)(const Circle &) const>(_SC("_add"), &Circle::operator +)
|
||||
|
@ -9,355 +9,370 @@
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Class used to represent a two-dimensional circle.
|
||||
*/
|
||||
struct Circle
|
||||
{
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* The type of value used by components of type.
|
||||
*/
|
||||
typedef float Value;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Helper instances for common values mostly used as return types or comparison.
|
||||
*/
|
||||
static const Circle NIL;
|
||||
static const Circle MIN;
|
||||
static const Circle MAX;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* The delimiter character to be used when extracting values from strings.
|
||||
*/
|
||||
static SQChar Delim;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* The position and radius components of this type.
|
||||
*/
|
||||
Vector2 pos;
|
||||
Value rad;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Default constructor.
|
||||
*/
|
||||
Circle();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Construct a circle at position 0,0 using the specified radius.
|
||||
*/
|
||||
Circle(Value rv);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Construct a circle at the specified position using the specified radius.
|
||||
*/
|
||||
Circle(const Vector2 & pv, Value rv);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Construct a circle at the specified position using the specified radius.
|
||||
*/
|
||||
Circle(Value xv, Value yv, Value rv);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Copy constructor.
|
||||
*/
|
||||
Circle(const Circle & o);
|
||||
Circle(const Circle & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Move constructor.
|
||||
*/
|
||||
~Circle();
|
||||
Circle(Circle && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Destructor.
|
||||
*/
|
||||
Circle & operator = (const Circle & o);
|
||||
~Circle() = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
Circle & operator = (const Circle & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
Circle & operator = (Circle && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Radius assignment operator.
|
||||
*/
|
||||
Circle & operator = (Value r);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Position assignment operator.
|
||||
*/
|
||||
Circle & operator = (const Vector2 & p);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Addition assignment operator.
|
||||
*/
|
||||
Circle & operator += (const Circle & c);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Subtraction assignment operator.
|
||||
*/
|
||||
Circle & operator -= (const Circle & c);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Multiplication assignment operator.
|
||||
*/
|
||||
Circle & operator *= (const Circle & c);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Division assignment operator.
|
||||
*/
|
||||
Circle & operator /= (const Circle & c);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Modulo assignment operator.
|
||||
*/
|
||||
Circle & operator %= (const Circle & c);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Radius addition assignment operator.
|
||||
*/
|
||||
Circle & operator += (Value r);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Radius subtraction assignment operator.
|
||||
*/
|
||||
Circle & operator -= (Value r);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Radius multiplication assignment operator.
|
||||
*/
|
||||
Circle & operator *= (Value r);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Radius division assignment operator.
|
||||
*/
|
||||
Circle & operator /= (Value r);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Radius modulo assignment operator.
|
||||
*/
|
||||
Circle & operator %= (Value r);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Position addition assignment operator.
|
||||
*/
|
||||
Circle & operator += (const Vector2 & p);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Position subtraction assignment operator.
|
||||
*/
|
||||
Circle & operator -= (const Vector2 & p);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Position multiplication assignment operator.
|
||||
*/
|
||||
Circle & operator *= (const Vector2 & p);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Position division assignment operator.
|
||||
*/
|
||||
Circle & operator /= (const Vector2 & p);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Position modulo assignment operator.
|
||||
*/
|
||||
Circle & operator %= (const Vector2 & p);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Pre-increment operator.
|
||||
*/
|
||||
Circle & operator ++ ();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Pre-decrement operator.
|
||||
*/
|
||||
Circle & operator -- ();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Post-increment operator.
|
||||
*/
|
||||
Circle operator ++ (int);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Post-decrement operator.
|
||||
*/
|
||||
Circle operator -- (int);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Addition operator.
|
||||
*/
|
||||
Circle operator + (const Circle & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Subtraction operator.
|
||||
*/
|
||||
Circle operator - (const Circle & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Multiplication operator.
|
||||
*/
|
||||
Circle operator * (const Circle & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Division operator.
|
||||
*/
|
||||
Circle operator / (const Circle & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Modulo operator.
|
||||
*/
|
||||
Circle operator % (const Circle & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Radius addition operator.
|
||||
*/
|
||||
Circle operator + (Value r) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Radius subtraction operator.
|
||||
*/
|
||||
Circle operator - (Value r) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Radius multiplication operator.
|
||||
*/
|
||||
Circle operator * (Value r) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Radius division operator.
|
||||
*/
|
||||
Circle operator / (Value r) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Radius modulo operator.
|
||||
*/
|
||||
Circle operator % (Value r) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Position addition operator.
|
||||
*/
|
||||
Circle operator + (const Vector2 & p) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Position subtraction operator.
|
||||
*/
|
||||
Circle operator - (const Vector2 & p) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Position multiplication operator.
|
||||
*/
|
||||
Circle operator * (const Vector2 & p) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Position division operator.
|
||||
*/
|
||||
Circle operator / (const Vector2 & p) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Position modulo operator.
|
||||
*/
|
||||
Circle operator % (const Vector2 & p) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Unary plus operator.
|
||||
*/
|
||||
Circle operator + () const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Unary minus operator.
|
||||
*/
|
||||
Circle operator - () const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Equality comparison operator.
|
||||
*/
|
||||
bool operator == (const Circle & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Inequality comparison operator.
|
||||
*/
|
||||
bool operator != (const Circle & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Less than comparison operator.
|
||||
*/
|
||||
bool operator < (const Circle & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Greater than comparison operator.
|
||||
*/
|
||||
bool operator > (const Circle & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Less than or equal comparison operator.
|
||||
*/
|
||||
bool operator <= (const Circle & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Greater than or equal comparison operator.
|
||||
*/
|
||||
bool operator >= (const Circle & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Used by the script engine to compare two instances of this type.
|
||||
*/
|
||||
Int32 Cmp(const Circle & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Used by the script engine to retrieve the name from instances of this type.
|
||||
*/
|
||||
static SQInteger Typename(HSQUIRRELVM vm);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Set the specified radius.
|
||||
*/
|
||||
void Set(Value nr);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Copy the circle from another instance of this type.
|
||||
*/
|
||||
void Set(const Circle & nc);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set the position from the specified position.
|
||||
*/
|
||||
void Set(const Vector2 & np);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set the specified position and radius.
|
||||
*/
|
||||
void Set(const Vector2 & np, Value nr);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set the specified position.
|
||||
*/
|
||||
void Set(Value nx, Value ny);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set the specified position and radius.
|
||||
*/
|
||||
void Set(Value nx, Value ny, Value nr);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set the values extracted from the specified string using the specified delimiter.
|
||||
*/
|
||||
void Set(CSStr values, SQChar delim);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Generate a randomly sized and positioned circle.
|
||||
*/
|
||||
void Generate();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Generate a randomly sized or positioned circle within the specified bounds.
|
||||
*/
|
||||
void Generate(Value min, Value max, bool r);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Generate a randomly positioned circle within the specified bounds.
|
||||
*/
|
||||
void Generate(Value xmin, Value xmax, Value ymin, Value ymax);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Generate a randomly sized and positioned circle within the specified bounds.
|
||||
*/
|
||||
void Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value rmin, Value rmax);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Clear the component values to default.
|
||||
*/
|
||||
void Clear()
|
||||
{
|
||||
@ -365,7 +380,7 @@ struct Circle
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Retrieve a new instance of this type with absolute component values.
|
||||
*/
|
||||
Circle Abs() const;
|
||||
};
|
||||
|
@ -15,6 +15,14 @@ const Color3 Color3::MAX = Color3(NumLimit< Color3::Value >::Max);
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQChar Color3::Delim = ',';
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger Color3::Typename(HSQUIRRELVM vm)
|
||||
{
|
||||
static SQChar name[] = _SC("Color3");
|
||||
sq_pushstring(vm, name, sizeof(name));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Color3::Color3()
|
||||
: r(0), g(0), b(0)
|
||||
@ -36,28 +44,6 @@ Color3::Color3(Value rv, Value gv, Value bv)
|
||||
/* ... */
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Color3::Color3(const Color3 & o)
|
||||
: r(o.r), g(o.g), b(o.b)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Color3::~Color3()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Color3 & Color3::operator = (const Color3 & o)
|
||||
{
|
||||
r = o.r;
|
||||
g = o.g;
|
||||
b = o.b;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Color3 & Color3::operator = (Value s)
|
||||
{
|
||||
@ -449,7 +435,7 @@ Int32 Color3::Cmp(const Color3 & o) const
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr Color3::ToString() const
|
||||
{
|
||||
return ToStringF("%u,%u,%u", r, g, b);
|
||||
return ToStrF("%u,%u,%u", r, g, b);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -502,9 +488,9 @@ Uint32 Color3::GetRGB() const
|
||||
|
||||
void Color3::SetRGB(Uint32 p)
|
||||
{
|
||||
r = Value((p >> 16) & 0xFF);
|
||||
g = Value((p >> 8) & 0xFF);
|
||||
b = Value((p) & 0xFF);
|
||||
r = static_cast< Value >((p >> 16) & 0xFF);
|
||||
g = static_cast< Value >((p >> 8) & 0xFF);
|
||||
b = static_cast< Value >((p) & 0xFF);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -515,9 +501,9 @@ Uint32 Color3::GetRGBA() const
|
||||
|
||||
void Color3::SetRGBA(Uint32 p)
|
||||
{
|
||||
r = Value((p >> 24) & 0xFF);
|
||||
g = Value((p >> 16) & 0xFF);
|
||||
b = Value((p >> 8) & 0xFF);
|
||||
r = static_cast< Value >((p >> 24) & 0xFF);
|
||||
g = static_cast< Value >((p >> 16) & 0xFF);
|
||||
b = static_cast< Value >((p >> 8) & 0xFF);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -528,9 +514,9 @@ Uint32 Color3::GetARGB() const
|
||||
|
||||
void Color3::SetARGB(Uint32 p)
|
||||
{
|
||||
r = Value((p >> 16) & 0xFF);
|
||||
g = Value((p >> 8) & 0xFF);
|
||||
b = Value((p) & 0xFF);
|
||||
r = static_cast< Value >((p >> 16) & 0xFF);
|
||||
g = static_cast< Value >((p >> 8) & 0xFF);
|
||||
b = static_cast< Value >((p) & 0xFF);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -544,29 +530,21 @@ void Color3::Generate()
|
||||
void Color3::Generate(Value min, Value max)
|
||||
{
|
||||
if (max < min)
|
||||
{
|
||||
SqThrow("max value is lower than min value");
|
||||
}
|
||||
else
|
||||
{
|
||||
r = GetRandomUint8(min, max);
|
||||
g = GetRandomUint8(min, max);
|
||||
b = GetRandomUint8(min, max);
|
||||
}
|
||||
SqThrowF("max value is lower than min value");
|
||||
|
||||
r = GetRandomUint8(min, max);
|
||||
g = GetRandomUint8(min, max);
|
||||
b = GetRandomUint8(min, max);
|
||||
}
|
||||
|
||||
void Color3::Generate(Value rmin, Value rmax, Value gmin, Value gmax, Value bmin, Value bmax)
|
||||
{
|
||||
if (rmax < rmin || gmax < gmin || bmax < bmin)
|
||||
{
|
||||
SqThrow("max value is lower than min value");
|
||||
}
|
||||
else
|
||||
{
|
||||
r = GetRandomUint8(rmin, rmax);
|
||||
g = GetRandomUint8(gmin, gmax);
|
||||
b = GetRandomUint8(bmin, bmax);
|
||||
}
|
||||
SqThrowF("max value is lower than min value");
|
||||
|
||||
r = GetRandomUint8(rmin, rmax);
|
||||
g = GetRandomUint8(gmin, gmax);
|
||||
b = GetRandomUint8(bmin, bmax);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -578,9 +556,9 @@ void Color3::Random()
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Color3::Inverse()
|
||||
{
|
||||
r = Value(~r);
|
||||
g = Value(~g);
|
||||
b = Value(~b);
|
||||
r = static_cast< Value >(~r);
|
||||
g = static_cast< Value >(~g);
|
||||
b = static_cast< Value >(~b);
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
@ -606,6 +584,7 @@ void Register_Color3(HSQUIRRELVM vm)
|
||||
.Prop(_SC("str"), &Color3::SetCol)
|
||||
/* Core Metamethods */
|
||||
.Func(_SC("_tostring"), &Color3::ToString)
|
||||
.SquirrelFunc(_SC("_typename"), &Color3::Typename)
|
||||
.Func(_SC("_cmp"), &Color3::Cmp)
|
||||
/* Metamethods */
|
||||
.Func<Color3 (Color3::*)(const Color3 &) const>(_SC("_add"), &Color3::operator +)
|
||||
|
@ -8,434 +8,449 @@
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Class used to represent an opaque RGB color.
|
||||
*/
|
||||
struct Color3
|
||||
{
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* The type of value used by components of type.
|
||||
*/
|
||||
typedef unsigned char Value;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Helper instances for common values mostly used as return types or comparison.
|
||||
*/
|
||||
static const Color3 NIL;
|
||||
static const Color3 MIN;
|
||||
static const Color3 MAX;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* The delimiter character to be used when extracting values from strings.
|
||||
*/
|
||||
static SQChar Delim;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* The red, green and blue components of this type.
|
||||
*/
|
||||
Value r, g, b;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Default constructor.
|
||||
*/
|
||||
Color3();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Construct a color with all components with the same specified color.
|
||||
*/
|
||||
Color3(Value sv);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Construct with individually specified red, green and blue colors.
|
||||
*/
|
||||
Color3(Value rv, Value gv, Value bv);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Copy constructor.
|
||||
*/
|
||||
Color3(const Color3 & o);
|
||||
Color3(const Color3 & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Move constructor.
|
||||
*/
|
||||
~Color3();
|
||||
Color3(Color3 && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Destructor.
|
||||
*/
|
||||
Color3 & operator = (const Color3 & o);
|
||||
~Color3() = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
Color3 & operator = (const Color3 & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
Color3 & operator = (Color3 && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Scalar value assignment operator.
|
||||
*/
|
||||
Color3 & operator = (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Named color assignment operator.
|
||||
*/
|
||||
Color3 & operator = (CSStr name);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Transparent color assignment operator.
|
||||
*/
|
||||
Color3 & operator = (const Color4 & c);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Addition assignment operator.
|
||||
*/
|
||||
Color3 & operator += (const Color3 & c);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Subtraction assignment operator.
|
||||
*/
|
||||
Color3 & operator -= (const Color3 & c);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Multiplication assignment operator.
|
||||
*/
|
||||
Color3 & operator *= (const Color3 & c);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Division assignment operator.
|
||||
*/
|
||||
Color3 & operator /= (const Color3 & c);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Modulo assignment operator.
|
||||
*/
|
||||
Color3 & operator %= (const Color3 & c);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Bitwise AND assignment operator.
|
||||
*/
|
||||
Color3 & operator &= (const Color3 & c);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Bitwise OR assignment operator.
|
||||
*/
|
||||
Color3 & operator |= (const Color3 & c);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Bitwise XOR assignment operator.
|
||||
*/
|
||||
Color3 & operator ^= (const Color3 & c);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Bitwise left shift assignment operator.
|
||||
*/
|
||||
Color3 & operator <<= (const Color3 & c);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Bitwise right shift assignment operator.
|
||||
*/
|
||||
Color3 & operator >>= (const Color3 & c);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value addition assignment operator.
|
||||
*/
|
||||
Color3 & operator += (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value subtraction assignment operator.
|
||||
*/
|
||||
Color3 & operator -= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value multiplication assignment operator.
|
||||
*/
|
||||
Color3 & operator *= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value division assignment operator.
|
||||
*/
|
||||
Color3 & operator /= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value modulo assignment operator.
|
||||
*/
|
||||
Color3 & operator %= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value bitwise AND assignment operator.
|
||||
*/
|
||||
Color3 & operator &= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value bitwise OR assignment operator.
|
||||
*/
|
||||
Color3 & operator |= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value bitwise XOR assignment operator.
|
||||
*/
|
||||
Color3 & operator ^= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value bitwise left shift assignment operator.
|
||||
*/
|
||||
Color3 & operator <<= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value bitwise right shift assignment operator.
|
||||
*/
|
||||
Color3 & operator >>= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Pre-increment operator.
|
||||
*/
|
||||
Color3 & operator ++ ();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Pre-decrement operator.
|
||||
*/
|
||||
Color3 & operator -- ();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Post-increment operator.
|
||||
*/
|
||||
Color3 operator ++ (int);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Post-decrement operator.
|
||||
*/
|
||||
Color3 operator -- (int);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Addition operator.
|
||||
*/
|
||||
Color3 operator + (const Color3 & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Subtraction operator.
|
||||
*/
|
||||
Color3 operator - (const Color3 & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Multiplication operator.
|
||||
*/
|
||||
Color3 operator * (const Color3 & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Division operator.
|
||||
*/
|
||||
Color3 operator / (const Color3 & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Modulo operator.
|
||||
*/
|
||||
Color3 operator % (const Color3 & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Bitwise AND operator.
|
||||
*/
|
||||
Color3 operator & (const Color3 & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Bitwise OR operator.
|
||||
*/
|
||||
Color3 operator | (const Color3 & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Bitwise XOR operator.
|
||||
*/
|
||||
Color3 operator ^ (const Color3 & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Bitwise shift left operator.
|
||||
*/
|
||||
Color3 operator << (const Color3 & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Bitwise shift right operator.
|
||||
*/
|
||||
Color3 operator >> (const Color3 & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value addition operator.
|
||||
*/
|
||||
Color3 operator + (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value subtraction operator.
|
||||
*/
|
||||
Color3 operator - (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value multiplication operator.
|
||||
*/
|
||||
Color3 operator * (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value division operator.
|
||||
*/
|
||||
Color3 operator / (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value modulo operator.
|
||||
*/
|
||||
Color3 operator % (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value bitwise AND operator.
|
||||
*/
|
||||
Color3 operator & (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value bitwise OR operator.
|
||||
*/
|
||||
Color3 operator | (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value bitwise XOR operator.
|
||||
*/
|
||||
Color3 operator ^ (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value bitwise shift left operator.
|
||||
*/
|
||||
Color3 operator << (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value bitwise shift right operator.
|
||||
*/
|
||||
Color3 operator >> (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Unary plus operator.
|
||||
*/
|
||||
Color3 operator + () const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Unary minus operator.
|
||||
*/
|
||||
Color3 operator - () const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Bitwise NOT operator.
|
||||
*/
|
||||
Color3 operator ~ () const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Equality comparison operator.
|
||||
*/
|
||||
bool operator == (const Color3 & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Inequality comparison operator.
|
||||
*/
|
||||
bool operator != (const Color3 & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Less than comparison operator.
|
||||
*/
|
||||
bool operator < (const Color3 & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Greater than comparison operator.
|
||||
*/
|
||||
bool operator > (const Color3 & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Less than or equal comparison operator.
|
||||
*/
|
||||
bool operator <= (const Color3 & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Greater than or equal comparison operator.
|
||||
*/
|
||||
bool operator >= (const Color3 & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Implicit conversion to transparent color.
|
||||
*/
|
||||
operator Color4 () const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Used by the script engine to compare two instances of this type.
|
||||
*/
|
||||
Int32 Cmp(const Color3 & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Used by the script engine to retrieve the name from instances of this type.
|
||||
*/
|
||||
static SQInteger Typename(HSQUIRRELVM vm);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Set all components to the specified scalar value.
|
||||
*/
|
||||
void Set(Value ns);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set all components to the specified values.
|
||||
*/
|
||||
void Set(Value nr, Value ng, Value nb);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Copy the values from another instance of this type.
|
||||
*/
|
||||
void Set(const Color3 & c);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Copy the values from an opaque color.
|
||||
*/
|
||||
void Set(const Color4 & c);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set the values extracted from the specified string using the specified delimiter.
|
||||
*/
|
||||
void Set(CSStr str, SQChar delim);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set the values from the identified color.
|
||||
*/
|
||||
void SetCol(CSStr name);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Get the component values packed inside an integer value.
|
||||
*/
|
||||
Uint32 GetRGB() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set the component values wxtracted from an integer value.
|
||||
*/
|
||||
void SetRGB(Uint32 p);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Get the component values packed inside an integer value.
|
||||
*/
|
||||
Uint32 GetRGBA() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set the component values wxtracted from an integer value.
|
||||
*/
|
||||
void SetRGBA(Uint32 p);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Get the component values packed inside an integer value.
|
||||
*/
|
||||
Uint32 GetARGB() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set the component values wxtracted from an integer value.
|
||||
*/
|
||||
void SetARGB(Uint32 p);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Generate random values for all components of this instance.
|
||||
*/
|
||||
void Generate();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Generate random values for all components of this instance within the specified bounds.
|
||||
*/
|
||||
void Generate(Value min, Value max);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Generate random values for all components of this instance within the specified bounds.
|
||||
*/
|
||||
void Generate(Value rmin, Value rmax, Value gmin, Value gmax, Value bmin, Value bmax);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Clear the component values to default.
|
||||
*/
|
||||
void Clear()
|
||||
{
|
||||
@ -443,12 +458,12 @@ struct Color3
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set the component values to a randomly chosen color.
|
||||
*/
|
||||
void Random();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Inverse the color.
|
||||
*/
|
||||
void Inverse();
|
||||
};
|
||||
|
@ -15,6 +15,14 @@ const Color4 Color4::MAX = Color4(NumLimit< Color4::Value >::Max);
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQChar Color4::Delim = ',';
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger Color4::Typename(HSQUIRRELVM vm)
|
||||
{
|
||||
static SQChar name[] = _SC("Color4");
|
||||
sq_pushstring(vm, name, sizeof(name));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Color4::Color4()
|
||||
: r(0), g(0), b(0), a(0)
|
||||
@ -24,7 +32,7 @@ Color4::Color4()
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Color4::Color4(Value sv)
|
||||
: r(sv), g(sv), b(sv), a(sv)
|
||||
: r(sv), g(sv), b(sv), a(0)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
@ -43,29 +51,6 @@ Color4::Color4(Value rv, Value gv, Value bv, Value av)
|
||||
/* ... */
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Color4::Color4(const Color4 & o)
|
||||
: r(o.r), g(o.g), b(o.b), a(o.a)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Color4::~Color4()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Color4 & Color4::operator = (const Color4 & o)
|
||||
{
|
||||
r = o.r;
|
||||
g = o.g;
|
||||
b = o.b;
|
||||
a = o.a;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Color4 & Color4::operator = (Value s)
|
||||
{
|
||||
@ -482,7 +467,7 @@ Int32 Color4::Cmp(const Color4 & o) const
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr Color4::ToString() const
|
||||
{
|
||||
return ToStringF("%u,%u,%u,%u", r, g, b, a);
|
||||
return ToStrF("%u,%u,%u,%u", r, g, b, a);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -546,9 +531,9 @@ Uint32 Color4::GetRGB() const
|
||||
|
||||
void Color4::SetRGB(Uint32 p)
|
||||
{
|
||||
r = Value((p >> 16) & 0xFF);
|
||||
g = Value((p >> 8) & 0xFF);
|
||||
b = Value((p) & 0xFF);
|
||||
r = static_cast< Value >((p >> 16) & 0xFF);
|
||||
g = static_cast< Value >((p >> 8) & 0xFF);
|
||||
b = static_cast< Value >((p) & 0xFF);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -559,10 +544,10 @@ Uint32 Color4::GetRGBA() const
|
||||
|
||||
void Color4::SetRGBA(Uint32 p)
|
||||
{
|
||||
r = Value((p >> 24) & 0xFF);
|
||||
g = Value((p >> 16) & 0xFF);
|
||||
b = Value((p >> 8) & 0xFF);
|
||||
a = Value((p) & 0xFF);
|
||||
r = static_cast< Value >((p >> 24) & 0xFF);
|
||||
g = static_cast< Value >((p >> 16) & 0xFF);
|
||||
b = static_cast< Value >((p >> 8) & 0xFF);
|
||||
a = static_cast< Value >((p) & 0xFF);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -573,10 +558,10 @@ Uint32 Color4::GetARGB() const
|
||||
|
||||
void Color4::SetARGB(Uint32 p)
|
||||
{
|
||||
a = Value((p >> 24) & 0xFF);
|
||||
r = Value((p >> 16) & 0xFF);
|
||||
g = Value((p >> 8) & 0xFF);
|
||||
b = Value((p) & 0xFF);
|
||||
a = static_cast< Value >((p >> 24) & 0xFF);
|
||||
r = static_cast< Value >((p >> 16) & 0xFF);
|
||||
g = static_cast< Value >((p >> 8) & 0xFF);
|
||||
b = static_cast< Value >((p) & 0xFF);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -591,31 +576,23 @@ void Color4::Generate()
|
||||
void Color4::Generate(Value min, Value max)
|
||||
{
|
||||
if (max < min)
|
||||
{
|
||||
SqThrow("max value is lower than min value");
|
||||
}
|
||||
else
|
||||
{
|
||||
r = GetRandomUint8(min, max);
|
||||
g = GetRandomUint8(min, max);
|
||||
b = GetRandomUint8(min, max);
|
||||
a = GetRandomUint8(min, max);
|
||||
}
|
||||
SqThrowF("max value is lower than min value");
|
||||
|
||||
r = GetRandomUint8(min, max);
|
||||
g = GetRandomUint8(min, max);
|
||||
b = GetRandomUint8(min, max);
|
||||
a = GetRandomUint8(min, max);
|
||||
}
|
||||
|
||||
void Color4::Generate(Value rmin, Value rmax, Value gmin, Value gmax, Value bmin, Value bmax, Value amin, Value amax)
|
||||
{
|
||||
if (rmax < rmin || gmax < gmin || bmax < bmin || amax < amin)
|
||||
{
|
||||
SqThrow("max value is lower than min value");
|
||||
}
|
||||
else
|
||||
{
|
||||
r = GetRandomUint8(rmin, rmax);
|
||||
g = GetRandomUint8(gmin, gmax);
|
||||
b = GetRandomUint8(bmin, bmax);
|
||||
a = GetRandomUint8(bmin, bmax);
|
||||
}
|
||||
SqThrowF("max value is lower than min value");
|
||||
|
||||
r = GetRandomUint8(rmin, rmax);
|
||||
g = GetRandomUint8(gmin, gmax);
|
||||
b = GetRandomUint8(bmin, bmax);
|
||||
a = GetRandomUint8(bmin, bmax);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -627,10 +604,10 @@ void Color4::Random()
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Color4::Inverse()
|
||||
{
|
||||
r = Value(~r);
|
||||
g = Value(~g);
|
||||
b = Value(~b);
|
||||
a = Value(~a);
|
||||
r = static_cast< Value >(~r);
|
||||
g = static_cast< Value >(~g);
|
||||
b = static_cast< Value >(~b);
|
||||
a = static_cast< Value >(~a);
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
@ -658,6 +635,7 @@ void Register_Color4(HSQUIRRELVM vm)
|
||||
.Prop(_SC("str"), &Color4::SetCol)
|
||||
/* Core Metamethods */
|
||||
.Func(_SC("_tostring"), &Color4::ToString)
|
||||
.SquirrelFunc(_SC("_typename"), &Color4::Typename)
|
||||
.Func(_SC("_cmp"), &Color4::Cmp)
|
||||
/* Metamethods */
|
||||
.Func<Color4 (Color4::*)(const Color4 &) const>(_SC("_add"), &Color4::operator +)
|
||||
|
@ -8,444 +8,459 @@
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Class used to represent a transparent RGBA color.
|
||||
*/
|
||||
struct Color4
|
||||
{
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* The type of value used by components of type.
|
||||
*/
|
||||
typedef unsigned char Value;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Helper instances for common values mostly used as return types or comparison.
|
||||
*/
|
||||
static const Color4 NIL;
|
||||
static const Color4 MIN;
|
||||
static const Color4 MAX;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* The delimiter character to be used when extracting values from strings.
|
||||
*/
|
||||
static SQChar Delim;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* The red, green and blue components of this type.
|
||||
*/
|
||||
Value r, g, b, a;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Default constructor.
|
||||
*/
|
||||
Color4();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Construct a color with all components with the same specified color.
|
||||
*/
|
||||
Color4(Value sv);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Construct with individually specified red, green and blue colors.
|
||||
*/
|
||||
Color4(Value rv, Value gv, Value bv);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Construct with individually specified red, green, blue and alpha colors.
|
||||
*/
|
||||
Color4(Value rv, Value gv, Value bv, Value av);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Copy constructor.
|
||||
*/
|
||||
Color4(const Color4 & o);
|
||||
Color4(const Color4 & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Move constructor.
|
||||
*/
|
||||
~Color4();
|
||||
Color4(Color4 && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Destructor.
|
||||
*/
|
||||
Color4 & operator = (const Color4 & o);
|
||||
~Color4() = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
Color4 & operator = (const Color4 & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
Color4 & operator = (Color4 && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Scalar value assignment operator.
|
||||
*/
|
||||
Color4 & operator = (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Named color assignment operator.
|
||||
*/
|
||||
Color4 & operator = (CSStr name);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Opaque color assignment operator.
|
||||
*/
|
||||
Color4 & operator = (const Color3 & c);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Addition assignment operator.
|
||||
*/
|
||||
Color4 & operator += (const Color4 & c);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Subtraction assignment operator.
|
||||
*/
|
||||
Color4 & operator -= (const Color4 & c);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Multiplication assignment operator.
|
||||
*/
|
||||
Color4 & operator *= (const Color4 & c);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Division assignment operator.
|
||||
*/
|
||||
Color4 & operator /= (const Color4 & c);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Modulo assignment operator.
|
||||
*/
|
||||
Color4 & operator %= (const Color4 & c);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Bitwise AND assignment operator.
|
||||
*/
|
||||
Color4 & operator &= (const Color4 & c);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Bitwise OR assignment operator.
|
||||
*/
|
||||
Color4 & operator |= (const Color4 & c);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Bitwise XOR assignment operator.
|
||||
*/
|
||||
Color4 & operator ^= (const Color4 & c);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Bitwise left shift assignment operator.
|
||||
*/
|
||||
Color4 & operator <<= (const Color4 & c);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Bitwise right shift assignment operator.
|
||||
*/
|
||||
Color4 & operator >>= (const Color4 & c);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value addition assignment operator.
|
||||
*/
|
||||
Color4 & operator += (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value subtraction assignment operator.
|
||||
*/
|
||||
Color4 & operator -= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value multiplication assignment operator.
|
||||
*/
|
||||
Color4 & operator *= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value division assignment operator.
|
||||
*/
|
||||
Color4 & operator /= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value modulo assignment operator.
|
||||
*/
|
||||
Color4 & operator %= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value bitwise AND assignment operator.
|
||||
*/
|
||||
Color4 & operator &= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value bitwise OR assignment operator.
|
||||
*/
|
||||
Color4 & operator |= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value bitwise XOR assignment operator.
|
||||
*/
|
||||
Color4 & operator ^= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value bitwise left shift assignment operator.
|
||||
*/
|
||||
Color4 & operator <<= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value bitwise right shift assignment operator.
|
||||
*/
|
||||
Color4 & operator >>= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Pre-increment operator.
|
||||
*/
|
||||
Color4 & operator ++ ();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Pre-decrement operator.
|
||||
*/
|
||||
Color4 & operator -- ();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Post-increment operator.
|
||||
*/
|
||||
Color4 operator ++ (int);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Post-decrement operator.
|
||||
*/
|
||||
Color4 operator -- (int);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Addition operator.
|
||||
*/
|
||||
Color4 operator + (const Color4 & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Subtraction operator.
|
||||
*/
|
||||
Color4 operator - (const Color4 & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Multiplication operator.
|
||||
*/
|
||||
Color4 operator * (const Color4 & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Division operator.
|
||||
*/
|
||||
Color4 operator / (const Color4 & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Modulo operator.
|
||||
*/
|
||||
Color4 operator % (const Color4 & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Bitwise AND operator.
|
||||
*/
|
||||
Color4 operator & (const Color4 & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Bitwise OR operator.
|
||||
*/
|
||||
Color4 operator | (const Color4 & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Bitwise XOR operator.
|
||||
*/
|
||||
Color4 operator ^ (const Color4 & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Bitwise shift left operator.
|
||||
*/
|
||||
Color4 operator << (const Color4 & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Bitwise shift right operator.
|
||||
*/
|
||||
Color4 operator >> (const Color4 & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value addition operator.
|
||||
*/
|
||||
Color4 operator + (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value subtraction operator.
|
||||
*/
|
||||
Color4 operator - (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value multiplication operator.
|
||||
*/
|
||||
Color4 operator * (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value division operator.
|
||||
*/
|
||||
Color4 operator / (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value modulo operator.
|
||||
*/
|
||||
Color4 operator % (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value bitwise AND operator.
|
||||
*/
|
||||
Color4 operator & (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value bitwise OR operator.
|
||||
*/
|
||||
Color4 operator | (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value bitwise XOR operator.
|
||||
*/
|
||||
Color4 operator ^ (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value bitwise shift left operator.
|
||||
*/
|
||||
Color4 operator << (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value bitwise shift right operator.
|
||||
*/
|
||||
Color4 operator >> (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Unary plus operator.
|
||||
*/
|
||||
Color4 operator + () const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Unary minus operator.
|
||||
*/
|
||||
Color4 operator - () const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Bitwise NOT operator.
|
||||
*/
|
||||
Color4 operator ~ () const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Equality comparison operator.
|
||||
*/
|
||||
bool operator == (const Color4 & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Inequality comparison operator.
|
||||
*/
|
||||
bool operator != (const Color4 & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Less than comparison operator.
|
||||
*/
|
||||
bool operator < (const Color4 & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Greater than comparison operator.
|
||||
*/
|
||||
bool operator > (const Color4 & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Less than or equal comparison operator.
|
||||
*/
|
||||
bool operator <= (const Color4 & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Greater than or equal comparison operator.
|
||||
*/
|
||||
bool operator >= (const Color4 & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Implicit conversion to opaque color.
|
||||
*/
|
||||
operator Color3 () const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Used by the script engine to compare two instances of this type.
|
||||
*/
|
||||
Int32 Cmp(const Color4 & c) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Used by the script engine to retrieve the name from instances of this type.
|
||||
*/
|
||||
static SQInteger Typename(HSQUIRRELVM vm);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Set all components to the specified scalar value.
|
||||
*/
|
||||
void Set(Value ns);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set all components to the specified values.
|
||||
*/
|
||||
void Set(Value nr, Value ng, Value nb);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set all components to the specified values.
|
||||
*/
|
||||
void Set(Value nr, Value ng, Value nb, Value na);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Copy the values from another instance of this type.
|
||||
*/
|
||||
void Set(const Color4 & c);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Copy the values from an opaque color.
|
||||
*/
|
||||
void Set(const Color3 & c);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set the values extracted from the specified string using the specified delimiter.
|
||||
*/
|
||||
void Set(CSStr name, SQChar delim);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set the values from the identified color.
|
||||
*/
|
||||
void SetCol(CSStr name);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Get the component values packed inside an integer value.
|
||||
*/
|
||||
Uint32 GetRGB() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set the component values wxtracted from an integer value.
|
||||
*/
|
||||
void SetRGB(Uint32 p);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Get the component values packed inside an integer value.
|
||||
*/
|
||||
Uint32 GetRGBA() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set the component values wxtracted from an integer value.
|
||||
*/
|
||||
void SetRGBA(Uint32 p);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Get the component values packed inside an integer value.
|
||||
*/
|
||||
Uint32 GetARGB() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set the component values wxtracted from an integer value.
|
||||
*/
|
||||
void SetARGB(Uint32 p);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Generate random values for all components of this instance.
|
||||
*/
|
||||
void Generate();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Generate random values for all components of this instance within the specified bounds.
|
||||
*/
|
||||
void Generate(Value min, Value max);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Generate random values for all components of this instance within the specified bounds.
|
||||
*/
|
||||
void Generate(Value rmin, Value rmax, Value gmin, Value gmax, Value bmin, Value bmax, Value amin, Value amax);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Clear the component values to default.
|
||||
*/
|
||||
void Clear()
|
||||
{
|
||||
@ -453,12 +468,12 @@ struct Color4
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set the component values to a randomly chosen color.
|
||||
*/
|
||||
void Random();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Inverse the color.
|
||||
*/
|
||||
void Inverse();
|
||||
};
|
||||
|
@ -16,6 +16,14 @@ const Quaternion Quaternion::MAX = Quaternion(NumLimit< Quaternion::Value >::Max
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQChar Quaternion::Delim = ',';
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger Quaternion::Typename(HSQUIRRELVM vm)
|
||||
{
|
||||
static SQChar name[] = _SC("Quaternion");
|
||||
sq_pushstring(vm, name, sizeof(name));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Quaternion::Quaternion()
|
||||
: x(0.0), y(0.0), z(0.0), w(0.0)
|
||||
@ -44,29 +52,6 @@ Quaternion::Quaternion(Value xv, Value yv, Value zv, Value wv)
|
||||
/* ... */
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Quaternion::Quaternion(const Quaternion & o)
|
||||
: x(o.x), y(o.y), z(o.z), w(o.w)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Quaternion::~Quaternion()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Quaternion & Quaternion::operator = (const Quaternion & o)
|
||||
{
|
||||
x = o.x;
|
||||
y = o.y;
|
||||
z = o.z;
|
||||
w = o.w;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Quaternion & Quaternion::operator = (Value s)
|
||||
{
|
||||
@ -338,7 +323,7 @@ Int32 Quaternion::Cmp(const Quaternion & o) const
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr Quaternion::ToString() const
|
||||
{
|
||||
return ToStringF("%f,%f,%f,%f", x, y, z, w);
|
||||
return ToStrF("%f,%f,%f,%f", x, y, z, w);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -408,31 +393,23 @@ void Quaternion::Generate()
|
||||
void Quaternion::Generate(Value min, Value max)
|
||||
{
|
||||
if (EpsLt(max, min))
|
||||
{
|
||||
SqThrow("max value is lower than min value");
|
||||
}
|
||||
else
|
||||
{
|
||||
x = GetRandomFloat32(min, max);
|
||||
y = GetRandomFloat32(min, max);
|
||||
z = GetRandomFloat32(min, max);
|
||||
y = GetRandomFloat32(min, max);
|
||||
}
|
||||
SqThrowF("max value is lower than min value");
|
||||
|
||||
x = GetRandomFloat32(min, max);
|
||||
y = GetRandomFloat32(min, max);
|
||||
z = GetRandomFloat32(min, max);
|
||||
y = GetRandomFloat32(min, max);
|
||||
}
|
||||
|
||||
void Quaternion::Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value zmin, Value zmax, Value wmin, Value wmax)
|
||||
{
|
||||
if (EpsLt(xmax, xmin) || EpsLt(ymax, ymin) || EpsLt(zmax, zmin) || EpsLt(wmax, wmin))
|
||||
{
|
||||
SqThrow("max value is lower than min value");
|
||||
}
|
||||
else
|
||||
{
|
||||
x = GetRandomFloat32(xmin, xmax);
|
||||
y = GetRandomFloat32(ymin, ymax);
|
||||
z = GetRandomFloat32(zmin, zmax);
|
||||
y = GetRandomFloat32(ymin, ymax);
|
||||
}
|
||||
SqThrowF("max value is lower than min value");
|
||||
|
||||
x = GetRandomFloat32(xmin, xmax);
|
||||
y = GetRandomFloat32(ymin, ymax);
|
||||
z = GetRandomFloat32(zmin, zmax);
|
||||
y = GetRandomFloat32(ymin, ymax);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -463,6 +440,7 @@ void Register_Quaternion(HSQUIRRELVM vm)
|
||||
.Prop(_SC("abs"), &Quaternion::Abs)
|
||||
/* Core Metamethods */
|
||||
.Func(_SC("_tostring"), &Quaternion::ToString)
|
||||
.SquirrelFunc(_SC("_typename"), &Quaternion::Typename)
|
||||
.Func(_SC("_cmp"), &Quaternion::Cmp)
|
||||
/* Metamethods */
|
||||
.Func<Quaternion (Quaternion::*)(const Quaternion &) const>(_SC("_add"), &Quaternion::operator +)
|
||||
|
@ -8,34 +8,34 @@
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Quaternion class for representing rotations.
|
||||
*/
|
||||
struct Quaternion
|
||||
{
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* The type of value used by components of type.
|
||||
*/
|
||||
typedef float Value;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Helper instances for common values mostly used as return types or comparison.
|
||||
*/
|
||||
static const Quaternion NIL;
|
||||
static const Quaternion MIN;
|
||||
static const Quaternion MAX;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* The delimiter character to be used when extracting values from strings.
|
||||
*/
|
||||
static SQChar Delim;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* The x, y, z and w components of this type.
|
||||
*/
|
||||
Value x, y, z, w;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Default constructor.
|
||||
*/
|
||||
Quaternion();
|
||||
|
||||
@ -55,257 +55,272 @@ struct Quaternion
|
||||
Quaternion(Value xv, Value yv, Value zv, Value wv);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Copy constructor.
|
||||
*/
|
||||
Quaternion(const Quaternion & o);
|
||||
Quaternion(const Quaternion & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Move constructor.
|
||||
*/
|
||||
~Quaternion();
|
||||
Quaternion(Quaternion && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Destructor.
|
||||
*/
|
||||
Quaternion & operator = (const Quaternion & o);
|
||||
~Quaternion() = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
Quaternion & operator = (const Quaternion & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
Quaternion & operator = (Quaternion && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Scalar value assignment operator.
|
||||
*/
|
||||
Quaternion & operator = (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Euler assignment operator.
|
||||
*/
|
||||
Quaternion & operator = (const Vector3 & q);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Four-dimensional vector assignment operator threated as a three-dimensional vector.
|
||||
*/
|
||||
Quaternion & operator = (const Vector4 & q);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Addition assignment operator.
|
||||
*/
|
||||
Quaternion & operator += (const Quaternion & q);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Subtraction assignment operator.
|
||||
*/
|
||||
Quaternion & operator -= (const Quaternion & q);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Multiplication assignment operator.
|
||||
*/
|
||||
Quaternion & operator *= (const Quaternion & q);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Division assignment operator.
|
||||
*/
|
||||
Quaternion & operator /= (const Quaternion & q);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Modulo assignment operator.
|
||||
*/
|
||||
Quaternion & operator %= (const Quaternion & q);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value addition assignment operator.
|
||||
*/
|
||||
Quaternion & operator += (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value subtraction assignment operator.
|
||||
*/
|
||||
Quaternion & operator -= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value multiplication assignment operator.
|
||||
*/
|
||||
Quaternion & operator *= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value division assignment operator.
|
||||
*/
|
||||
Quaternion & operator /= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value modulo assignment operator.
|
||||
*/
|
||||
Quaternion & operator %= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Pre-increment operator.
|
||||
*/
|
||||
Quaternion & operator ++ ();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Pre-decrement operator.
|
||||
*/
|
||||
Quaternion & operator -- ();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Post-increment operator.
|
||||
*/
|
||||
Quaternion operator ++ (int);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Post-decrement operator.
|
||||
*/
|
||||
Quaternion operator -- (int);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Addition operator.
|
||||
*/
|
||||
Quaternion operator + (const Quaternion & q) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Subtraction operator.
|
||||
*/
|
||||
Quaternion operator - (const Quaternion & q) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Multiplication operator.
|
||||
*/
|
||||
Quaternion operator * (const Quaternion & q) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Division operator.
|
||||
*/
|
||||
Quaternion operator / (const Quaternion & q) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Modulo operator.
|
||||
*/
|
||||
Quaternion operator % (const Quaternion & q) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value addition operator.
|
||||
*/
|
||||
Quaternion operator + (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value subtraction operator.
|
||||
*/
|
||||
Quaternion operator - (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value multiplication operator.
|
||||
*/
|
||||
Quaternion operator * (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value division operator.
|
||||
*/
|
||||
Quaternion operator / (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value modulo operator.
|
||||
*/
|
||||
Quaternion operator % (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Unary plus operator.
|
||||
*/
|
||||
Quaternion operator + () const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Unary minus operator.
|
||||
*/
|
||||
Quaternion operator - () const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Equality comparison operator.
|
||||
*/
|
||||
bool operator == (const Quaternion & q) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Inequality comparison operator.
|
||||
*/
|
||||
bool operator != (const Quaternion & q) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Less than comparison operator.
|
||||
*/
|
||||
bool operator < (const Quaternion & q) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Greater than comparison operator.
|
||||
*/
|
||||
bool operator > (const Quaternion & q) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Less than or equal comparison operator.
|
||||
*/
|
||||
bool operator <= (const Quaternion & q) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Greater than or equal comparison operator.
|
||||
*/
|
||||
bool operator >= (const Quaternion & q) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Used by the script engine to compare two instances of this type.
|
||||
*/
|
||||
Int32 Cmp(const Quaternion & q) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Used by the script engine to retrieve the name from instances of this type.
|
||||
*/
|
||||
static SQInteger Typename(HSQUIRRELVM vm);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Set all components to the specified scalar value.
|
||||
*/
|
||||
void Set(Value ns);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set all components to the specified values.
|
||||
*/
|
||||
void Set(Value nx, Value ny, Value nz);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set all components to the specified values.
|
||||
*/
|
||||
void Set(Value nx, Value ny, Value nz, Value nw);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Copy the values from another instance of this type.
|
||||
*/
|
||||
void Set(const Quaternion & q);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Copy the values from a three-dimensional vector as euler rotation.
|
||||
*/
|
||||
void Set(const Vector3 & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Copy the values from a four-dimensional vector.
|
||||
*/
|
||||
void Set(const Vector4 & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set the values extracted from the specified string using the specified delimiter.
|
||||
*/
|
||||
void Set(CSStr values, SQChar delim);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Generate random values for all components of this instance.
|
||||
*/
|
||||
void Generate();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Generate random values for all components of this instance within the specified bounds.
|
||||
*/
|
||||
void Generate(Value min, Value max);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Generate random values for all components of this instance within the specified bounds.
|
||||
*/
|
||||
void Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value zmin, Value zmax, Value wmin, Value wmax);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Clear the component values to default.
|
||||
*/
|
||||
void Clear()
|
||||
{
|
||||
@ -313,7 +328,7 @@ struct Quaternion
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Retrieve a new instance of this type with absolute component values.
|
||||
*/
|
||||
Quaternion Abs() const;
|
||||
};
|
||||
|
@ -35,6 +35,11 @@ PluginFuncs* _Func = NULL;
|
||||
PluginCallbacks* _Clbk = NULL;
|
||||
PluginInfo* _Info = NULL;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Common buffer to reduce memory allocations. To be immediately copied uppon return!
|
||||
*/
|
||||
static SQChar g_Buffer[4096];
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const char NumLimit< char >::Min = CHAR_MIN;
|
||||
const signed char NumLimit< signed char >::Min = SCHAR_MIN;
|
||||
@ -99,30 +104,52 @@ bool SToB(CSStr str)
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr ToStrF(CCStr fmt, ...)
|
||||
void SqThrowF(CCStr fmt, ...)
|
||||
{
|
||||
static char buf[128];
|
||||
// Initialize the argument list
|
||||
va_list args;
|
||||
va_start (args, fmt);
|
||||
int ret = vsnprintf(buf, sizeof(buf), fmt, args);
|
||||
if (ret < 0)
|
||||
{
|
||||
SqThrow("Failed to run the specified string format");
|
||||
buf[0] = 0;
|
||||
}
|
||||
// Write the requested contents
|
||||
if (snprintf(g_Buffer, sizeof(g_Buffer), fmt, args) < 0)
|
||||
strcpy(g_Buffer, "Unknown error has occurred");
|
||||
// Release the argument list
|
||||
va_end(args);
|
||||
return buf;
|
||||
// Throw the exception with the resulted message
|
||||
throw Sqrat::Exception(g_Buffer);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr ToStrF(CCStr fmt, ...)
|
||||
{
|
||||
// Prepare the arguments list
|
||||
va_list args;
|
||||
va_start (args, fmt);
|
||||
// Attempt to run the specified format
|
||||
int ret = vsnprintf(g_Buffer, sizeof(g_Buffer), fmt, args);
|
||||
// See if the format function failed
|
||||
if (ret < 0)
|
||||
SqThrowF("Failed to run the specified string format");
|
||||
// Finalized the arguments list
|
||||
va_end(args);
|
||||
// Return the resulted string
|
||||
return g_Buffer;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr ToStringF(CCStr fmt, ...)
|
||||
{
|
||||
// Acquire a moderately sized buffer
|
||||
Buffer b(128);
|
||||
// Prepare the arguments list
|
||||
va_list args;
|
||||
va_start (args, fmt);
|
||||
// Attempt to run the specified format
|
||||
if (b.WriteF(0, fmt, args) == 0)
|
||||
b.At< SQChar >(0) = 0;
|
||||
// Make sure the string is null terminated
|
||||
b.At(0) = 0;
|
||||
// Finalized the arguments list
|
||||
va_end(args);
|
||||
// Return the resulted string
|
||||
return b.Get< SQChar >();
|
||||
}
|
||||
|
||||
@ -280,22 +307,17 @@ const Color3 & GetRandomColor()
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Color3 GetColor(CSStr name)
|
||||
{
|
||||
Uint32 len = 0;
|
||||
// See if we actually have something to search for
|
||||
if(!name || (len = (Uint32)strlen(name)) <= 0)
|
||||
{
|
||||
SqThrow("Cannot extract values from an empty string");
|
||||
return Color3::NIL;
|
||||
}
|
||||
if(!name || *name == 0)
|
||||
SqThrowF("Cannot extract values from an empty string");
|
||||
// Clone the string into an editable version
|
||||
CCStr str = StrJustAlphaNum(name);
|
||||
str = StrToLowercase(str);
|
||||
// See if we still have a valid name after the cleanup
|
||||
if((len = (Uint32)strlen(name)) <= 0)
|
||||
{
|
||||
SqThrow("Cannot extract values from an invalid string: %s", name);
|
||||
return Color3::NIL;
|
||||
}
|
||||
if(!str || *str == 0)
|
||||
SqThrowF("Cannot extract values from an invalid string: %s", name);
|
||||
// Calculate the name length
|
||||
const Uint32 len = strlen(str);
|
||||
// Get the most significant characters used to identify a weapon
|
||||
SQChar a = str[0], b = 0, c = 0, d = str[len-1];
|
||||
// Look for deeper specifiers
|
||||
@ -885,19 +907,17 @@ Color3 GetColor(CSStr name)
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AABB GetAABB(CSStr str, SQChar delim)
|
||||
const AABB & GetAABB(CSStr str, SQChar delim)
|
||||
{
|
||||
static SQChar fs[] = _SC(" %f , %f , %f , %f , %f , %f ");
|
||||
static AABB box;
|
||||
|
||||
if (!str || *str == 0)
|
||||
SqThrowF("Cannot extract values from an empty string");
|
||||
|
||||
box.Clear();
|
||||
|
||||
if (strlen(str) <= 0)
|
||||
{
|
||||
SqThrow("Cannot extract values from an empty string");
|
||||
return box;
|
||||
}
|
||||
else if (delim != AABB::Delim)
|
||||
if (delim != AABB::Delim)
|
||||
{
|
||||
fs[4] = delim;
|
||||
fs[9] = delim;
|
||||
@ -920,19 +940,17 @@ AABB GetAABB(CSStr str, SQChar delim)
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Circle GetCircle(CSStr str, SQChar delim)
|
||||
const Circle & GetCircle(CSStr str, SQChar delim)
|
||||
{
|
||||
static SQChar fs[] = _SC(" %f , %f , %f ");
|
||||
static Circle circle;
|
||||
|
||||
//circle.Clear();
|
||||
if (!str || *str == 0)
|
||||
SqThrowF("Cannot extract values from an empty string");
|
||||
|
||||
if (strlen(str) <= 0)
|
||||
{
|
||||
SqThrow("Cannot extract values from an empty string");
|
||||
return circle;
|
||||
}
|
||||
else if (delim != Circle::Delim)
|
||||
circle.Clear();
|
||||
|
||||
if (delim != Circle::Delim)
|
||||
{
|
||||
fs[4] = delim;
|
||||
fs[9] = delim;
|
||||
@ -949,16 +967,15 @@ Circle GetCircle(CSStr str, SQChar delim)
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Color3 GetColor3(CSStr str, SQChar delim)
|
||||
const Color3 & GetColor3(CSStr str, SQChar delim)
|
||||
{
|
||||
static SQChar fs[] = _SC(" %u , %u , %u ");
|
||||
static Color3 col;
|
||||
|
||||
Uint32 r = 0, g = 0, b = 0;
|
||||
|
||||
if (strlen(str) <= 0)
|
||||
{
|
||||
SqThrow("Cannot extract values from an empty string");
|
||||
return Color3();
|
||||
}
|
||||
if (!str || *str == 0)
|
||||
SqThrowF("Cannot extract values from an empty string");
|
||||
else if (delim != Color3::Delim)
|
||||
{
|
||||
fs[4] = delim;
|
||||
@ -972,19 +989,23 @@ Color3 GetColor3(CSStr str, SQChar delim)
|
||||
|
||||
sscanf(str, &fs[0], &r, &g, &b);
|
||||
|
||||
return Color3(Color3::Value(r), Color3::Value(g), Color3::Value(b));
|
||||
col.r = static_cast< Color4::Value >(r);
|
||||
col.g = static_cast< Color4::Value >(g);
|
||||
col.b = static_cast< Color4::Value >(b);
|
||||
|
||||
return col;
|
||||
}
|
||||
|
||||
Color4 GetColor4(CSStr str, SQChar delim)
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const Color4 & GetColor4(CSStr str, SQChar delim)
|
||||
{
|
||||
static SQChar fs[] = _SC(" %u , %u , %u , %u ");
|
||||
static Color4 col;
|
||||
|
||||
Uint32 r = 0, g = 0, b = 0, a = 0;
|
||||
|
||||
if (strlen(str) <= 0)
|
||||
{
|
||||
SqThrow("Cannot extract values from an empty string");
|
||||
return Color4();
|
||||
}
|
||||
if (!str || *str == 0)
|
||||
SqThrowF("Cannot extract values from an empty string");
|
||||
else if (delim != Color4::Delim)
|
||||
{
|
||||
fs[4] = delim;
|
||||
@ -1000,23 +1021,26 @@ Color4 GetColor4(CSStr str, SQChar delim)
|
||||
|
||||
sscanf(str, &fs[0], &r, &g, &b, &a);
|
||||
|
||||
return Color4(Color4::Value(r), Color4::Value(g), Color4::Value(b), Color4::Value(a));
|
||||
col.r = static_cast< Color4::Value >(r);
|
||||
col.g = static_cast< Color4::Value >(g);
|
||||
col.b = static_cast< Color4::Value >(b);
|
||||
col.a = static_cast< Color4::Value >(a);
|
||||
|
||||
return col;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Quaternion GetQuaternion(CSStr str, SQChar delim)
|
||||
const Quaternion & GetQuaternion(CSStr str, SQChar delim)
|
||||
{
|
||||
static SQChar fs[] = _SC(" %f , %f , %f , %f ");
|
||||
static Quaternion quat;
|
||||
|
||||
//quat.Clear();
|
||||
if (!str || *str == 0)
|
||||
SqThrowF("Cannot extract values from an empty string");
|
||||
|
||||
if (strlen(str) <= 0)
|
||||
{
|
||||
SqThrow("Cannot extract values from an empty string");
|
||||
return quat;
|
||||
}
|
||||
else if (delim != Quaternion::Delim)
|
||||
quat.Clear();
|
||||
|
||||
if (delim != Quaternion::Delim)
|
||||
{
|
||||
fs[4] = delim;
|
||||
fs[9] = delim;
|
||||
@ -1034,19 +1058,18 @@ Quaternion GetQuaternion(CSStr str, SQChar delim)
|
||||
return quat;
|
||||
}
|
||||
|
||||
Sphere GetSphere(CSStr str, SQChar delim)
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const Sphere & GetSphere(CSStr str, SQChar delim)
|
||||
{
|
||||
static SQChar fs[] = _SC(" %f , %f , %f , %f ");
|
||||
static Sphere sphere;
|
||||
|
||||
//sphere.Clear();
|
||||
if (!str || *str == 0)
|
||||
SqThrowF("Cannot extract values from an empty string");
|
||||
|
||||
if (strlen(str) <= 0)
|
||||
{
|
||||
SqThrow("Cannot extract values from an empty string");
|
||||
return sphere;
|
||||
}
|
||||
else if (delim != Sphere::Delim)
|
||||
sphere.Clear();
|
||||
|
||||
if (delim != Sphere::Delim)
|
||||
{
|
||||
fs[4] = delim;
|
||||
fs[9] = delim;
|
||||
@ -1065,52 +1088,40 @@ Sphere GetSphere(CSStr str, SQChar delim)
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Vector2 GetVector2(CSStr str, SQChar delim)
|
||||
const Vector2 & GetVector2(CSStr str, SQChar delim)
|
||||
{
|
||||
static SQChar fs[] = _SC(" %f , %f ");
|
||||
static Vector2 vec;
|
||||
|
||||
//vec.Clear();
|
||||
if (!str || *str == 0)
|
||||
SqThrowF("Cannot extract values from an empty string");
|
||||
|
||||
if (strlen(str) <= 0)
|
||||
{
|
||||
SqThrow("Cannot extract values from an empty string");
|
||||
return vec;
|
||||
}
|
||||
else if (delim != Vector2::Delim)
|
||||
{
|
||||
vec.Clear();
|
||||
|
||||
if (delim != Vector2::Delim)
|
||||
fs[4] = delim;
|
||||
}
|
||||
else
|
||||
{
|
||||
fs[4] = Vector2::Delim;
|
||||
}
|
||||
|
||||
sscanf(str, &fs[0], &vec.x, &vec.y);
|
||||
|
||||
return vec;
|
||||
}
|
||||
|
||||
Vector2i GetVector2i(CSStr str, SQChar delim)
|
||||
const Vector2i & GetVector2i(CSStr str, SQChar delim)
|
||||
{
|
||||
static SQChar fs[] = _SC(" %d , %d ");
|
||||
static Vector2i vec;
|
||||
|
||||
//vec.Clear();
|
||||
if (!str || *str == 0)
|
||||
SqThrowF("Cannot extract values from an empty string");
|
||||
|
||||
if (strlen(str) <= 0)
|
||||
{
|
||||
SqThrow("Cannot extract values from an empty string");
|
||||
return vec;
|
||||
}
|
||||
else if (delim != Vector2i::Delim)
|
||||
{
|
||||
vec.Clear();
|
||||
|
||||
if (delim != Vector2i::Delim)
|
||||
fs[4] = delim;
|
||||
}
|
||||
else
|
||||
{
|
||||
fs[4] = Vector2i::Delim;
|
||||
}
|
||||
|
||||
sscanf(str, &fs[0], &vec.x, &vec.y);
|
||||
|
||||
@ -1118,19 +1129,17 @@ Vector2i GetVector2i(CSStr str, SQChar delim)
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Vector3 GetVector3(CSStr str, SQChar delim)
|
||||
const Vector3 & GetVector3(CSStr str, SQChar delim)
|
||||
{
|
||||
static SQChar fs[] = _SC(" %f , %f , %f ");
|
||||
static Vector3 vec;
|
||||
|
||||
if (!str || *str == 0)
|
||||
SqThrowF("Cannot extract values from an empty string");
|
||||
|
||||
vec.Clear();
|
||||
|
||||
if (strlen(str) <= 0)
|
||||
{
|
||||
SqThrow("Cannot extract values from an empty string");
|
||||
return vec;
|
||||
}
|
||||
else if (delim != Vector3::Delim)
|
||||
if (delim != Vector3::Delim)
|
||||
{
|
||||
fs[4] = delim;
|
||||
fs[9] = delim;
|
||||
@ -1146,19 +1155,17 @@ Vector3 GetVector3(CSStr str, SQChar delim)
|
||||
return vec;
|
||||
}
|
||||
|
||||
Vector4 GetVector4(CSStr str, SQChar delim)
|
||||
const Vector4 & GetVector4(CSStr str, SQChar delim)
|
||||
{
|
||||
static SQChar fs[] = _SC(" %f , %f , %f , %f ");
|
||||
static Vector4 vec;
|
||||
|
||||
if (!str || *str == 0)
|
||||
SqThrowF("Cannot extract values from an empty string");
|
||||
|
||||
vec.Clear();
|
||||
|
||||
if (strlen(str) <= 0)
|
||||
{
|
||||
SqThrow("Cannot extract values from an empty string");
|
||||
return vec;
|
||||
}
|
||||
else if (delim != Vector4::Delim)
|
||||
if (delim != Vector4::Delim)
|
||||
{
|
||||
fs[4] = delim;
|
||||
fs[9] = delim;
|
||||
|
@ -5,8 +5,8 @@
|
||||
#include "SqBase.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
#include <cmath>
|
||||
#include <cassert>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <vcmp.h>
|
||||
@ -19,7 +19,7 @@ namespace SqMod {
|
||||
extern const SQChar * g_EmptyStr;
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Proxies to comunicate with the server.
|
||||
* Proxies to communicate with the server.
|
||||
*/
|
||||
extern PluginFuncs* _Func;
|
||||
extern PluginCallbacks* _Clbk;
|
||||
@ -28,7 +28,9 @@ extern PluginInfo* _Info;
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template < typename T > struct NumLimit;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Basic minimum and maximum values for primitive numeric types.
|
||||
*/
|
||||
template <> struct NumLimit< char > { static const char Min, Max; };
|
||||
template <> struct NumLimit< signed char > { static const signed char Min, Max; };
|
||||
template <> struct NumLimit< unsigned char > { static const unsigned char Min, Max; };
|
||||
@ -44,7 +46,58 @@ template <> struct NumLimit< float > { static const float Min, Max; };
|
||||
template <> struct NumLimit< double > { static const double Min, Max; };
|
||||
template <> struct NumLimit< long double > { static const long double Min, Max; };
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Implements RAII to restore the VM stack to it's initial size on function exit.
|
||||
*/
|
||||
struct StackGuard
|
||||
{
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Base constructor.
|
||||
*/
|
||||
StackGuard(HSQUIRRELVM vm)
|
||||
: m_Top(sq_gettop(vm)), m_VM(vm)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor. (disabled)
|
||||
*/
|
||||
StackGuard(const StackGuard &) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move constructor. (disabled)
|
||||
*/
|
||||
StackGuard(StackGuard &&) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
*/
|
||||
~StackGuard()
|
||||
{
|
||||
sq_pop(m_VM, sq_gettop(m_VM) - m_Top);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator. (disabled)
|
||||
*/
|
||||
StackGuard & operator = (const StackGuard &) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator. (disabled)
|
||||
*/
|
||||
StackGuard & operator = (StackGuard &&) = delete;
|
||||
|
||||
private:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
Int32 m_Top; /* The top of the stack when this instance was created. */
|
||||
HSQUIRRELVM m_VM; /* The VM where the stack should be restored. */
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Perform an equality comparison between two values taking into account floating point issues.
|
||||
*/
|
||||
template< typename T > inline bool EpsEq(const T a, const T b)
|
||||
{
|
||||
return abs(a - b) <= 0;
|
||||
@ -60,7 +113,9 @@ template <> inline bool EpsEq(const Float64 a, const Float64 b)
|
||||
return fabs(a - b) <= 0.000000001d;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Perform a less than comparison between two values taking into account floating point issues.
|
||||
*/
|
||||
template< typename T > inline bool EpsLt(const T a, const T b)
|
||||
{
|
||||
return !EpsEq(a, b) && (a < b);
|
||||
@ -76,7 +131,9 @@ template <> inline bool EpsLt(const Float64 a, const Float64 b)
|
||||
return !EpsEq(a, b) && (a - b) < 0.000000001d;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Perform a greater than comparison between two values taking into account floating point issues.
|
||||
*/
|
||||
template< typename T > inline bool EpsGt(const T a, const T b)
|
||||
{
|
||||
return !EpsEq(a, b) && (a > b);
|
||||
@ -92,7 +149,10 @@ template <> inline bool EpsGt(const Float64 a, const Float64 b)
|
||||
return !EpsEq(a, b) && (a - b) > 0.000000001d;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Perform a less than or equal comparison between two values taking into account
|
||||
* floating point issues.
|
||||
*/
|
||||
template< typename T > inline bool EpsLtEq(const T a, const T b)
|
||||
{
|
||||
return !EpsEq(a, b) || (a < b);
|
||||
@ -108,7 +168,10 @@ template <> inline bool EpsLtEq(const Float64 a, const Float64 b)
|
||||
return !EpsEq(a, b) || (a - b) < 0.000000001d;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Perform a greater than or equal comparison between two values taking into account
|
||||
* floating point issues.
|
||||
*/
|
||||
template< typename T > inline bool EpsGtEq(const T a, const T b)
|
||||
{
|
||||
return !EpsEq(a, b) || (a > b);
|
||||
@ -124,7 +187,9 @@ template <> inline bool EpsGtEq(const Float64 a, const Float64 b)
|
||||
return !EpsEq(a, b) || (a - b) > 0.000000001d;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Force a value to be within a certain range.
|
||||
*/
|
||||
template< typename T > inline T Clamp(T val, T min, T max)
|
||||
{
|
||||
return val < min ? min : (val > max ? max : val);
|
||||
@ -144,6 +209,142 @@ inline Uint32 NextPow2(Uint32 num)
|
||||
return ++num;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Output a message only if the _DEBUG was defined.
|
||||
*/
|
||||
void OutputDebug(const char * msg, ...);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Output a formatted user message to the console.
|
||||
*/
|
||||
void OutputMessage(const char * msg, ...);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Output a formatted error message to the console.
|
||||
*/
|
||||
void OutputError(const char * msg, ...);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve a reference to a null script object.
|
||||
*/
|
||||
Object & NullObject();
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve a reference to a null/empty script array.
|
||||
*/
|
||||
Array & NullArray();
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Retrieve a reference to a null script function.
|
||||
*/
|
||||
Function & NullFunction();
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Create a script object from the specified value on the default VM.
|
||||
*/
|
||||
template < typename T > Object MakeObject(const T & v)
|
||||
{
|
||||
PushVar< T >(DefaultVM::Get(), v);
|
||||
Var< Object > var(DefaultVM::Get(), -1);
|
||||
sq_pop(DefaultVM::Get(), 1);
|
||||
return var.value;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Create a script object from the specified value on the specified VM.
|
||||
*/
|
||||
template < typename T > Object MakeObject(HSQUIRRELVM vm, const T & v)
|
||||
{
|
||||
PushVar< T >(vm, v);
|
||||
Var< Object > var(vm, -1);
|
||||
sq_pop(vm, 1);
|
||||
return var.value;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Simple function to check whether the specified string can be considered as a boolean value
|
||||
*/
|
||||
bool SToB(CSStr str);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Generate a formatted string and throw it as a sqrat exception.
|
||||
*/
|
||||
void SqThrowF(CCStr fmt, ...);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Quickly generate a formatted string on a small static buffer without any memory allocations.
|
||||
*/
|
||||
CSStr ToStrF(CCStr fmt, ...);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Generate a formatted string on a temporary buffer and return the string but not the buffer.
|
||||
*/
|
||||
CSStr ToStringF(CCStr fmt, ...);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Obtain a randomly chosen color from a list of known colors.
|
||||
*/
|
||||
const Color3 & GetRandomColor();
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Attempt to identify the color in the specified name and return it.
|
||||
*/
|
||||
Color3 GetColor(CSStr name);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Extract the values for components of the AABB type from a string.
|
||||
*/
|
||||
const AABB & GetAABB(CSStr str, SQChar delim);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Extract the values for components of the Circle type from a string.
|
||||
*/
|
||||
const Circle & GetCircle(CSStr str, SQChar delim);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Extract the values for components of the Color3 type from a string.
|
||||
*/
|
||||
const Color3 & GetColor3(CSStr str, SQChar delim);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Extract the values for components of the Color4 type from a string.
|
||||
*/
|
||||
const Color4 & GetColor4(CSStr str, SQChar delim);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Extract the values for components of the Quaternion type from a string.
|
||||
*/
|
||||
const Quaternion & GetQuaternion(CSStr str, SQChar delim);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Extract the values for components of the Sphere type from a string.
|
||||
*/
|
||||
const Sphere & GetSphere(CSStr str, SQChar delim);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Extract the values for components of the Vector2 type from a string.
|
||||
*/
|
||||
const Vector2 & GetVector2(CSStr str, SQChar delim);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Extract the values for components of the Vector2i type from a string.
|
||||
*/
|
||||
const Vector2i & GetVector2i(CSStr str, SQChar delim);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Extract the values for components of the Vector3 type from a string.
|
||||
*/
|
||||
const Vector3 & GetVector3(CSStr str, SQChar delim);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Extract the values for components of the Vector4 type from a string.
|
||||
*/
|
||||
const Vector4 & GetVector4(CSStr str, SQChar delim);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Forward declarations of the logging functions to avoid including the logger everywhere.
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void LogDbg(CCStr fmt, ...);
|
||||
void LogUsr(CCStr fmt, ...);
|
||||
@ -180,84 +381,6 @@ bool cLogSWrn(bool cond, CCStr fmt, ...);
|
||||
bool cLogSErr(bool cond, CCStr fmt, ...);
|
||||
bool cLogSFtl(bool cond, CCStr fmt, ...);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void SqThrow(CCStr fmt, ...);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Output a message only if the _DEBUG was defined.
|
||||
*/
|
||||
void OutputDebug(const char * msg, ...);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Output a formatted user message to the console.
|
||||
*/
|
||||
void OutputMessage(const char * msg, ...);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Output a formatted error message to the console.
|
||||
*/
|
||||
void OutputError(const char * msg, ...);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Object & NullObject();
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Array & NullArray();
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Function & NullFunction();
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template < typename T > Object MakeObject(const T & v)
|
||||
{
|
||||
PushVar< T >(DefaultVM::Get(), v);
|
||||
Var< Object > var(DefaultVM::Get(), -1);
|
||||
sq_pop(DefaultVM::Get(), 1);
|
||||
return var.value;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template < typename T > Object MakeObject(HSQUIRRELVM vm, const T & v)
|
||||
{
|
||||
PushVar< T >(vm, v);
|
||||
Var< Object > var(vm, -1);
|
||||
sq_pop(vm, 1);
|
||||
return var.value;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Simple function to check whether the specified string can be considered as a boolean value
|
||||
*/
|
||||
bool SToB(CSStr str);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
CSStr ToStrF(CCStr fmt, ...);
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
CSStr ToStringF(CCStr fmt, ...);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const Color3 & GetRandomColor();
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Value extractors.
|
||||
*/
|
||||
Color3 GetColor(CSStr name);
|
||||
AABB GetAABB(CSStr str, SQChar delim);
|
||||
Circle GetCircle(CSStr str, SQChar delim);
|
||||
Color3 GetColor3(CSStr str, SQChar delim);
|
||||
Color4 GetColor4(CSStr str, SQChar delim);
|
||||
Quaternion GetQuaternion(CSStr str, SQChar delim);
|
||||
Sphere GetSphere(CSStr str, SQChar delim);
|
||||
Vector2 GetVector2(CSStr str, SQChar delim);
|
||||
Vector2i GetVector2i(CSStr str, SQChar delim);
|
||||
Vector3 GetVector3(CSStr str, SQChar delim);
|
||||
Vector4 GetVector4(CSStr str, SQChar delim);
|
||||
|
||||
} // Namespace:: SqMod
|
||||
|
||||
#endif // _BASE_SHARED_HPP_
|
||||
|
@ -14,6 +14,14 @@ const Sphere Sphere::MAX = Sphere(NumLimit< Sphere::Value >::Max);
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQChar Sphere::Delim = ',';
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger Sphere::Typename(HSQUIRRELVM vm)
|
||||
{
|
||||
static SQChar name[] = _SC("Sphere");
|
||||
sq_pushstring(vm, name, sizeof(name));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Sphere::Sphere()
|
||||
: pos(0.0), rad(0.0)
|
||||
@ -42,27 +50,6 @@ Sphere::Sphere(Value xv, Value yv, Value zv, Value rv)
|
||||
/* ... */
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Sphere::Sphere(const Sphere & o)
|
||||
: pos(o.pos), rad(o.rad)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Sphere::~Sphere()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Sphere & Sphere::operator = (const Sphere & o)
|
||||
{
|
||||
pos = o.pos;
|
||||
rad = o.rad;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Sphere & Sphere::operator = (Value r)
|
||||
{
|
||||
@ -341,7 +328,7 @@ Int32 Sphere::Cmp(const Sphere & o) const
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr Sphere::ToString() const
|
||||
{
|
||||
return ToStringF("%f,%f,%f,%f", pos.x, pos.y, pos.z, rad);
|
||||
return ToStrF("%f,%f,%f,%f", pos.x, pos.y, pos.z, rad);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -395,35 +382,28 @@ void Sphere::Generate()
|
||||
void Sphere::Generate(Value min, Value max, bool r)
|
||||
{
|
||||
if (EpsLt(max, min))
|
||||
{
|
||||
SqThrow("max value is lower than min value");
|
||||
}
|
||||
SqThrowF("max value is lower than min value");
|
||||
else if (r)
|
||||
{
|
||||
rad = GetRandomFloat32(min, max);
|
||||
}
|
||||
else
|
||||
{
|
||||
pos.Generate(min, max);
|
||||
}
|
||||
}
|
||||
|
||||
void Sphere::Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value zmin, Value zmax)
|
||||
{
|
||||
if (EpsLt(xmax, xmin) || EpsLt(ymax, ymin) || EpsLt(zmax, zmin))
|
||||
SqThrowF("max value is lower than min value");
|
||||
|
||||
pos.Generate(xmin, xmax, ymin, ymax, zmin, zmax);
|
||||
}
|
||||
|
||||
void Sphere::Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value zmin, Value zmax, Value rmin, Value rmax)
|
||||
{
|
||||
if (EpsLt(rmax, rmin))
|
||||
{
|
||||
SqThrow("max value is lower than min value");
|
||||
}
|
||||
else
|
||||
{
|
||||
pos.Generate(xmin, xmax, ymin, ymax, zmin, zmax);
|
||||
rad = GetRandomFloat32(rmin, rmax);
|
||||
}
|
||||
if (EpsLt(xmax, xmin) || EpsLt(ymax, ymin) || EpsLt(zmax, zmin) || EpsLt(rmax, rmin))
|
||||
SqThrowF("max value is lower than min value");
|
||||
|
||||
pos.Generate(xmin, xmax, ymin, ymax, zmin, zmax);
|
||||
rad = GetRandomFloat32(rmin, rmax);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -452,6 +432,7 @@ void Register_Sphere(HSQUIRRELVM vm)
|
||||
.Prop(_SC("abs"), &Sphere::Abs)
|
||||
/* Core Metamethods */
|
||||
.Func(_SC("_tostring"), &Sphere::ToString)
|
||||
.SquirrelFunc(_SC("_typename"), &Sphere::Typename)
|
||||
.Func(_SC("_cmp"), &Sphere::Cmp)
|
||||
/* Metamethods */
|
||||
.Func<Sphere (Sphere::*)(const Sphere &) const>(_SC("_add"), &Sphere::operator +)
|
||||
|
@ -9,355 +9,370 @@
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Class used to represent a three-dimensional sphere.
|
||||
*/
|
||||
struct Sphere
|
||||
{
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* The type of value used by components of type.
|
||||
*/
|
||||
typedef float Value;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Helper instances for common values mostly used as return types or comparison.
|
||||
*/
|
||||
static const Sphere NIL;
|
||||
static const Sphere MIN;
|
||||
static const Sphere MAX;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* The delimiter character to be used when extracting values from strings.
|
||||
*/
|
||||
static SQChar Delim;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* The position and radius components of this type.
|
||||
*/
|
||||
Vector3 pos;
|
||||
Value rad;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Default constructor.
|
||||
*/
|
||||
Sphere();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Construct a sphere at position 0,0,0 using the specified radius.
|
||||
*/
|
||||
Sphere(Value rv);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Construct a sphere at the specified position using the specified radius.
|
||||
*/
|
||||
Sphere(const Vector3 & pv, Value rv);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Construct a sphere at the specified position using the specified radius.
|
||||
*/
|
||||
Sphere(Value xv, Value yv, Value zv, Value rv);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Copy constructor.
|
||||
*/
|
||||
Sphere(const Sphere & o);
|
||||
Sphere(const Sphere & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Move constructor.
|
||||
*/
|
||||
~Sphere();
|
||||
Sphere(Sphere && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Destructor.
|
||||
*/
|
||||
Sphere & operator = (const Sphere & o);
|
||||
~Sphere() = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
Sphere & operator = (const Sphere & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
Sphere & operator = (Sphere && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Radius assignment operator.
|
||||
*/
|
||||
Sphere & operator = (Value r);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Position assignment operator.
|
||||
*/
|
||||
Sphere & operator = (const Vector3 & p);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Addition assignment operator.
|
||||
*/
|
||||
Sphere & operator += (const Sphere & s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Subtraction assignment operator.
|
||||
*/
|
||||
Sphere & operator -= (const Sphere & s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Multiplication assignment operator.
|
||||
*/
|
||||
Sphere & operator *= (const Sphere & s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Division assignment operator.
|
||||
*/
|
||||
Sphere & operator /= (const Sphere & s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Modulo assignment operator.
|
||||
*/
|
||||
Sphere & operator %= (const Sphere & s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Radius addition assignment operator.
|
||||
*/
|
||||
Sphere & operator += (Value r);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Radius subtraction assignment operator.
|
||||
*/
|
||||
Sphere & operator -= (Value r);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Radius multiplication assignment operator.
|
||||
*/
|
||||
Sphere & operator *= (Value r);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Radius division assignment operator.
|
||||
*/
|
||||
Sphere & operator /= (Value r);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Radius modulo assignment operator.
|
||||
*/
|
||||
Sphere & operator %= (Value r);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Position addition assignment operator.
|
||||
*/
|
||||
Sphere & operator += (const Vector3 & p);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Position subtraction assignment operator.
|
||||
*/
|
||||
Sphere & operator -= (const Vector3 & p);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Position multiplication assignment operator.
|
||||
*/
|
||||
Sphere & operator *= (const Vector3 & p);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Position division assignment operator.
|
||||
*/
|
||||
Sphere & operator /= (const Vector3 & p);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Position modulo assignment operator.
|
||||
*/
|
||||
Sphere & operator %= (const Vector3 & p);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Pre-increment operator.
|
||||
*/
|
||||
Sphere & operator ++ ();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Pre-decrement operator.
|
||||
*/
|
||||
Sphere & operator -- ();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Post-increment operator.
|
||||
*/
|
||||
Sphere operator ++ (int);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Post-decrement operator.
|
||||
*/
|
||||
Sphere operator -- (int);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Addition operator.
|
||||
*/
|
||||
Sphere operator + (const Sphere & s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Subtraction operator.
|
||||
*/
|
||||
Sphere operator - (const Sphere & s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Multiplication operator.
|
||||
*/
|
||||
Sphere operator * (const Sphere & s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Division operator.
|
||||
*/
|
||||
Sphere operator / (const Sphere & s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Modulo operator.
|
||||
*/
|
||||
Sphere operator % (const Sphere & s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Radius addition operator.
|
||||
*/
|
||||
Sphere operator + (Value r) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Radius subtraction operator.
|
||||
*/
|
||||
Sphere operator - (Value r) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Radius multiplication operator.
|
||||
*/
|
||||
Sphere operator * (Value r) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Radius division operator.
|
||||
*/
|
||||
Sphere operator / (Value r) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Radius modulo operator.
|
||||
*/
|
||||
Sphere operator % (Value r) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Position addition operator.
|
||||
*/
|
||||
Sphere operator + (const Vector3 & p) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Position subtraction operator.
|
||||
*/
|
||||
Sphere operator - (const Vector3 & p) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Position multiplication operator.
|
||||
*/
|
||||
Sphere operator * (const Vector3 & p) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Position division operator.
|
||||
*/
|
||||
Sphere operator / (const Vector3 & p) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Position modulo operator.
|
||||
*/
|
||||
Sphere operator % (const Vector3 & p) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Unary plus operator.
|
||||
*/
|
||||
Sphere operator + () const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Unary minus operator.
|
||||
*/
|
||||
Sphere operator - () const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Equality comparison operator.
|
||||
*/
|
||||
bool operator == (const Sphere & s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Inequality comparison operator.
|
||||
*/
|
||||
bool operator != (const Sphere & s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Less than comparison operator.
|
||||
*/
|
||||
bool operator < (const Sphere & s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Greater than comparison operator.
|
||||
*/
|
||||
bool operator > (const Sphere & s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Less than or equal comparison operator.
|
||||
*/
|
||||
bool operator <= (const Sphere & s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Greater than or equal comparison operator.
|
||||
*/
|
||||
bool operator >= (const Sphere & s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Used by the script engine to compare two instances of this type.
|
||||
*/
|
||||
Int32 Cmp(const Sphere & s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Used by the script engine to retrieve the name from instances of this type.
|
||||
*/
|
||||
static SQInteger Typename(HSQUIRRELVM vm);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Set the specified radius.
|
||||
*/
|
||||
void Set(Value nr);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Copy the sphere from another instance of this type.
|
||||
*/
|
||||
void Set(const Sphere & ns);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set the position from the specified position.
|
||||
*/
|
||||
void Set(const Vector3 & np);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set the specified position and radius.
|
||||
*/
|
||||
void Set(const Vector3 & np, Value nr);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set the specified position.
|
||||
*/
|
||||
void Set(Value nx, Value ny, Value nz);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set the specified position and radius.
|
||||
*/
|
||||
void Set(Value nx, Value ny, Value nz, Value nr);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set the values extracted from the specified string using the specified delimiter.
|
||||
*/
|
||||
void Set(CSStr values, SQChar delim);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Generate a randomly sized and positioned sphere.
|
||||
*/
|
||||
void Generate();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Generate a randomly sized or positioned sphere within the specified bounds.
|
||||
*/
|
||||
void Generate(Value min, Value max, bool r);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Generate a randomly positioned sphere within the specified bounds.
|
||||
*/
|
||||
void Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value zmin, Value zmax);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Generate a randomly sized and positioned sphere within the specified bounds.
|
||||
*/
|
||||
void Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value zmin, Value zmax, Value rmin, Value rmax);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Clear the component values to default.
|
||||
*/
|
||||
void Clear()
|
||||
{
|
||||
@ -365,7 +380,7 @@ struct Sphere
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Retrieve a new instance of this type with absolute component values.
|
||||
*/
|
||||
Sphere Abs() const;
|
||||
};
|
||||
|
@ -15,6 +15,14 @@ const Vector2 Vector2::MAX = Vector2(NumLimit< Vector2::Value >::Max);
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQChar Vector2::Delim = ',';
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger Vector2::Typename(HSQUIRRELVM vm)
|
||||
{
|
||||
static SQChar name[] = _SC("Vector2");
|
||||
sq_pushstring(vm, name, sizeof(name));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Vector2::Vector2()
|
||||
: x(0.0), y(0.0)
|
||||
@ -36,27 +44,6 @@ Vector2::Vector2(Value xv, Value yv)
|
||||
/* ... */
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Vector2::Vector2(const Vector2 & o)
|
||||
: x(o.x), y(o.y)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Vector2::~Vector2()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Vector2 & Vector2::operator = (const Vector2 & o)
|
||||
{
|
||||
x = o.x;
|
||||
y = o.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Vector2 & Vector2::operator = (Value s)
|
||||
{
|
||||
@ -290,7 +277,7 @@ Int32 Vector2::Cmp(const Vector2 & o) const
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr Vector2::ToString() const
|
||||
{
|
||||
return ToStringF("%f,%f", x, y);
|
||||
return ToStrF("%f,%f", x, y);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -335,27 +322,19 @@ void Vector2::Generate()
|
||||
void Vector2::Generate(Value min, Value max)
|
||||
{
|
||||
if (EpsLt(max, min))
|
||||
{
|
||||
SqThrow("max value is lower than min value");
|
||||
}
|
||||
else
|
||||
{
|
||||
x = GetRandomFloat32(min, max);
|
||||
y = GetRandomFloat32(min, max);
|
||||
}
|
||||
SqThrowF("max value is lower than min value");
|
||||
|
||||
x = GetRandomFloat32(min, max);
|
||||
y = GetRandomFloat32(min, max);
|
||||
}
|
||||
|
||||
void Vector2::Generate(Value xmin, Value xmax, Value ymin, Value ymax)
|
||||
{
|
||||
if (EpsLt(xmax, xmin) || EpsLt(ymax, ymin))
|
||||
{
|
||||
SqThrow("max value is lower than min value");
|
||||
}
|
||||
else
|
||||
{
|
||||
x = GetRandomFloat32(ymin, ymax);
|
||||
y = GetRandomFloat32(xmin, xmax);
|
||||
}
|
||||
SqThrowF("max value is lower than min value");
|
||||
|
||||
x = GetRandomFloat32(ymin, ymax);
|
||||
y = GetRandomFloat32(xmin, xmax);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -383,6 +362,7 @@ void Register_Vector2(HSQUIRRELVM vm)
|
||||
.Prop(_SC("abs"), &Vector2::Abs)
|
||||
/* Core Metamethods */
|
||||
.Func(_SC("_tostring"), &Vector2::ToString)
|
||||
.SquirrelFunc(_SC("_typename"), &Vector2::Typename)
|
||||
.Func(_SC("_cmp"), &Vector2::Cmp)
|
||||
/* Metamethods */
|
||||
.Func<Vector2 (Vector2::*)(const Vector2 &) const>(_SC("_add"), &Vector2::operator +)
|
||||
|
@ -8,289 +8,304 @@
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Class used to represent a two-dimensional vector.
|
||||
*/
|
||||
struct Vector2
|
||||
{
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* The type of value used by components of type.
|
||||
*/
|
||||
typedef float Value;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Helper instances for common values mostly used as return types or comparison.
|
||||
*/
|
||||
static const Vector2 NIL;
|
||||
static const Vector2 MIN;
|
||||
static const Vector2 MAX;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* The delimiter character to be used when extracting values from strings.
|
||||
*/
|
||||
static SQChar Delim;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* The x and y components of this type.
|
||||
*/
|
||||
Value x, y;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Default constructor.
|
||||
*/
|
||||
Vector2();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Construct a vector with the same scalar value for all components.
|
||||
*/
|
||||
Vector2(Value sv);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Construct a vector with the specified component values.
|
||||
*/
|
||||
Vector2(Value xv, Value yv);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Copy constructor.
|
||||
*/
|
||||
Vector2(const Vector2 & o);
|
||||
Vector2(const Vector2 & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Move constructor.
|
||||
*/
|
||||
~Vector2();
|
||||
Vector2(Vector2 && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Destructor.
|
||||
*/
|
||||
Vector2 & operator = (const Vector2 & o);
|
||||
~Vector2() = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
Vector2 & operator = (const Vector2 & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
Vector2 & operator = (Vector2 && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Scalar value assignment operator.
|
||||
*/
|
||||
Vector2 & operator = (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* String assignment operator.
|
||||
*/
|
||||
Vector2 & operator = (CSStr values);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Integral two-dimensional vector assignment.
|
||||
*/
|
||||
Vector2 & operator = (const Vector2i & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Addition assignment operator.
|
||||
*/
|
||||
Vector2 & operator += (const Vector2 & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Subtraction assignment operator.
|
||||
*/
|
||||
Vector2 & operator -= (const Vector2 & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Multiplication assignment operator.
|
||||
*/
|
||||
Vector2 & operator *= (const Vector2 & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Division assignment operator.
|
||||
*/
|
||||
Vector2 & operator /= (const Vector2 & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Modulo assignment operator.
|
||||
*/
|
||||
Vector2 & operator %= (const Vector2 & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value addition assignment operator.
|
||||
*/
|
||||
Vector2 & operator += (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value subtraction assignment operator.
|
||||
*/
|
||||
Vector2 & operator -= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value multiplication assignment operator.
|
||||
*/
|
||||
Vector2 & operator *= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value division assignment operator.
|
||||
*/
|
||||
Vector2 & operator /= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value modulo assignment operator.
|
||||
*/
|
||||
Vector2 & operator %= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Pre-increment operator.
|
||||
*/
|
||||
Vector2 & operator ++ ();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Pre-decrement operator.
|
||||
*/
|
||||
Vector2 & operator -- ();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Post-increment operator.
|
||||
*/
|
||||
Vector2 operator ++ (int);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Post-decrement operator.
|
||||
*/
|
||||
Vector2 operator -- (int);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Addition operator.
|
||||
*/
|
||||
Vector2 operator + (const Vector2 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Subtraction operator.
|
||||
*/
|
||||
Vector2 operator - (const Vector2 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Multiplication operator.
|
||||
*/
|
||||
Vector2 operator * (const Vector2 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Division operator.
|
||||
*/
|
||||
Vector2 operator / (const Vector2 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Modulo operator.
|
||||
*/
|
||||
Vector2 operator % (const Vector2 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value addition operator.
|
||||
*/
|
||||
Vector2 operator + (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value subtraction operator.
|
||||
*/
|
||||
Vector2 operator - (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value multiplication operator.
|
||||
*/
|
||||
Vector2 operator * (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value division operator.
|
||||
*/
|
||||
Vector2 operator / (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value modulo operator.
|
||||
*/
|
||||
Vector2 operator % (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Unary plus operator.
|
||||
*/
|
||||
Vector2 operator + () const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Unary minus operator.
|
||||
*/
|
||||
Vector2 operator - () const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Equality comparison operator.
|
||||
*/
|
||||
bool operator == (const Vector2 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Inequality comparison operator.
|
||||
*/
|
||||
bool operator != (const Vector2 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Less than comparison operator.
|
||||
*/
|
||||
bool operator < (const Vector2 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Greater than comparison operator.
|
||||
*/
|
||||
bool operator > (const Vector2 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Less than or equal comparison operator.
|
||||
*/
|
||||
bool operator <= (const Vector2 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Greater than or equal comparison operator.
|
||||
*/
|
||||
bool operator >= (const Vector2 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Used by the script engine to compare two instances of this type.
|
||||
*/
|
||||
Int32 Cmp(const Vector2 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Used by the script engine to retrieve the name from instances of this type.
|
||||
*/
|
||||
static SQInteger Typename(HSQUIRRELVM vm);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Set all components to the specified scalar value.
|
||||
*/
|
||||
void Set(Value ns);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set all components to the specified values.
|
||||
*/
|
||||
void Set(Value nx, Value ny);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Copy the values from another instance of this type.
|
||||
*/
|
||||
void Set(const Vector2 & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Copy the values from an integral two-dimensional vector.
|
||||
*/
|
||||
void Set(const Vector2i & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set the values extracted from the specified string using the specified delimiter.
|
||||
*/
|
||||
void Set(CSStr values, SQChar delim);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Generate random values for all components of this instance.
|
||||
*/
|
||||
void Generate();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Generate random values for all components of this instance within the specified bounds.
|
||||
*/
|
||||
void Generate(Value min, Value max);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Generate random values for all components of this instance within the specified bounds.
|
||||
*/
|
||||
void Generate(Value xmin, Value xmax, Value ymin, Value ymax);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Clear the component values to default.
|
||||
*/
|
||||
void Clear()
|
||||
{
|
||||
@ -298,7 +313,7 @@ struct Vector2
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Retrieve a new instance of this type with absolute component values.
|
||||
*/
|
||||
Vector2 Abs() const;
|
||||
};
|
||||
|
@ -15,6 +15,14 @@ const Vector2i Vector2i::MAX = Vector2i(NumLimit< Vector2i::Value >::Max);
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQChar Vector2i::Delim = ',';
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger Vector2i::Typename(HSQUIRRELVM vm)
|
||||
{
|
||||
static SQChar name[] = _SC("Vector2i");
|
||||
sq_pushstring(vm, name, sizeof(name));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Vector2i::Vector2i()
|
||||
: x(0), y(0)
|
||||
@ -36,27 +44,6 @@ Vector2i::Vector2i(Value xv, Value yv)
|
||||
/* ... */
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Vector2i::Vector2i(const Vector2i & o)
|
||||
: x(o.x), y(o.y)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Vector2i::~Vector2i()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Vector2i & Vector2i::operator = (const Vector2i & o)
|
||||
{
|
||||
x = o.x;
|
||||
y = o.y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Vector2i & Vector2i::operator = (Value s)
|
||||
{
|
||||
@ -416,7 +403,7 @@ Int32 Vector2i::Cmp(const Vector2i & o) const
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr Vector2i::ToString() const
|
||||
{
|
||||
return ToStringF("%d,%d", x, y);
|
||||
return ToStrF("%d,%d", x, y);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -461,27 +448,19 @@ void Vector2i::Generate()
|
||||
void Vector2i::Generate(Value min, Value max)
|
||||
{
|
||||
if (max < min)
|
||||
{
|
||||
SqThrow("max value is lower than min value");
|
||||
}
|
||||
else
|
||||
{
|
||||
x = GetRandomInt32(min, max);
|
||||
y = GetRandomInt32(min, max);
|
||||
}
|
||||
SqThrowF("max value is lower than min value");
|
||||
|
||||
x = GetRandomInt32(min, max);
|
||||
y = GetRandomInt32(min, max);
|
||||
}
|
||||
|
||||
void Vector2i::Generate(Value xmin, Value xmax, Value ymin, Value ymax)
|
||||
{
|
||||
if (xmax < xmin || ymax < ymin)
|
||||
{
|
||||
SqThrow("max value is lower than min value");
|
||||
}
|
||||
else
|
||||
{
|
||||
x = GetRandomInt32(ymin, ymax);
|
||||
y = GetRandomInt32(xmin, xmax);
|
||||
}
|
||||
SqThrowF("max value is lower than min value");
|
||||
|
||||
x = GetRandomInt32(ymin, ymax);
|
||||
y = GetRandomInt32(xmin, xmax);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -509,6 +488,7 @@ void Register_Vector2i(HSQUIRRELVM vm)
|
||||
.Prop(_SC("abs"), &Vector2i::Abs)
|
||||
/* Core Metamethods */
|
||||
.Func(_SC("_tostring"), &Vector2i::ToString)
|
||||
.SquirrelFunc(_SC("_typename"), &Vector2i::Typename)
|
||||
.Func(_SC("_cmp"), &Vector2i::Cmp)
|
||||
/* Metamethods */
|
||||
.Func<Vector2i (Vector2i::*)(const Vector2i &) const>(_SC("_add"), &Vector2i::operator +)
|
||||
|
@ -8,394 +8,409 @@
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Class used to represent a two-dimensional vector using integral values.
|
||||
*/
|
||||
struct Vector2i
|
||||
{
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* The type of value used by components of type.
|
||||
*/
|
||||
typedef int Value;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Helper instances for common values mostly used as return types or comparison.
|
||||
*/
|
||||
static const Vector2i NIL;
|
||||
static const Vector2i MIN;
|
||||
static const Vector2i MAX;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* The delimiter character to be used when extracting values from strings.
|
||||
*/
|
||||
static SQChar Delim;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* The x and y components of this type.
|
||||
*/
|
||||
Value x, y;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Default constructor.
|
||||
*/
|
||||
Vector2i();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Construct a vector with the same scalar value for all components.
|
||||
*/
|
||||
Vector2i(Value sv);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Construct a vector with the specified component values.
|
||||
*/
|
||||
Vector2i(Value xv, Value yv);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Copy constructor.
|
||||
*/
|
||||
Vector2i(const Vector2i & o);
|
||||
Vector2i(const Vector2i & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Copy constructor.
|
||||
*/
|
||||
~Vector2i();
|
||||
Vector2i(Vector2i && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Destructor.
|
||||
*/
|
||||
Vector2i & operator = (const Vector2i & o);
|
||||
~Vector2i() = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
Vector2i & operator = (const Vector2i & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
Vector2i & operator = (Vector2i && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Scalar value assignment operator.
|
||||
*/
|
||||
Vector2i & operator = (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* String assignment operator.
|
||||
*/
|
||||
Vector2i & operator = (CSStr values);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Real two-dimensional vector assignment.
|
||||
*/
|
||||
Vector2i & operator = (const Vector2 & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Addition assignment operator.
|
||||
*/
|
||||
Vector2i & operator += (const Vector2i & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Subtraction assignment operator.
|
||||
*/
|
||||
Vector2i & operator -= (const Vector2i & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Multiplication assignment operator.
|
||||
*/
|
||||
Vector2i & operator *= (const Vector2i & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Division assignment operator.
|
||||
*/
|
||||
Vector2i & operator /= (const Vector2i & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Modulo assignment operator.
|
||||
*/
|
||||
Vector2i & operator %= (const Vector2i & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Bitwise AND assignment operator.
|
||||
*/
|
||||
Vector2i & operator &= (const Vector2i & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Bitwise OR assignment operator.
|
||||
*/
|
||||
Vector2i & operator |= (const Vector2i & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Bitwise XOR assignment operator.
|
||||
*/
|
||||
Vector2i & operator ^= (const Vector2i & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Bitwise left shift assignment operator.
|
||||
*/
|
||||
Vector2i & operator <<= (const Vector2i & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Bitwise right shift assignment operator.
|
||||
*/
|
||||
Vector2i & operator >>= (const Vector2i & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value addition assignment operator.
|
||||
*/
|
||||
Vector2i & operator += (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value subtraction assignment operator.
|
||||
*/
|
||||
Vector2i & operator -= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value multiplication assignment operator.
|
||||
*/
|
||||
Vector2i & operator *= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value division assignment operator.
|
||||
*/
|
||||
Vector2i & operator /= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value modulo assignment operator.
|
||||
*/
|
||||
Vector2i & operator %= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value bitwise AND assignment operator.
|
||||
*/
|
||||
Vector2i & operator &= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value bitwise OR assignment operator.
|
||||
*/
|
||||
Vector2i & operator |= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value bitwise XOR assignment operator.
|
||||
*/
|
||||
Vector2i & operator ^= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value bitwise left shift assignment operator.
|
||||
*/
|
||||
Vector2i & operator <<= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value bitwise right shift assignment operator.
|
||||
*/
|
||||
Vector2i & operator >>= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Pre-increment operator.
|
||||
*/
|
||||
Vector2i & operator ++ ();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Pre-decrement operator.
|
||||
*/
|
||||
Vector2i & operator -- ();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Post-increment operator.
|
||||
*/
|
||||
Vector2i operator ++ (int);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Post-decrement operator.
|
||||
*/
|
||||
Vector2i operator -- (int);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Addition operator.
|
||||
*/
|
||||
Vector2i operator + (const Vector2i & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Subtraction operator.
|
||||
*/
|
||||
Vector2i operator - (const Vector2i & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Multiplication operator.
|
||||
*/
|
||||
Vector2i operator * (const Vector2i & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Division operator.
|
||||
*/
|
||||
Vector2i operator / (const Vector2i & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Modulo operator.
|
||||
*/
|
||||
Vector2i operator % (const Vector2i & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Bitwise AND operator.
|
||||
*/
|
||||
Vector2i operator & (const Vector2i & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Bitwise OR operator.
|
||||
*/
|
||||
Vector2i operator | (const Vector2i & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Bitwise XOR operator.
|
||||
*/
|
||||
Vector2i operator ^ (const Vector2i & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Bitwise shift left operator.
|
||||
*/
|
||||
Vector2i operator << (const Vector2i & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Bitwise shift right operator.
|
||||
*/
|
||||
Vector2i operator >> (const Vector2i & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value addition operator.
|
||||
*/
|
||||
Vector2i operator + (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value subtraction operator.
|
||||
*/
|
||||
Vector2i operator - (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value multiplication operator.
|
||||
*/
|
||||
Vector2i operator * (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value division operator.
|
||||
*/
|
||||
Vector2i operator / (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value modulo operator.
|
||||
*/
|
||||
Vector2i operator % (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value bitwise AND operator.
|
||||
*/
|
||||
Vector2i operator & (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value bitwise OR operator.
|
||||
*/
|
||||
Vector2i operator | (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value bitwise XOR operator.
|
||||
*/
|
||||
Vector2i operator ^ (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value bitwise shift left operator.
|
||||
*/
|
||||
Vector2i operator << (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value bitwise shift right operator.
|
||||
*/
|
||||
Vector2i operator >> (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Unary plus operator.
|
||||
*/
|
||||
Vector2i operator + () const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Unary minus operator.
|
||||
*/
|
||||
Vector2i operator - () const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Bitwise NOT operator.
|
||||
*/
|
||||
Vector2i operator ~ () const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Equality comparison operator.
|
||||
*/
|
||||
bool operator == (const Vector2i & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Inequality comparison operator.
|
||||
*/
|
||||
bool operator != (const Vector2i & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Less than comparison operator.
|
||||
*/
|
||||
bool operator < (const Vector2i & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Greater than comparison operator.
|
||||
*/
|
||||
bool operator > (const Vector2i & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Less than or equal comparison operator.
|
||||
*/
|
||||
bool operator <= (const Vector2i & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Greater than or equal comparison operator.
|
||||
*/
|
||||
bool operator >= (const Vector2i & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Used by the script engine to compare two instances of this type.
|
||||
*/
|
||||
Int32 Cmp(const Vector2i & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Used by the script engine to retrieve the name from instances of this type.
|
||||
*/
|
||||
static SQInteger Typename(HSQUIRRELVM vm);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Set all components to the specified scalar value.
|
||||
*/
|
||||
void Set(Value ns);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set all components to the specified values.
|
||||
*/
|
||||
void Set(Value nx, Value ny);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Copy the values from another instance of this type.
|
||||
*/
|
||||
void Set(const Vector2i & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Copy the values from a real two-dimensional vector.
|
||||
*/
|
||||
void Set(const Vector2 & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set the values extracted from the specified string using the specified delimiter.
|
||||
*/
|
||||
void Set(CSStr values, SQChar delim);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Generate random values for all components of this instance.
|
||||
*/
|
||||
void Generate();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Generate random values for all components of this instance within the specified bounds.
|
||||
*/
|
||||
void Generate(Value min, Value max);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Generate random values for all components of this instance within the specified bounds.
|
||||
*/
|
||||
void Generate(Value xmin, Value xmax, Value ymin, Value ymax);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Clear the component values to default.
|
||||
*/
|
||||
void Clear()
|
||||
{
|
||||
@ -403,7 +418,7 @@ struct Vector2i
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Retrieve a new instance of this type with absolute component values.
|
||||
*/
|
||||
Vector2i Abs() const;
|
||||
};
|
||||
|
@ -16,6 +16,14 @@ const Vector3 Vector3::MAX = Vector3(NumLimit< Vector3::Value >::Max);
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQChar Vector3::Delim = ',';
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger Vector3::Typename(HSQUIRRELVM vm)
|
||||
{
|
||||
static SQChar name[] = _SC("Vector3");
|
||||
sq_pushstring(vm, name, sizeof(name));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Vector3::Vector3()
|
||||
: x(0.0), y(0.0), z(0.0)
|
||||
@ -37,28 +45,6 @@ Vector3::Vector3(Value xv, Value yv, Value zv)
|
||||
/* ... */
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Vector3::Vector3(const Vector3 & o)
|
||||
: x(o.x), y(o.y), z(o.z)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Vector3::~Vector3()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Vector3 & Vector3::operator = (const Vector3 & o)
|
||||
{
|
||||
x = o.x;
|
||||
y = o.y;
|
||||
z = o.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Vector3 & Vector3::operator = (Value s)
|
||||
{
|
||||
@ -310,7 +296,7 @@ Int32 Vector3::Cmp(const Vector3 & o) const
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr Vector3::ToString() const
|
||||
{
|
||||
return ToStringF("%f,%f,%f", x, y, z);
|
||||
return ToStrF("%f,%f,%f", x, y, z);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -367,29 +353,21 @@ void Vector3::Generate()
|
||||
void Vector3::Generate(Value min, Value max)
|
||||
{
|
||||
if (EpsLt(max, min))
|
||||
{
|
||||
SqThrow("max value is lower than min value");
|
||||
}
|
||||
else
|
||||
{
|
||||
x = GetRandomFloat32(min, max);
|
||||
y = GetRandomFloat32(min, max);
|
||||
z = GetRandomFloat32(min, max);
|
||||
}
|
||||
SqThrowF("max value is lower than min value");
|
||||
|
||||
x = GetRandomFloat32(min, max);
|
||||
y = GetRandomFloat32(min, max);
|
||||
z = GetRandomFloat32(min, max);
|
||||
}
|
||||
|
||||
void Vector3::Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value zmin, Value zmax)
|
||||
{
|
||||
if (EpsLt(xmax, xmin) || EpsLt(ymax, ymin) || EpsLt(zmax, zmin))
|
||||
{
|
||||
SqThrow("max value is lower than min value");
|
||||
}
|
||||
else
|
||||
{
|
||||
x = GetRandomFloat32(xmin, xmax);
|
||||
y = GetRandomFloat32(ymin, ymax);
|
||||
z = GetRandomFloat32(zmin, zmax);
|
||||
}
|
||||
SqThrowF("max value is lower than min value");
|
||||
|
||||
x = GetRandomFloat32(xmin, xmax);
|
||||
y = GetRandomFloat32(ymin, ymax);
|
||||
z = GetRandomFloat32(zmin, zmax);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -418,6 +396,7 @@ void Register_Vector3(HSQUIRRELVM vm)
|
||||
.Prop(_SC("abs"), &Vector3::Abs)
|
||||
/* Core Metamethods */
|
||||
.Func(_SC("_tostring"), &Vector3::ToString)
|
||||
.SquirrelFunc(_SC("_typename"), &Vector3::Typename)
|
||||
.Func(_SC("_cmp"), &Vector3::Cmp)
|
||||
/* Metamethods */
|
||||
.Func<Vector3 (Vector3::*)(const Vector3 &) const>(_SC("_add"), &Vector3::operator +)
|
||||
|
@ -8,294 +8,309 @@
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Class used to represent a three-dimensional vector.
|
||||
*/
|
||||
struct Vector3
|
||||
{
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* The type of value used by components of type.
|
||||
*/
|
||||
typedef float Value;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Helper instances for common values mostly used as return types or comparison.
|
||||
*/
|
||||
static const Vector3 NIL;
|
||||
static const Vector3 MIN;
|
||||
static const Vector3 MAX;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* The delimiter character to be used when extracting values from strings.
|
||||
*/
|
||||
static SQChar Delim;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* The x, y and z components of this type.
|
||||
*/
|
||||
Value x, y, z;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Default constructor.
|
||||
*/
|
||||
Vector3();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Construct a vector with the same scalar value for all components.
|
||||
*/
|
||||
Vector3(Value sv);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Construct a vector with the specified component values.
|
||||
*/
|
||||
Vector3(Value xv, Value yv, Value zv);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Copy constructor.
|
||||
*/
|
||||
Vector3(const Vector3 & o);
|
||||
Vector3(const Vector3 & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Copy constructor.
|
||||
*/
|
||||
~Vector3();
|
||||
Vector3(Vector3 && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Destructor.
|
||||
*/
|
||||
Vector3 & operator = (const Vector3 & o);
|
||||
~Vector3() = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
Vector3 & operator = (const Vector3 & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
Vector3 & operator = (Vector3 && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Scalar value assignment operator.
|
||||
*/
|
||||
Vector3 & operator = (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Four-dimensional vector assignment.
|
||||
*/
|
||||
Vector3 & operator = (const Vector4 & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Quaternion rotation assignment.
|
||||
*/
|
||||
Vector3 & operator = (const Quaternion & q);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Addition assignment operator.
|
||||
*/
|
||||
Vector3 & operator += (const Vector3 & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Subtraction assignment operator.
|
||||
*/
|
||||
Vector3 & operator -= (const Vector3 & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Multiplication assignment operator.
|
||||
*/
|
||||
Vector3 & operator *= (const Vector3 & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Division assignment operator.
|
||||
*/
|
||||
Vector3 & operator /= (const Vector3 & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Modulo assignment operator.
|
||||
*/
|
||||
Vector3 & operator %= (const Vector3 & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value addition assignment operator.
|
||||
*/
|
||||
Vector3 & operator += (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value subtraction assignment operator.
|
||||
*/
|
||||
Vector3 & operator -= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value multiplication assignment operator.
|
||||
*/
|
||||
Vector3 & operator *= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value division assignment operator.
|
||||
*/
|
||||
Vector3 & operator /= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value modulo assignment operator.
|
||||
*/
|
||||
Vector3 & operator %= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Pre-increment operator.
|
||||
*/
|
||||
Vector3 & operator ++ ();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Pre-decrement operator.
|
||||
*/
|
||||
Vector3 & operator -- ();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Post-increment operator.
|
||||
*/
|
||||
Vector3 operator ++ (int);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Post-decrement operator.
|
||||
*/
|
||||
Vector3 operator -- (int);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Addition operator.
|
||||
*/
|
||||
Vector3 operator + (const Vector3 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Subtraction operator.
|
||||
*/
|
||||
Vector3 operator - (const Vector3 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Multiplication operator.
|
||||
*/
|
||||
Vector3 operator * (const Vector3 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Division operator.
|
||||
*/
|
||||
Vector3 operator / (const Vector3 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Modulo operator.
|
||||
*/
|
||||
Vector3 operator % (const Vector3 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value addition operator.
|
||||
*/
|
||||
Vector3 operator + (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value subtraction operator.
|
||||
*/
|
||||
Vector3 operator - (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value multiplication operator.
|
||||
*/
|
||||
Vector3 operator * (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value division operator.
|
||||
*/
|
||||
Vector3 operator / (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value modulo operator.
|
||||
*/
|
||||
Vector3 operator % (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Unary plus operator.
|
||||
*/
|
||||
Vector3 operator + () const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Unary minus operator.
|
||||
*/
|
||||
Vector3 operator - () const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Equality comparison operator.
|
||||
*/
|
||||
bool operator == (const Vector3 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Inequality comparison operator.
|
||||
*/
|
||||
bool operator != (const Vector3 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Less than comparison operator.
|
||||
*/
|
||||
bool operator < (const Vector3 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Greater than comparison operator.
|
||||
*/
|
||||
bool operator > (const Vector3 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Less than or equal comparison operator.
|
||||
*/
|
||||
bool operator <= (const Vector3 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Greater than or equal comparison operator.
|
||||
*/
|
||||
bool operator >= (const Vector3 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Used by the script engine to compare two instances of this type.
|
||||
*/
|
||||
Int32 Cmp(const Vector3 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Used by the script engine to retrieve the name from instances of this type.
|
||||
*/
|
||||
static SQInteger Typename(HSQUIRRELVM vm);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Set all components to the specified scalar value.
|
||||
*/
|
||||
void Set(Value ns);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set all components to the specified values.
|
||||
*/
|
||||
void Set(Value nx, Value ny, Value nz);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Copy the values from another instance of this type.
|
||||
*/
|
||||
void Set(const Vector3 & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Copy the values from a four-dimensional vector.
|
||||
*/
|
||||
void Set(const Vector4 & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Copy the values from a quaternion rotation.
|
||||
*/
|
||||
void Set(const Quaternion & q);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set the values extracted from the specified string using the specified delimiter.
|
||||
*/
|
||||
void Set(CSStr values, SQChar delim);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Generate random values for all components of this instance.
|
||||
*/
|
||||
void Generate();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Generate random values for all components of this instance within the specified bounds.
|
||||
*/
|
||||
void Generate(Value min, Value max);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Generate random values for all components of this instance within the specified bounds.
|
||||
*/
|
||||
void Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value zmin, Value zmax);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Clear the component values to default.
|
||||
*/
|
||||
void Clear()
|
||||
{
|
||||
@ -303,7 +318,7 @@ struct Vector3
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Retrieve a new instance of this type with absolute component values.
|
||||
*/
|
||||
Vector3 Abs() const;
|
||||
};
|
||||
|
@ -16,6 +16,14 @@ const Vector4 Vector4::MAX = Vector4(NumLimit< Vector4::Value >::Max);
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQChar Vector4::Delim = ',';
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQInteger Vector4::Typename(HSQUIRRELVM vm)
|
||||
{
|
||||
static SQChar name[] = _SC("Vector4");
|
||||
sq_pushstring(vm, name, sizeof(name));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Vector4::Vector4()
|
||||
: x(0.0), y(0.0), z(0.0), w(0.0)
|
||||
@ -44,29 +52,6 @@ Vector4::Vector4(Value xv, Value yv, Value zv, Value wv)
|
||||
/* ... */
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Vector4::Vector4(const Vector4 & o)
|
||||
: x(o.x), y(o.y), z(o.z), w(o.w)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Vector4::~Vector4()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Vector4 & Vector4::operator = (const Vector4 & o)
|
||||
{
|
||||
x = o.x;
|
||||
y = o.y;
|
||||
z = o.z;
|
||||
w = o.w;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Vector4 & Vector4::operator = (Value s)
|
||||
{
|
||||
@ -335,7 +320,7 @@ Int32 Vector4::Cmp(const Vector4 & o) const
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr Vector4::ToString() const
|
||||
{
|
||||
return ToStringF("%f,%f,%f,%f", x, y, z, w);
|
||||
return ToStrF("%f,%f,%f,%f", x, y, z, w);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -405,31 +390,23 @@ void Vector4::Generate()
|
||||
void Vector4::Generate(Value min, Value max)
|
||||
{
|
||||
if (max < min)
|
||||
{
|
||||
SqThrow("max value is lower than min value");
|
||||
}
|
||||
else
|
||||
{
|
||||
x = GetRandomFloat32(min, max);
|
||||
y = GetRandomFloat32(min, max);
|
||||
z = GetRandomFloat32(min, max);
|
||||
y = GetRandomFloat32(min, max);
|
||||
}
|
||||
SqThrowF("max value is lower than min value");
|
||||
|
||||
x = GetRandomFloat32(min, max);
|
||||
y = GetRandomFloat32(min, max);
|
||||
z = GetRandomFloat32(min, max);
|
||||
y = GetRandomFloat32(min, max);
|
||||
}
|
||||
|
||||
void Vector4::Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value zmin, Value zmax, Value wmin, Value wmax)
|
||||
{
|
||||
if (EpsLt(xmax, xmin) || EpsLt(ymax, ymin) || EpsLt(zmax, zmin) || EpsLt(wmax, wmin))
|
||||
{
|
||||
SqThrow("max value is lower than min value");
|
||||
}
|
||||
else
|
||||
{
|
||||
x = GetRandomFloat32(xmin, xmax);
|
||||
y = GetRandomFloat32(ymin, ymax);
|
||||
z = GetRandomFloat32(zmin, zmax);
|
||||
y = GetRandomFloat32(ymin, ymax);
|
||||
}
|
||||
SqThrowF("max value is lower than min value");
|
||||
|
||||
x = GetRandomFloat32(xmin, xmax);
|
||||
y = GetRandomFloat32(ymin, ymax);
|
||||
z = GetRandomFloat32(zmin, zmax);
|
||||
y = GetRandomFloat32(ymin, ymax);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@ -460,6 +437,7 @@ void Register_Vector4(HSQUIRRELVM vm)
|
||||
.Prop(_SC("abs"), &Vector4::Abs)
|
||||
/* Core Metamethods */
|
||||
.Func(_SC("_tostring"), &Vector4::ToString)
|
||||
.SquirrelFunc(_SC("_typename"), &Vector4::Typename)
|
||||
.Func(_SC("_cmp"), &Vector4::Cmp)
|
||||
/* Metamethods */
|
||||
.Func<Vector4 (Vector4::*)(const Vector4 &) const>(_SC("_add"), &Vector4::operator +)
|
||||
|
@ -8,304 +8,319 @@
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Class used to represent a four-dimensional vector.
|
||||
*/
|
||||
struct Vector4
|
||||
{
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* The type of value used by components of type.
|
||||
*/
|
||||
typedef float Value;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Helper instances for common values mostly used as return types or comparison.
|
||||
*/
|
||||
static const Vector4 NIL;
|
||||
static const Vector4 MIN;
|
||||
static const Vector4 MAX;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* The delimiter character to be used when extracting values from strings.
|
||||
*/
|
||||
static SQChar Delim;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* The x, y, z and w components of this type.
|
||||
*/
|
||||
Value x, y, z, w;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Default constructor.
|
||||
*/
|
||||
Vector4();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Construct a vector with the same scalar value for all components.
|
||||
*/
|
||||
Vector4(Value sv);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Construct a vector with the specified component values.
|
||||
*/
|
||||
Vector4(Value xv, Value yv, Value zv);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Construct a vector with the specified component values.
|
||||
*/
|
||||
Vector4(Value xv, Value yv, Value zv, Value wv);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Copy constructor.
|
||||
*/
|
||||
Vector4(const Vector4 & o);
|
||||
Vector4(const Vector4 & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Move constructor.
|
||||
*/
|
||||
~Vector4();
|
||||
Vector4(Vector4 && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* Destructor.
|
||||
*/
|
||||
Vector4 & operator = (const Vector4 & o);
|
||||
~Vector4() = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Copy assignment operator.
|
||||
*/
|
||||
Vector4 & operator = (const Vector4 & o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator.
|
||||
*/
|
||||
Vector4 & operator = (Vector4 && o) = default;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Scalar value assignment operator.
|
||||
*/
|
||||
Vector4 & operator = (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Three-dimensional vector assignment operator.
|
||||
*/
|
||||
Vector4 & operator = (const Vector3 & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Quaternion rotation assignment operator.
|
||||
*/
|
||||
Vector4 & operator = (const Quaternion & q);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Addition assignment operator.
|
||||
*/
|
||||
Vector4 & operator += (const Vector4 & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Subtraction assignment operator.
|
||||
*/
|
||||
Vector4 & operator -= (const Vector4 & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Multiplication assignment operator.
|
||||
*/
|
||||
Vector4 & operator *= (const Vector4 & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Division assignment operator.
|
||||
*/
|
||||
Vector4 & operator /= (const Vector4 & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Modulo assignment operator.
|
||||
*/
|
||||
Vector4 & operator %= (const Vector4 & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value addition assignment operator.
|
||||
*/
|
||||
Vector4 & operator += (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value subtraction assignment operator.
|
||||
*/
|
||||
Vector4 & operator -= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value multiplication assignment operator.
|
||||
*/
|
||||
Vector4 & operator *= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value division assignment operator.
|
||||
*/
|
||||
Vector4 & operator /= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value modulo assignment operator.
|
||||
*/
|
||||
Vector4 & operator %= (Value s);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Pre-increment operator.
|
||||
*/
|
||||
Vector4 & operator ++ ();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Pre-decrement operator.
|
||||
*/
|
||||
Vector4 & operator -- ();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Post-increment operator.
|
||||
*/
|
||||
Vector4 operator ++ (int);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Post-decrement operator.
|
||||
*/
|
||||
Vector4 operator -- (int);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Addition operator.
|
||||
*/
|
||||
Vector4 operator + (const Vector4 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Subtraction operator.
|
||||
*/
|
||||
Vector4 operator - (const Vector4 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Multiplication operator.
|
||||
*/
|
||||
Vector4 operator * (const Vector4 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Division operator.
|
||||
*/
|
||||
Vector4 operator / (const Vector4 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Modulo operator.
|
||||
*/
|
||||
Vector4 operator % (const Vector4 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value addition operator.
|
||||
*/
|
||||
Vector4 operator + (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value subtraction operator.
|
||||
*/
|
||||
Vector4 operator - (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value multiplication operator.
|
||||
*/
|
||||
Vector4 operator * (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value division operator.
|
||||
*/
|
||||
Vector4 operator / (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Scalar value modulo operator.
|
||||
*/
|
||||
Vector4 operator % (Value s) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Unary plus operator.
|
||||
*/
|
||||
Vector4 operator + () const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Unary minus operator.
|
||||
*/
|
||||
Vector4 operator - () const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Equality comparison operator.
|
||||
*/
|
||||
bool operator == (const Vector4 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Inequality comparison operator.
|
||||
*/
|
||||
bool operator != (const Vector4 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Less than comparison operator.
|
||||
*/
|
||||
bool operator < (const Vector4 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Greater than comparison operator.
|
||||
*/
|
||||
bool operator > (const Vector4 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Less than or equal comparison operator.
|
||||
*/
|
||||
bool operator <= (const Vector4 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Greater than or equal comparison operator.
|
||||
*/
|
||||
bool operator >= (const Vector4 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Used by the script engine to compare two instances of this type.
|
||||
*/
|
||||
Int32 Cmp(const Vector4 & v) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Used by the script engine to retrieve the name from instances of this type.
|
||||
*/
|
||||
static SQInteger Typename(HSQUIRRELVM vm);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Set all components to the specified scalar value.
|
||||
*/
|
||||
void Set(Value ns);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set all components to the specified values.
|
||||
*/
|
||||
void Set(Value nx, Value ny, Value nz);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set all components to the specified values.
|
||||
*/
|
||||
void Set(Value nx, Value ny, Value nz, Value nw);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Copy the values from another instance of this type.
|
||||
*/
|
||||
void Set(const Vector4 & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Copy the values from a three-dimensional vector.
|
||||
*/
|
||||
void Set(const Vector3 & v);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Copy the values from a quaternion rotation.
|
||||
*/
|
||||
void Set(const Quaternion & q);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Set the values extracted from the specified string using the specified delimiter.
|
||||
*/
|
||||
void Set(CSStr values, SQChar delim);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Generate random values for all components of this instance.
|
||||
*/
|
||||
void Generate();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Generate random values for all components of this instance within the specified bounds.
|
||||
*/
|
||||
void Generate(Value min, Value max);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Generate random values for all components of this instance within the specified bounds.
|
||||
*/
|
||||
void Generate(Value xmin, Value xmax, Value ymin, Value ymax, Value zmin, Value zmax, Value wmin, Value wmax);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Clear the component values to default.
|
||||
*/
|
||||
void Clear()
|
||||
{
|
||||
@ -313,7 +328,7 @@ struct Vector4
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* ...
|
||||
* Retrieve a new instance of this type with absolute component values.
|
||||
*/
|
||||
Vector4 Abs() const;
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -165,10 +165,19 @@ protected:
|
||||
*/
|
||||
template < typename T > void SqError(Int32 type, CSStr msg, T data)
|
||||
{
|
||||
if (!m_OnError.IsNull())
|
||||
// Is there a callback that deals with errors?
|
||||
if (m_OnError.IsNull())
|
||||
return;
|
||||
// Attempt to forward the error to that callback
|
||||
try
|
||||
{
|
||||
m_OnError.Execute< Int32, CSStr, T >(type, msg, data);
|
||||
}
|
||||
catch (const Sqrat::Exception & e)
|
||||
{
|
||||
// We can only log this incident and in the future maybe also include the location
|
||||
LogErr("Command error callback failed [%s]", e.Message().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
@ -350,7 +359,7 @@ protected:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
*/
|
||||
bool ProcSpec(CSStr spec);
|
||||
void ProcSpec(CSStr spec);
|
||||
|
||||
private:
|
||||
|
||||
|
215
source/Core.cpp
215
source/Core.cpp
@ -48,13 +48,6 @@ extern void TerminateCommand();
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Core * _Core = NULL;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static void CalculateStringIDs(SQChar arr[][8], Uint32 num)
|
||||
{
|
||||
for (Uint32 n = 0; n < num; n++)
|
||||
snprintf(arr[n], 8, "%d", n);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Core::Core()
|
||||
: m_State(0)
|
||||
@ -100,19 +93,6 @@ bool Core::Init()
|
||||
m_Textdraws.resize(SQMOD_TEXTDRAW_POOL);
|
||||
m_Vehicles.resize(SQMOD_VEHICLE_POOL);
|
||||
|
||||
LogDbg("Pre-calculating entity string identifiers");
|
||||
// Pre-calculate all possible entity IDs for fast string conversion
|
||||
CalculateStringIDs(CBlip::s_StrID, SQMOD_BLIP_POOL);
|
||||
CalculateStringIDs(CCheckpoint::s_StrID, SQMOD_CHECKPOINT_POOL);
|
||||
CalculateStringIDs(CForcefield::s_StrID, SQMOD_FORCEFIELD_POOL);
|
||||
CalculateStringIDs(CKeybind::s_StrID, SQMOD_KEYBIND_POOL);
|
||||
CalculateStringIDs(CObject::s_StrID, SQMOD_OBJECT_POOL);
|
||||
CalculateStringIDs(CPickup::s_StrID, SQMOD_PICKUP_POOL);
|
||||
CalculateStringIDs(CPlayer::s_StrID, SQMOD_PLAYER_POOL);
|
||||
CalculateStringIDs(CSprite::s_StrID, SQMOD_SPRITE_POOL);
|
||||
CalculateStringIDs(CTextdraw::s_StrID, SQMOD_TEXTDRAW_POOL);
|
||||
CalculateStringIDs(CVehicle::s_StrID, SQMOD_VEHICLE_POOL);
|
||||
|
||||
LogDbg("Initializing entity options to defaults");
|
||||
// Initialize player messaging options to default values
|
||||
for (Players::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
|
||||
@ -154,148 +134,130 @@ bool Core::Init()
|
||||
// Attempt to read the database port number
|
||||
try
|
||||
{
|
||||
Ulong num = strtoul(conf.GetValue("Config", "StackSize", "0"), NULL, 10);
|
||||
// Make sure that the retrieved number is in range
|
||||
Ulong num = conf.GetLongValue("Config", "StackSize", SQMOD_STACK_SIZE);
|
||||
// Make sure that the retrieved number is within range
|
||||
if (!num)
|
||||
{
|
||||
throw std::out_of_range("stack size too small");
|
||||
}
|
||||
else if (num >= NumLimit< Uint16 >::Max)
|
||||
{
|
||||
else if (num >= std::numeric_limits< Uint16 >::max())
|
||||
throw std::out_of_range("stack size too big");
|
||||
}
|
||||
// Save the port number
|
||||
stack_size = (Uint16)num;
|
||||
stack_size = static_cast< Uint16 >(num);
|
||||
}
|
||||
catch (const std::exception & e)
|
||||
{
|
||||
LogWrn("Unable to obtain the stack size [%s]", e.what());
|
||||
LogWrn("Unable to obtain a valid stack size [%s]", e.what());
|
||||
}
|
||||
|
||||
LogDbg("Creating virtual machine with a stack size (%d)", stack_size);
|
||||
LogDbg("Creating a virtual machine with a stack size of (%d)", stack_size);
|
||||
// Attempt to create the VM
|
||||
m_VM = sq_open(stack_size);
|
||||
|
||||
// See if the virtual machine could be created
|
||||
if (cLogFtl(!m_VM, "Unable to create the virtual machine"))
|
||||
{
|
||||
m_VM = NULL;
|
||||
// Explicitly prevent further use of this pointer
|
||||
m_VM = nullptr;
|
||||
// Unable to load the plugin properly
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set this as the default VM and enable error handling
|
||||
// Set this as the default VM
|
||||
DefaultVM::Set(m_VM);
|
||||
// Enable error handling
|
||||
ErrorHandling::Enable(true);
|
||||
|
||||
LogDbg("Registering the standard libraries");
|
||||
// Register the standard library on the root table
|
||||
// Push the root table on the stack
|
||||
sq_pushroottable(m_VM);
|
||||
// Register the standard library on the pushed table
|
||||
sqstd_register_iolib(m_VM);
|
||||
sqstd_register_bloblib(m_VM);
|
||||
sqstd_register_mathlib(m_VM);
|
||||
sqstd_register_systemlib(m_VM);
|
||||
sqstd_register_stringlib(m_VM);
|
||||
// Pop the root table from the stack
|
||||
sq_pop(m_VM, 1);
|
||||
|
||||
LogDbg("Setting the base output function");
|
||||
// Tell the VM to use these functions to output user on error messages
|
||||
sq_setprintfunc(m_VM, PrintFunc, ErrorFunc);
|
||||
|
||||
LogDbg("Setting the base error handlers");
|
||||
// Tell the VM to trigger this function on compile time errors
|
||||
sq_setcompilererrorhandler(m_VM, CompilerErrorHandler);
|
||||
// Push the runtime error handler on the stack and create a closure
|
||||
sq_newclosure(m_VM, RuntimeErrorHandler, 0);
|
||||
// Tell the VM to trigger this function on runtime errors
|
||||
sq_seterrorhandler(m_VM);
|
||||
|
||||
LogDbg("Registering the plug-in API");
|
||||
// Attempt to register the plugin API
|
||||
if (cLogFtl(!RegisterAPI(m_VM), "Unable to register the plug-in API"))
|
||||
return false;
|
||||
return false; // Can't execute scripts without a valid API!
|
||||
|
||||
// Attempt to retrieve the list of strings specified in the config
|
||||
CSimpleIniA::TNamesDepend scripts;
|
||||
conf.GetAllValues("Scripts", "Source", scripts);
|
||||
// See if any script was specified
|
||||
if (scripts.size() <= 0)
|
||||
if (scripts.size() <= 0 && !conf.GetBoolValue("Config", "EmptyInit", false))
|
||||
{
|
||||
LogWrn("No scripts specified in the configuration file");
|
||||
// No point in loading the plug-in
|
||||
return false;
|
||||
}
|
||||
// Sort the list in it's original order
|
||||
scripts.sort(CSimpleIniA::Entry::LoadOrder());
|
||||
// Process each specified script path
|
||||
for (CSimpleIniA::TNamesDepend::iterator itr = scripts.begin(); itr != scripts.end(); ++itr)
|
||||
else
|
||||
{
|
||||
// Get the file path as a string
|
||||
String path(itr->pItem);
|
||||
// See if the specified script path is valid
|
||||
if (path.empty())
|
||||
{
|
||||
// Simply ignore it
|
||||
continue;
|
||||
}
|
||||
// See if it wasn't already loaded
|
||||
else if (m_Scripts.find(path) != m_Scripts.end())
|
||||
{
|
||||
LogWrn("Script was specified before: %s", path.c_str());
|
||||
// No point in loading it again
|
||||
continue;
|
||||
}
|
||||
// Create a new script container and insert it into the script pool
|
||||
std::pair< Scripts::iterator, bool > res = m_Scripts.insert(Scripts::value_type(path, Script(m_VM)));
|
||||
// We don't compile the scripts yet. We just store their path and prepare the objects.
|
||||
if (!res.second)
|
||||
{
|
||||
LogErr("Unable to queue script: %s", path.c_str());
|
||||
// Drop all previous scripts
|
||||
m_Scripts.clear();
|
||||
// Failed to compile the specified script
|
||||
return false;
|
||||
}
|
||||
// Sort the list in it's original order
|
||||
scripts.sort(CSimpleIniA::Entry::LoadOrder());
|
||||
// Process each specified script paths
|
||||
for (const auto & script : scripts)
|
||||
// Attempt to queue the specified script path for loading
|
||||
LoadScript(script.pItem);
|
||||
}
|
||||
// See if any script could be compiled
|
||||
// See if any script could be queued for loading
|
||||
if (m_Scripts.empty() && !conf.GetBoolValue("Config", "EmptyInit", false))
|
||||
{
|
||||
LogErr("No scripts compiled. No reason to load the plug-in");
|
||||
LogErr("No scripts loaded. No reason to load the plug-in");
|
||||
// No point in loading the plug-in
|
||||
return false;
|
||||
}
|
||||
|
||||
LogDbg("Reading the options from the general section");
|
||||
// Read options only after compilation was successful
|
||||
// Read options only after loading was successful
|
||||
CSimpleIniA::TNamesDepend options;
|
||||
// Are there any options to load?
|
||||
// Are there any options to read?
|
||||
if (conf.GetAllKeys("Options", options) || options.size() > 0)
|
||||
{
|
||||
// Process all the specified keys under the [Options] section
|
||||
for (CSimpleIniA::TNamesDepend::iterator itr = options.begin(); itr != options.end(); ++itr)
|
||||
for (const auto & option : options)
|
||||
{
|
||||
CSimpleIniA::TNamesDepend optlist;
|
||||
// Get all keys with the same name
|
||||
if (!conf.GetAllValues("Options", itr->pItem, optlist))
|
||||
{
|
||||
CSimpleIniA::TNamesDepend values;
|
||||
// Get the values of all keys with the same name
|
||||
if (!conf.GetAllValues("Options", option.pItem, values))
|
||||
continue;
|
||||
}
|
||||
// Sort the keys in their original order
|
||||
optlist.sort(CSimpleIniA::Entry::LoadOrder());
|
||||
// Process each option and overwrite existing values
|
||||
for (CSimpleIniA::TNamesDepend::iterator opt = optlist.begin(); opt != optlist.end(); ++opt)
|
||||
{
|
||||
m_Options[itr->pItem] = opt->pItem;
|
||||
}
|
||||
values.sort(CSimpleIniA::Entry::LoadOrder());
|
||||
// Save each option option and overwrite existing value
|
||||
for (const auto & value : values)
|
||||
m_Options[option.pItem] = value.pItem;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogInf("No options specified in the configuration file");
|
||||
}
|
||||
|
||||
LogDbg("Applying the specified logging filters");
|
||||
// Apply the specified logging filters only after initialization was completed
|
||||
if (!SToB(conf.GetValue("Log", "Debug", "true"))) _Log->DisableLevel(LL_DBG);
|
||||
if (!SToB(conf.GetValue("Log", "User", "true"))) _Log->DisableLevel(LL_USR);
|
||||
if (!SToB(conf.GetValue("Log", "Success", "true"))) _Log->DisableLevel(LL_SCS);
|
||||
if (!SToB(conf.GetValue("Log", "Info", "true"))) _Log->DisableLevel(LL_INF);
|
||||
if (!SToB(conf.GetValue("Log", "Warning", "true"))) _Log->DisableLevel(LL_WRN);
|
||||
if (!SToB(conf.GetValue("Log", "Error", "true"))) _Log->DisableLevel(LL_ERR);
|
||||
if (!SToB(conf.GetValue("Log", "Fatal", "true"))) _Log->DisableLevel(LL_FTL);
|
||||
if (!conf.GetBoolValue("Log", "Debug", true))
|
||||
_Log->DisableLevel(LL_DBG);
|
||||
if (!conf.GetBoolValue("Log", "User", true))
|
||||
_Log->DisableLevel(LL_USR);
|
||||
if (!conf.GetBoolValue("Log", "Success", true))
|
||||
_Log->DisableLevel(LL_SCS);
|
||||
if (!conf.GetBoolValue("Log", "Info", true))
|
||||
_Log->DisableLevel(LL_INF);
|
||||
if (!conf.GetBoolValue("Log", "Warning", true))
|
||||
_Log->DisableLevel(LL_WRN);
|
||||
if (!conf.GetBoolValue("Log", "Error", true))
|
||||
_Log->DisableLevel(LL_ERR);
|
||||
if (!conf.GetBoolValue("Log", "Fatal", true))
|
||||
_Log->DisableLevel(LL_FTL);
|
||||
|
||||
// Initialization successful
|
||||
return true;
|
||||
@ -306,7 +268,8 @@ bool Core::Load()
|
||||
{
|
||||
// Are there any scripts to execute?
|
||||
if (cLogErr(m_Scripts.empty(), "No scripts to execute. Plug-in has no purpose"))
|
||||
return false;
|
||||
return false; // No reason to load the plug-in
|
||||
|
||||
LogDbg("Signaling outside plugins to register their API");
|
||||
// Signal outside plugins to do their monkey business
|
||||
_Func->SendCustomCommand(0xDEADBABE, "");
|
||||
@ -316,18 +279,29 @@ bool Core::Load()
|
||||
for (Scripts::iterator itr = m_Scripts.begin(); itr != m_Scripts.end(); ++itr)
|
||||
{
|
||||
// Attempt to load and compile the script file
|
||||
itr->second.CompileFile(itr->first);
|
||||
// See if any compile time error occurred during compilation
|
||||
if (Error::Occurred(m_VM))
|
||||
return false; /* Failed to load properly */
|
||||
// Attempt to execute the script
|
||||
itr->second.Run();
|
||||
// See if the executed script had any errors
|
||||
if (Error::Occurred(m_VM))
|
||||
// Failed to execute scripts
|
||||
return false; /* Failed to load properly */
|
||||
else
|
||||
LogScs("Successfully executed script: %s", itr->first.c_str());
|
||||
try
|
||||
{
|
||||
itr->second.CompileFile(itr->first);
|
||||
}
|
||||
catch (const Sqrat::Exception & e)
|
||||
{
|
||||
LogFtl("Unable to compile: %s", itr->first.c_str());
|
||||
// Failed to load properly
|
||||
return false;
|
||||
}
|
||||
// Attempt to execute the compiled script code
|
||||
try
|
||||
{
|
||||
itr->second.Run();
|
||||
}
|
||||
catch (const Sqrat::Exception & e)
|
||||
{
|
||||
LogFtl("Unable to execute: %s", itr->first.c_str());
|
||||
// Failed to load properly
|
||||
return false;
|
||||
}
|
||||
// At this point the script should be completely loaded
|
||||
LogScs("Successfully executed script: %s", itr->first.c_str());
|
||||
}
|
||||
// Successfully loaded
|
||||
return true;
|
||||
@ -382,6 +356,25 @@ void Core::SetOption(const String & name, const String & value)
|
||||
m_Options[name] = value;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool Core::LoadScript(CSStr filepath)
|
||||
{
|
||||
// Is the specified path empty?
|
||||
if (!filepath || *filepath == 0)
|
||||
return false; // Simply ignore it
|
||||
// Get the file path as a string
|
||||
String path(filepath);
|
||||
// See if it wasn't already loaded
|
||||
if (m_Scripts.find(path) != m_Scripts.end())
|
||||
LogWrn("Script was specified before: %s", path.c_str());
|
||||
// We don't compile the scripts yet. We just store their path and prepare the objects.
|
||||
else
|
||||
// Create a new script container and insert it into the script pool
|
||||
m_Scripts.emplace(std::move(path), Script(m_VM));
|
||||
// At this point the script exists in the pool
|
||||
return true;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Core::PrintFunc(HSQUIRRELVM vm, CSStr msg, ...)
|
||||
{
|
||||
@ -1720,8 +1713,8 @@ void Core::ResetInst(BlipInst & inst)
|
||||
inst.mWorld = -1;
|
||||
inst.mScale = -1;
|
||||
inst.mSprID = -1;
|
||||
//inst.mPosition.Clear();
|
||||
//inst.mColor.Clear();
|
||||
inst.mPosition.Clear();
|
||||
inst.mColor.Clear();
|
||||
}
|
||||
|
||||
void Core::ResetInst(CheckpointInst & inst)
|
||||
@ -1740,9 +1733,9 @@ void Core::ResetInst(KeybindInst & inst)
|
||||
{
|
||||
inst.mID = -1;
|
||||
inst.mFlags = ENF_DEFAULT;
|
||||
inst.mPrimary = -1;
|
||||
inst.mSecondary = -1;
|
||||
inst.mAlternative = -1;
|
||||
inst.mFirst = -1;
|
||||
inst.mSecond = -1;
|
||||
inst.mThird = -1;
|
||||
inst.mRelease = -1;
|
||||
}
|
||||
|
||||
|
@ -155,9 +155,9 @@ protected:
|
||||
Object mObj;
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
Int32 mPrimary;
|
||||
Int32 mSecondary;
|
||||
Int32 mAlternative;
|
||||
Int32 mFirst;
|
||||
Int32 mSecond;
|
||||
Int32 mThird;
|
||||
Int32 mRelease;
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
@ -392,6 +392,8 @@ protected:
|
||||
Function mOnDisembark;
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
typedef std::vector< BlipInst > Blips;
|
||||
typedef std::vector< CheckpointInst > Checkpoints;
|
||||
@ -483,8 +485,15 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* State mutators.
|
||||
*/
|
||||
void SetState(Int32 val) { m_State = val; }
|
||||
Int32 GetState() const { return m_State; }
|
||||
void SetState(Int32 val)
|
||||
{
|
||||
m_State = val;
|
||||
}
|
||||
|
||||
Int32 GetState() const
|
||||
{
|
||||
return m_State;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Option mutators.
|
||||
@ -495,7 +504,15 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the virtual machine.
|
||||
*/
|
||||
HSQUIRRELVM GetVM() const { return m_VM; }
|
||||
HSQUIRRELVM GetVM() const
|
||||
{
|
||||
return m_VM;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Adds a script to the load queue.
|
||||
*/
|
||||
bool LoadScript(CSStr filepath);
|
||||
|
||||
protected:
|
||||
|
||||
@ -578,6 +595,20 @@ public:
|
||||
TextdrawInst & GetTextdraw(Int32 id) { return m_Textdraws.at(id); }
|
||||
VehicleInst & GetVehicle(Int32 id) { return m_Vehicles.at(id); }
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Pool retrievers.
|
||||
*/
|
||||
const Blips & GetBlips() const { return m_Blips; }
|
||||
const Checkpoints & GetCheckpoints() const { return m_Checkpoints; }
|
||||
const Forcefields & GetForcefields() const { return m_Forcefields; }
|
||||
const Keybinds & GetKeybinds() const { return m_Keybinds; }
|
||||
const Objects & GetObjects() const { return m_Objects; }
|
||||
const Pickups & GetPickups() const { return m_Pickups; }
|
||||
const Players & GetPlayers() const { return m_Players; }
|
||||
const Sprites & GetSprites() const { return m_Sprites; }
|
||||
const Textdraws & GetTextdraws() const { return m_Textdraws; }
|
||||
const Vehicles & GetVehicles() const { return m_Vehicles; }
|
||||
|
||||
protected:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
|
@ -6,15 +6,20 @@
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQChar CBlip::s_StrID[SQMOD_BLIP_POOL][8];
|
||||
const Int32 CBlip::Max = SQMOD_BLIP_POOL;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const Int32 CBlip::Max = SQMOD_BLIP_POOL;
|
||||
SQInteger CBlip::Typename(HSQUIRRELVM vm)
|
||||
{
|
||||
static SQChar name[] = _SC("SqBlip");
|
||||
sq_pushstring(vm, name, sizeof(name));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CBlip::CBlip(Int32 id)
|
||||
: m_ID(VALID_ENTITYGETEX(id, SQMOD_BLIP_POOL))
|
||||
, m_Tag(VALID_ENTITY(m_ID) ? s_StrID[m_ID] : _SC("-1"))
|
||||
, m_Tag(ToStrF("%d", id))
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
@ -36,153 +41,183 @@ Int32 CBlip::Cmp(const CBlip & o) const
|
||||
return -1;
|
||||
}
|
||||
|
||||
CSStr CBlip::ToString() const
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const String & CBlip::ToString() const
|
||||
{
|
||||
return VALID_ENTITYEX(m_ID, SQMOD_BLIP_POOL) ? s_StrID[m_ID] : _SC("-1");
|
||||
return m_Tag;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr CBlip::GetTag() const
|
||||
const String & CBlip::GetTag() const
|
||||
{
|
||||
return m_Tag.c_str();
|
||||
return m_Tag;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CBlip::SetTag(CSStr tag)
|
||||
{
|
||||
m_Tag.assign(tag);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Object & CBlip::GetData()
|
||||
{
|
||||
if (Validate())
|
||||
return m_Data;
|
||||
return NullObject();
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return m_Data;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CBlip::SetData(Object & data)
|
||||
{
|
||||
if (Validate())
|
||||
m_Data = data;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Apply the specified value
|
||||
m_Data = data;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool CBlip::Destroy(Int32 header, Object & payload)
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
return _Core->DelBlip(m_ID, header, payload);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool CBlip::BindEvent(Int32 evid, Object & env, Function & func) const
|
||||
void CBlip::BindEvent(Int32 evid, Object & env, Function & func) const
|
||||
{
|
||||
if (!Validate())
|
||||
return false;
|
||||
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Obtain the function instance called for this event
|
||||
Function & event = _Core->GetBlipEvent(m_ID, evid);
|
||||
|
||||
// Is the specified callback function null?
|
||||
if (func.IsNull())
|
||||
event.Release();
|
||||
event.Release(); // Then release the current callback
|
||||
// Assign the specified environment and function
|
||||
else
|
||||
event = Function(env.GetVM(), env, func.GetFunc());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 CBlip::GetWorld() const
|
||||
{
|
||||
if (Validate())
|
||||
return _Core->GetBlip(m_ID).mWorld;
|
||||
return -1;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Core->GetBlip(m_ID).mWorld;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 CBlip::GetScale() const
|
||||
{
|
||||
if (Validate())
|
||||
return _Core->GetBlip(m_ID).mScale;
|
||||
return -1;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Core->GetBlip(m_ID).mScale;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const Vector3 & CBlip::GetPosition() const
|
||||
{
|
||||
if (Validate())
|
||||
return _Core->GetBlip(m_ID).mPosition;
|
||||
return Vector3::NIL;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Core->GetBlip(m_ID).mPosition;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const Color4 & CBlip::GetColor() const
|
||||
{
|
||||
if (Validate())
|
||||
return _Core->GetBlip(m_ID).mColor;
|
||||
return Color4::NIL;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Core->GetBlip(m_ID).mColor;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 CBlip::GetSprID() const
|
||||
{
|
||||
if (Validate())
|
||||
return _Core->GetBlip(m_ID).mSprID;
|
||||
return -1;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Core->GetBlip(m_ID).mSprID;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Float32 CBlip::GetPosX() const
|
||||
{
|
||||
if (Validate())
|
||||
return _Core->GetBlip(m_ID).mPosition.x;
|
||||
return 0;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Core->GetBlip(m_ID).mPosition.x;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Float32 CBlip::GetPosY() const
|
||||
{
|
||||
if (Validate())
|
||||
return _Core->GetBlip(m_ID).mPosition.y;
|
||||
return 0;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Core->GetBlip(m_ID).mPosition.y;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Float32 CBlip::GetPosZ() const
|
||||
{
|
||||
if (Validate())
|
||||
return _Core->GetBlip(m_ID).mPosition.z;
|
||||
return 0;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Core->GetBlip(m_ID).mPosition.z;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 CBlip::GetColorR() const
|
||||
{
|
||||
if (Validate())
|
||||
return _Core->GetBlip(m_ID).mColor.r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Int32 CBlip::GetColorG() const
|
||||
{
|
||||
if (Validate())
|
||||
return _Core->GetBlip(m_ID).mColor.g;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Int32 CBlip::GetColorB() const
|
||||
{
|
||||
if (Validate())
|
||||
return _Core->GetBlip(m_ID).mColor.b;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Int32 CBlip::GetColorA() const
|
||||
{
|
||||
if (Validate())
|
||||
return _Core->GetBlip(m_ID).mColor.a;
|
||||
return 0;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Core->GetBlip(m_ID).mColor.r;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static Object & CreateBlipEx(Int32 world, Float32 x, Float32 y, Float32 z, Int32 scale,
|
||||
Int32 CBlip::GetColorG() const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Core->GetBlip(m_ID).mColor.g;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 CBlip::GetColorB() const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Core->GetBlip(m_ID).mColor.b;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 CBlip::GetColorA() const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Core->GetBlip(m_ID).mColor.a;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static Object & Blip_CreateEx(Int32 world, Float32 x, Float32 y, Float32 z, Int32 scale,
|
||||
Uint8 r, Uint8 g, Uint8 b, Uint8 a, Int32 sprid)
|
||||
{
|
||||
return _Core->NewBlip(-1, world, x, y, z, scale, SQMOD_PACK_RGBA(r, g, b, a), sprid,
|
||||
SQMOD_CREATE_DEFAULT, NullObject());
|
||||
}
|
||||
|
||||
static Object & CreateBlipEx(Int32 world, Float32 x, Float32 y, Float32 z, Int32 scale,
|
||||
static Object & Blip_CreateEx(Int32 world, Float32 x, Float32 y, Float32 z, Int32 scale,
|
||||
Uint8 r, Uint8 g, Uint8 b, Uint8 a, Int32 sprid,
|
||||
Int32 header, Object & payload)
|
||||
{
|
||||
@ -191,14 +226,14 @@ static Object & CreateBlipEx(Int32 world, Float32 x, Float32 y, Float32 z, Int32
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static Object & CreateBlipEx(Int32 index, Int32 world, Float32 x, Float32 y, Float32 z,
|
||||
static Object & Blip_CreateEx(Int32 index, Int32 world, Float32 x, Float32 y, Float32 z,
|
||||
Int32 scale, Uint8 r, Uint8 g, Uint8 b, Uint8 a, Int32 sprid)
|
||||
{
|
||||
return _Core->NewBlip(index, world, x, y, z, scale, SQMOD_PACK_RGBA(r, g, b, a), sprid,
|
||||
SQMOD_CREATE_DEFAULT, NullObject());
|
||||
}
|
||||
|
||||
static Object & CreateBlipEx(Int32 index, Int32 world, Float32 x, Float32 y, Float32 z, Int32 scale,
|
||||
static Object & Blip_CreateEx(Int32 index, Int32 world, Float32 x, Float32 y, Float32 z, Int32 scale,
|
||||
Uint8 r, Uint8 g, Uint8 b, Uint8 a, Int32 sprid,
|
||||
Int32 header, Object & payload)
|
||||
{
|
||||
@ -207,14 +242,14 @@ static Object & CreateBlipEx(Int32 index, Int32 world, Float32 x, Float32 y, Flo
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static Object & CreateBlip(Int32 world, const Vector3 & pos, Int32 scale, const Color4 & color,
|
||||
static Object & Blip_Create(Int32 world, const Vector3 & pos, Int32 scale, const Color4 & color,
|
||||
Int32 sprid)
|
||||
{
|
||||
return _Core->NewBlip(-1, world, pos.x, pos.y, pos.z, scale, color.GetRGBA(), sprid,
|
||||
SQMOD_CREATE_DEFAULT, NullObject());
|
||||
}
|
||||
|
||||
static Object & CreateBlip(Int32 world, const Vector3 & pos, Int32 scale, const Color4 & color,
|
||||
static Object & Blip_Create(Int32 world, const Vector3 & pos, Int32 scale, const Color4 & color,
|
||||
Int32 sprid, Int32 header, Object & payload)
|
||||
{
|
||||
return _Core->NewBlip(-1, world, pos.x, pos.y, pos.z, scale, color.GetRGBA(), sprid,
|
||||
@ -222,41 +257,82 @@ static Object & CreateBlip(Int32 world, const Vector3 & pos, Int32 scale, const
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static Object & CreateBlip(Int32 index, Int32 world, const Vector3 & pos, Int32 scale,
|
||||
static Object & Blip_Create(Int32 index, Int32 world, const Vector3 & pos, Int32 scale,
|
||||
const Color4 & color, Int32 sprid)
|
||||
{
|
||||
return _Core->NewBlip(index, world, pos.x, pos.y, pos.z, scale, color.GetRGBA(), sprid,
|
||||
SQMOD_CREATE_DEFAULT, NullObject());
|
||||
}
|
||||
|
||||
static Object & CreateBlip(Int32 index, Int32 world, const Vector3 & pos, Int32 scale,
|
||||
static Object & Blip_Create(Int32 index, Int32 world, const Vector3 & pos, Int32 scale,
|
||||
const Color4 & color, Int32 sprid, Int32 header, Object & payload)
|
||||
{
|
||||
return _Core->NewBlip(index, world, pos.x, pos.y, pos.z, scale, color.GetRGBA(), sprid,
|
||||
header, payload);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static const Object & Blip_FindByID(Int32 id)
|
||||
{
|
||||
// Perform a range check on the specified identifier
|
||||
if (INVALID_ENTITYEX(id, SQMOD_BLIP_POOL))
|
||||
SqThrowF("The specified blip identifier is invalid: %d", id);
|
||||
// Obtain the ends of the entity pool
|
||||
Core::Blips::const_iterator itr = _Core->GetBlips().cbegin();
|
||||
Core::Blips::const_iterator end = _Core->GetBlips().cend();
|
||||
// Process each entity in the pool
|
||||
for (; itr != end; ++itr)
|
||||
{
|
||||
// Does the identifier match the specified one?
|
||||
if (itr->mID == id)
|
||||
return itr->mObj; // Stop searching and return this entity
|
||||
}
|
||||
// Unable to locate a blip matching the specified identifier
|
||||
return NullObject();
|
||||
}
|
||||
|
||||
static const Object & Blip_FindByTag(CSStr tag)
|
||||
{
|
||||
// Perform a validity check on the specified tag
|
||||
if (!tag || *tag == 0)
|
||||
SqThrowF("The specified blip tag is invalid: null/empty");
|
||||
// Obtain the ends of the entity pool
|
||||
Core::Blips::const_iterator itr = _Core->GetBlips().cbegin();
|
||||
Core::Blips::const_iterator end = _Core->GetBlips().cend();
|
||||
// Process each entity in the pool
|
||||
for (; itr != end; ++itr)
|
||||
{
|
||||
// Does this entity even exist and does the tag match the specified one?
|
||||
if (itr->mInst != nullptr && itr->mInst->GetTag().compare(tag) == 0)
|
||||
return itr->mObj; // Stop searching and return this entity
|
||||
}
|
||||
// Unable to locate a blip matching the specified tag
|
||||
return NullObject();
|
||||
}
|
||||
|
||||
// ================================================================================================
|
||||
void Register_CBlip(HSQUIRRELVM vm)
|
||||
{
|
||||
RootTable(vm).Bind(_SC("SqBlip"),
|
||||
Class< CBlip, NoConstructor< CBlip > >(vm, _SC("SqBlip"))
|
||||
/* Metamethods */
|
||||
// Metamethods
|
||||
.Func(_SC("_cmp"), &CBlip::Cmp)
|
||||
.SquirrelFunc(_SC("_typename"), &CBlip::Typename)
|
||||
.Func(_SC("_tostring"), &CBlip::ToString)
|
||||
/* Core Properties */
|
||||
// Static values
|
||||
.SetStaticValue(_SC("MaxID"), CBlip::Max)
|
||||
// Core Properties
|
||||
.Prop(_SC("ID"), &CBlip::GetID)
|
||||
.Prop(_SC("Tag"), &CBlip::GetTag, &CBlip::SetTag)
|
||||
.Prop(_SC("Data"), &CBlip::GetData, &CBlip::SetData)
|
||||
.Prop(_SC("MaxID"), &CBlip::GetMaxID)
|
||||
.Prop(_SC("Active"), &CBlip::IsActive)
|
||||
/* Core Functions */
|
||||
// Core Functions
|
||||
.Func(_SC("Bind"), &CBlip::BindEvent)
|
||||
/* Core Overloads */
|
||||
// Core Overloads
|
||||
.Overload< bool (CBlip::*)(void) >(_SC("Destroy"), &CBlip::Destroy)
|
||||
.Overload< bool (CBlip::*)(Int32) >(_SC("Destroy"), &CBlip::Destroy)
|
||||
.Overload< bool (CBlip::*)(Int32, Object &) >(_SC("Destroy"), &CBlip::Destroy)
|
||||
/* Properties */
|
||||
// Properties
|
||||
.Prop(_SC("World"), &CBlip::GetWorld)
|
||||
.Prop(_SC("Scale"), &CBlip::GetScale)
|
||||
.Prop(_SC("Pos"), &CBlip::GetPosition)
|
||||
@ -270,25 +346,24 @@ void Register_CBlip(HSQUIRRELVM vm)
|
||||
.Prop(_SC("G"), &CBlip::GetColorG)
|
||||
.Prop(_SC("B"), &CBlip::GetColorB)
|
||||
.Prop(_SC("A"), &CBlip::GetColorA)
|
||||
// Static Overloads
|
||||
.StaticOverload< Object & (*)(Int32, Float32, Float32, Float32, Int32, Uint8, Uint8, Uint8, Uint8, Int32) >
|
||||
(_SC("CreateEx"), &Blip_CreateEx)
|
||||
.StaticOverload< Object & (*)(Int32, Float32, Float32, Float32, Int32, Uint8, Uint8, Uint8, Uint8, Int32, Int32, Object &) >
|
||||
(_SC("CreateEx"), &Blip_CreateEx)
|
||||
.StaticOverload< Object & (*)(Int32, Int32, Float32, Float32, Float32, Int32, Uint8, Uint8, Uint8, Uint8, Int32) >
|
||||
(_SC("CreateEx"), &Blip_CreateEx)
|
||||
.StaticOverload< Object & (*)(Int32, Int32, Float32, Float32, Float32, Int32, Uint8, Uint8, Uint8, Uint8, Int32, Int32, Object &) >
|
||||
(_SC("CreateEx"), &Blip_CreateEx)
|
||||
.StaticOverload< Object & (*)(Int32, const Vector3 &, Int32, const Color4 &, Int32) >
|
||||
(_SC("Create"), &Blip_Create)
|
||||
.StaticOverload< Object & (*)(Int32, const Vector3 &, Int32, const Color4 &, Int32, Int32, Object &) >
|
||||
(_SC("Create"), &Blip_Create)
|
||||
.StaticOverload< Object & (*)(Int32, Int32, const Vector3 &, Int32, const Color4 &, Int32) >
|
||||
(_SC("Create"), &Blip_Create)
|
||||
.StaticOverload< Object & (*)(Int32, Int32, const Vector3 &, Int32, const Color4 &, Int32, Int32, Object &) >
|
||||
(_SC("Create"), &Blip_Create)
|
||||
);
|
||||
|
||||
RootTable(vm)
|
||||
.Overload< Object & (*)(Int32, Float32, Float32, Float32, Int32, Uint8, Uint8, Uint8, Uint8, Int32) >
|
||||
(_SC("CreateBlipEx"), &CreateBlipEx)
|
||||
.Overload< Object & (*)(Int32, Float32, Float32, Float32, Int32, Uint8, Uint8, Uint8, Uint8, Int32, Int32, Object &) >
|
||||
(_SC("CreateBlipEx"), &CreateBlipEx)
|
||||
.Overload< Object & (*)(Int32, Int32, Float32, Float32, Float32, Int32, Uint8, Uint8, Uint8, Uint8, Int32) >
|
||||
(_SC("CreateBlipEx"), &CreateBlipEx)
|
||||
.Overload< Object & (*)(Int32, Int32, Float32, Float32, Float32, Int32, Uint8, Uint8, Uint8, Uint8, Int32, Int32, Object &) >
|
||||
(_SC("CreateBlipEx"), &CreateBlipEx)
|
||||
.Overload< Object & (*)(Int32, const Vector3 &, Int32, const Color4 &, Int32) >
|
||||
(_SC("CreateBlip"), &CreateBlip)
|
||||
.Overload< Object & (*)(Int32, const Vector3 &, Int32, const Color4 &, Int32, Int32, Object &) >
|
||||
(_SC("CreateBlip"), &CreateBlip)
|
||||
.Overload< Object & (*)(Int32, Int32, const Vector3 &, Int32, const Color4 &, Int32) >
|
||||
(_SC("CreateBlip"), &CreateBlip)
|
||||
.Overload< Object & (*)(Int32, Int32, const Vector3 &, Int32, const Color4 &, Int32, Int32, Object &) >
|
||||
(_SC("CreateBlip"), &CreateBlip);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
||||
} // Namespace:: SqMod
|
||||
|
@ -8,7 +8,7 @@
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Manages Blip instances.
|
||||
* Manages a single blip entity.
|
||||
*/
|
||||
class CBlip
|
||||
{
|
||||
@ -17,20 +17,19 @@ class CBlip
|
||||
|
||||
private:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Cached identifiers for fast integer to string conversion.
|
||||
*/
|
||||
static SQChar s_StrID[SQMOD_BLIP_POOL][8];
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Identifier of the managed entity.
|
||||
*/
|
||||
Int32 m_ID;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* User tag and data associated with this instance.
|
||||
* User tag associated with this instance.
|
||||
*/
|
||||
String m_Tag;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* User data associated with this instance.
|
||||
*/
|
||||
Object m_Data;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
@ -38,20 +37,22 @@ private:
|
||||
*/
|
||||
CBlip(Int32 id);
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Maximum possible number that could represent an identifier for this entity type.
|
||||
*/
|
||||
static const Int32 Max;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor. (disabled)
|
||||
*/
|
||||
CBlip(const CBlip &);
|
||||
CBlip(const CBlip &) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator. (disabled)
|
||||
* Move constructor. (disabled)
|
||||
*/
|
||||
CBlip & operator = (const CBlip &);
|
||||
|
||||
public:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
static const Int32 Max;
|
||||
CBlip(CBlip &&) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
@ -59,14 +60,22 @@ public:
|
||||
~CBlip();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether this instance manages a valid entity.
|
||||
* Copy assignment operator. (disabled)
|
||||
*/
|
||||
bool Validate() const
|
||||
CBlip & operator = (const CBlip &) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator. (disabled)
|
||||
*/
|
||||
CBlip & operator = (CBlip &&) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether this instance manages a valid entity otherwise throw an exception.
|
||||
*/
|
||||
void Validate() const
|
||||
{
|
||||
if (VALID_ENTITY(m_ID))
|
||||
return true;
|
||||
SqThrow("Invalid blip reference [%s]", m_Tag.c_str());
|
||||
return false;
|
||||
if (INVALID_ENTITY(m_ID))
|
||||
SqThrowF("Invalid blip reference [%s]", m_Tag.c_str());
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
@ -77,27 +86,33 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const;
|
||||
const String & ToString() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to retrieve the name from instances of this type.
|
||||
*/
|
||||
static SQInteger Typename(HSQUIRRELVM vm);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the identifier of the entity managed by this instance.
|
||||
*/
|
||||
Int32 GetID() const { return m_ID; }
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the maximum possible identifier to an entity of this type.
|
||||
*/
|
||||
Int32 GetMaxID() const { return SQMOD_BLIP_POOL; }
|
||||
Int32 GetID() const
|
||||
{
|
||||
return m_ID;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Check whether this instance manages a valid entity.
|
||||
*/
|
||||
bool IsActive() const { return VALID_ENTITY(m_ID); }
|
||||
bool IsActive() const
|
||||
{
|
||||
return VALID_ENTITY(m_ID);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the associated user tag.
|
||||
*/
|
||||
CSStr GetTag() const;
|
||||
const String & GetTag() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the associated user tag.
|
||||
@ -115,29 +130,89 @@ public:
|
||||
void SetData(Object & data);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destroy the managed entity instance.
|
||||
* Destroy the managed blip entity.
|
||||
*/
|
||||
bool Destroy()
|
||||
{
|
||||
return Destroy(0, NullObject());
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destroy the managed blip entity.
|
||||
*/
|
||||
bool Destroy(Int32 header)
|
||||
{
|
||||
return Destroy(header, NullObject());
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destroy the managed blip entity.
|
||||
*/
|
||||
bool Destroy(Int32 header, Object & payload);
|
||||
bool Destroy() { return Destroy(0, NullObject()); }
|
||||
bool Destroy(Int32 header) { return Destroy(header, NullObject()); }
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
bool BindEvent(Int32 evid, Object & env, Function & func) const;
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Bind to an event supported by this entity type.
|
||||
*/
|
||||
void BindEvent(Int32 evid, Object & env, Function & func) const;
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the world in which the referenced blip entity exists.
|
||||
*/
|
||||
Int32 GetWorld() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the scale of the managed blip entity.
|
||||
*/
|
||||
Int32 GetScale() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the position of the managed blip entity.
|
||||
*/
|
||||
const Vector3 & GetPosition() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the color of the managed blip entity.
|
||||
*/
|
||||
const Color4 & GetColor() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the identifier of the sprite used by the managed blip entity.
|
||||
*/
|
||||
Int32 GetSprID() const;
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the position on the x axis of the managed blip entity.
|
||||
*/
|
||||
Float32 GetPosX() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the position on the y axis of the managed blip entity.
|
||||
*/
|
||||
Float32 GetPosY() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the position on the z axis of the managed blip entity.
|
||||
*/
|
||||
Float32 GetPosZ() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the red color of the managed blip entity.
|
||||
*/
|
||||
Int32 GetColorR() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the green color of the managed blip entity.
|
||||
*/
|
||||
Int32 GetColorG() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the blue color of the managed blip entity.
|
||||
*/
|
||||
Int32 GetColorB() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the alpha transparency of the managed blip entity.
|
||||
*/
|
||||
Int32 GetColorA() const;
|
||||
};
|
||||
|
||||
|
@ -19,15 +19,20 @@ Uint32 CCheckpoint::s_ColorB;
|
||||
Uint32 CCheckpoint::s_ColorA;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQChar CCheckpoint::s_StrID[SQMOD_CHECKPOINT_POOL][8];
|
||||
const Int32 CCheckpoint::Max = SQMOD_CHECKPOINT_POOL;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const Int32 CCheckpoint::Max = SQMOD_CHECKPOINT_POOL;
|
||||
SQInteger CCheckpoint::Typename(HSQUIRRELVM vm)
|
||||
{
|
||||
static SQChar name[] = _SC("SqCheckpoint");
|
||||
sq_pushstring(vm, name, sizeof(name));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CCheckpoint::CCheckpoint(Int32 id)
|
||||
: m_ID(VALID_ENTITYGETEX(id, SQMOD_CHECKPOINT_POOL))
|
||||
, m_Tag(VALID_ENTITY(m_ID) ? s_StrID[m_ID] : _SC("-1"))
|
||||
, m_Tag(ToStrF("%d", id))
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
@ -49,282 +54,373 @@ Int32 CCheckpoint::Cmp(const CCheckpoint & o) const
|
||||
return -1;
|
||||
}
|
||||
|
||||
CSStr CCheckpoint::ToString() const
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const String & CCheckpoint::ToString() const
|
||||
{
|
||||
return VALID_ENTITYEX(m_ID, SQMOD_CHECKPOINT_POOL) ? s_StrID[m_ID] : _SC("-1");
|
||||
return m_Tag;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr CCheckpoint::GetTag() const
|
||||
const String & CCheckpoint::GetTag() const
|
||||
{
|
||||
return m_Tag.c_str();
|
||||
return m_Tag;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CCheckpoint::SetTag(CSStr tag)
|
||||
{
|
||||
m_Tag.assign(tag);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Object & CCheckpoint::GetData()
|
||||
{
|
||||
if (Validate())
|
||||
return m_Data;
|
||||
return NullObject();
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return m_Data;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CCheckpoint::SetData(Object & data)
|
||||
{
|
||||
if (Validate())
|
||||
m_Data = data;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Apply the specified value
|
||||
m_Data = data;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool CCheckpoint::Destroy(Int32 header, Object & payload)
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
return _Core->DelCheckpoint(m_ID, header, payload);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool CCheckpoint::BindEvent(Int32 evid, Object & env, Function & func) const
|
||||
void CCheckpoint::BindEvent(Int32 evid, Object & env, Function & func) const
|
||||
{
|
||||
if (!Validate())
|
||||
return false;
|
||||
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Obtain the function instance called for this event
|
||||
Function & event = _Core->GetCheckpointEvent(m_ID, evid);
|
||||
|
||||
// Is the specified callback function null?
|
||||
if (func.IsNull())
|
||||
event.Release();
|
||||
event.Release(); // Then release the current callback
|
||||
// Assign the specified environment and function
|
||||
else
|
||||
event = Function(env.GetVM(), env, func.GetFunc());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool CCheckpoint::IsStreamedFor(CPlayer & player) const
|
||||
{
|
||||
// Is the specified player even valid?
|
||||
if (!player.IsActive())
|
||||
SqThrow("Invalid player argument: null");
|
||||
else if (Validate())
|
||||
return _Func->IsCheckpointStreamedForPlayer(m_ID, player.GetID());
|
||||
return false;
|
||||
SqThrowF("Invalid player argument: null");
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Func->IsCheckpointStreamedForPlayer(m_ID, player.GetID());
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 CCheckpoint::GetWorld() const
|
||||
{
|
||||
if (Validate())
|
||||
return _Func->GetCheckpointWorld(m_ID);
|
||||
return -1;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Func->GetCheckpointWorld(m_ID);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CCheckpoint::SetWorld(Int32 world) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->SetCheckpointWorld(m_ID, world);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->SetCheckpointWorld(m_ID, world);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const Color4 & CCheckpoint::GetColor() const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Clear previous color information, if any
|
||||
s_Color4.Clear();
|
||||
if (Validate())
|
||||
{
|
||||
_Func->GetCheckpointColor(m_ID, &s_ColorR, &s_ColorG, &s_ColorB, &s_ColorA);
|
||||
s_Color4.Set(s_ColorR, s_ColorG, s_ColorB, s_ColorA);
|
||||
}
|
||||
// Query the server for the color values
|
||||
_Func->GetCheckpointColor(m_ID, &s_ColorR, &s_ColorG, &s_ColorB, &s_ColorA);
|
||||
// Convert and assign the retrieved values
|
||||
s_Color4.Set(s_ColorR, s_ColorG, s_ColorB, s_ColorA);
|
||||
// Return the requested information
|
||||
return s_Color4;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CCheckpoint::SetColor(const Color4 & col) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->SetCheckpointColor(m_ID, col.r, col.g, col.b, col.a);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->SetCheckpointColor(m_ID, col.r, col.g, col.b, col.a);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CCheckpoint::SetColorEx(Uint8 r, Uint8 g, Uint8 b, Uint8 a) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->SetCheckpointColor(m_ID, r, g, b, a);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->SetCheckpointColor(m_ID, r, g, b, a);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const Vector3 & CCheckpoint::GetPosition() const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Clear previous position information, if any
|
||||
s_Vector3.Clear();
|
||||
if (Validate())
|
||||
_Func->GetCheckpointPos(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z);
|
||||
// Query the server for the position values
|
||||
_Func->GetCheckpointPos(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z);
|
||||
// Return the requested information
|
||||
return s_Vector3;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CCheckpoint::SetPosition(const Vector3 & pos) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->SetCheckpointPos(m_ID, pos.x, pos.y, pos.z);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->SetCheckpointPos(m_ID, pos.x, pos.y, pos.z);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CCheckpoint::SetPositionEx(Float32 x, Float32 y, Float32 z) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->SetCheckpointPos(m_ID, x, y, z);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->SetCheckpointPos(m_ID, x, y, z);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Float32 CCheckpoint::GetRadius() const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->GetCheckpointRadius(m_ID);
|
||||
return 0;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Func->GetCheckpointRadius(m_ID);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CCheckpoint::SetRadius(Float32 radius) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->SetCheckpointRadius(m_ID, radius);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->SetCheckpointRadius(m_ID, radius);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Object & CCheckpoint::GetOwner() const
|
||||
{
|
||||
if (Validate())
|
||||
return _Core->GetPlayer(_Func->GetCheckpointOwner(m_ID)).mObj;
|
||||
return NullObject();
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Core->GetPlayer(_Func->GetCheckpointOwner(m_ID)).mObj;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 CCheckpoint::GetOwnerID() const
|
||||
{
|
||||
if (Validate())
|
||||
return _Func->GetCheckpointOwner(m_ID);
|
||||
return -1;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Func->GetCheckpointOwner(m_ID);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Float32 CCheckpoint::GetPosX() const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Clear previous position information, if any
|
||||
s_Vector3.x = 0;
|
||||
if (Validate())
|
||||
_Func->GetCheckpointPos(m_ID, &s_Vector3.x, NULL, NULL);
|
||||
// Query the server for the requested component value
|
||||
_Func->GetCheckpointPos(m_ID, &s_Vector3.x, NULL, NULL);
|
||||
// Return the requested information
|
||||
return s_Vector3.x;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Float32 CCheckpoint::GetPosY() const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Clear previous position information, if any
|
||||
s_Vector3.y = 0;
|
||||
if (Validate())
|
||||
_Func->GetCheckpointPos(m_ID, NULL, &s_Vector3.y, NULL);
|
||||
// Query the server for the requested component value
|
||||
_Func->GetCheckpointPos(m_ID, NULL, &s_Vector3.y, NULL);
|
||||
// Return the requested information
|
||||
return s_Vector3.y;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Float32 CCheckpoint::GetPosZ() const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Clear previous position information, if any
|
||||
s_Vector3.z = 0;
|
||||
if (Validate())
|
||||
_Func->GetCheckpointPos(m_ID, NULL, NULL, &s_Vector3.z);
|
||||
// Query the server for the requested component value
|
||||
_Func->GetCheckpointPos(m_ID, NULL, NULL, &s_Vector3.z);
|
||||
// Return the requested information
|
||||
return s_Vector3.z;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CCheckpoint::SetPosX(Float32 x) const
|
||||
{
|
||||
if (Validate())
|
||||
{
|
||||
_Func->GetCheckpointPos(m_ID, NULL, &s_Vector3.y, &s_Vector3.z);
|
||||
_Func->SetCheckpointPos(m_ID, x, s_Vector3.y, s_Vector3.z);
|
||||
}
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Retrieve the current values for unchanged components
|
||||
_Func->GetCheckpointPos(m_ID, NULL, &s_Vector3.y, &s_Vector3.z);
|
||||
// Perform the requested operation
|
||||
_Func->SetCheckpointPos(m_ID, x, s_Vector3.y, s_Vector3.z);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CCheckpoint::SetPosY(Float32 y) const
|
||||
{
|
||||
if (Validate())
|
||||
{
|
||||
_Func->GetCheckpointPos(m_ID, &s_Vector3.x, NULL, &s_Vector3.z);
|
||||
_Func->SetCheckpointPos(m_ID, s_Vector3.x, y, s_Vector3.z);
|
||||
}
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Retrieve the current values for unchanged components
|
||||
_Func->GetCheckpointPos(m_ID, &s_Vector3.x, NULL, &s_Vector3.z);
|
||||
// Perform the requested operation
|
||||
_Func->SetCheckpointPos(m_ID, s_Vector3.x, y, s_Vector3.z);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CCheckpoint::SetPosZ(Float32 z) const
|
||||
{
|
||||
if (Validate())
|
||||
{
|
||||
_Func->GetCheckpointPos(m_ID, &s_Vector3.x, &s_Vector3.y, NULL);
|
||||
_Func->SetCheckpointPos(m_ID, s_Vector3.z, s_Vector3.y, z);
|
||||
}
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Retrieve the current values for unchanged components
|
||||
_Func->GetCheckpointPos(m_ID, &s_Vector3.x, &s_Vector3.y, NULL);
|
||||
// Perform the requested operation
|
||||
_Func->SetCheckpointPos(m_ID, s_Vector3.z, s_Vector3.y, z);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Uint32 CCheckpoint::GetColR() const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Clear previous color information, if any
|
||||
s_ColorR = 0;
|
||||
if (Validate())
|
||||
_Func->GetCheckpointColor(m_ID, &s_ColorR, NULL, NULL, NULL);
|
||||
// Query the server for the requested component value
|
||||
_Func->GetCheckpointColor(m_ID, &s_ColorR, NULL, NULL, NULL);
|
||||
// Return the requested information
|
||||
return s_ColorR;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Uint32 CCheckpoint::GetColG() const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Clear previous color information, if any
|
||||
s_ColorG = 0;
|
||||
if (Validate())
|
||||
_Func->GetCheckpointColor(m_ID, NULL, &s_ColorG, NULL, NULL);
|
||||
// Query the server for the requested component value
|
||||
_Func->GetCheckpointColor(m_ID, NULL, &s_ColorG, NULL, NULL);
|
||||
// Return the requested information
|
||||
return s_ColorG;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Uint32 CCheckpoint::GetColB() const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Clear previous color information, if any
|
||||
s_ColorB = 0;
|
||||
if (Validate())
|
||||
_Func->GetCheckpointColor(m_ID, NULL, NULL, &s_ColorB, NULL);
|
||||
// Query the server for the requested component value
|
||||
_Func->GetCheckpointColor(m_ID, NULL, NULL, &s_ColorB, NULL);
|
||||
// Return the requested information
|
||||
return s_ColorB;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Uint32 CCheckpoint::GetColA() const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Clear previous color information, if any
|
||||
s_ColorA = 0;
|
||||
if (Validate())
|
||||
_Func->GetCheckpointColor(m_ID, NULL, NULL, NULL, &s_ColorA);
|
||||
// Query the server for the requested component value
|
||||
_Func->GetCheckpointColor(m_ID, NULL, NULL, NULL, &s_ColorA);
|
||||
// Return the requested information
|
||||
return s_ColorA;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CCheckpoint::SetColR(Uint32 r) const
|
||||
{
|
||||
if (Validate())
|
||||
{
|
||||
_Func->GetCheckpointColor(m_ID, NULL, &s_ColorG, &s_ColorB, &s_ColorA);
|
||||
_Func->SetCheckpointColor(m_ID, r, s_ColorG, s_ColorB, s_ColorA);
|
||||
}
|
||||
}
|
||||
|
||||
void CCheckpoint::SetColG(Uint32 g) const
|
||||
{
|
||||
if (Validate())
|
||||
{
|
||||
_Func->GetCheckpointColor(m_ID, &s_ColorR, NULL, &s_ColorB, &s_ColorA);
|
||||
_Func->SetCheckpointColor(m_ID, s_ColorR, g, s_ColorB, s_ColorA);
|
||||
}
|
||||
}
|
||||
|
||||
void CCheckpoint::SetColB(Uint32 b) const
|
||||
{
|
||||
if (Validate())
|
||||
{
|
||||
_Func->GetCheckpointColor(m_ID, &s_ColorB, &s_ColorG, NULL, &s_ColorA);
|
||||
_Func->SetCheckpointColor(m_ID, s_ColorB, s_ColorG, b, s_ColorA);
|
||||
}
|
||||
}
|
||||
|
||||
void CCheckpoint::SetColA(Uint32 a) const
|
||||
{
|
||||
if (Validate())
|
||||
{
|
||||
_Func->GetCheckpointColor(m_ID, &s_ColorA, &s_ColorG, &s_ColorB, NULL);
|
||||
_Func->SetCheckpointColor(m_ID, s_ColorA, s_ColorG, s_ColorB, a);
|
||||
}
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Retrieve the current values for unchanged components
|
||||
_Func->GetCheckpointColor(m_ID, NULL, &s_ColorG, &s_ColorB, &s_ColorA);
|
||||
// Perform the requested operation
|
||||
_Func->SetCheckpointColor(m_ID, r, s_ColorG, s_ColorB, s_ColorA);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static Object & CreateCheckpointEx(CPlayer & player, Int32 world, Float32 x, Float32 y, Float32 z,
|
||||
void CCheckpoint::SetColG(Uint32 g) const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Retrieve the current values for unchanged components
|
||||
_Func->GetCheckpointColor(m_ID, &s_ColorR, NULL, &s_ColorB, &s_ColorA);
|
||||
// Perform the requested operation
|
||||
_Func->SetCheckpointColor(m_ID, s_ColorR, g, s_ColorB, s_ColorA);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CCheckpoint::SetColB(Uint32 b) const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Retrieve the current values for unchanged components
|
||||
_Func->GetCheckpointColor(m_ID, &s_ColorB, &s_ColorG, NULL, &s_ColorA);
|
||||
// Perform the requested operation
|
||||
_Func->SetCheckpointColor(m_ID, s_ColorB, s_ColorG, b, s_ColorA);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CCheckpoint::SetColA(Uint32 a) const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Retrieve the current values for unchanged components
|
||||
_Func->GetCheckpointColor(m_ID, &s_ColorA, &s_ColorG, &s_ColorB, NULL);
|
||||
// Perform the requested operation
|
||||
_Func->SetCheckpointColor(m_ID, s_ColorA, s_ColorG, s_ColorB, a);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static Object & Checkpoint_CreateEx(CPlayer & player, Int32 world, Float32 x, Float32 y, Float32 z,
|
||||
Uint8 r, Uint8 g, Uint8 b, Uint8 a, Float32 radius)
|
||||
{
|
||||
return _Core->NewCheckpoint(player.GetID(), world, x, y, z, r, g, b, a, radius,
|
||||
SQMOD_CREATE_DEFAULT, NullObject());
|
||||
}
|
||||
|
||||
static Object & CreateCheckpointEx(CPlayer & player, Int32 world, Float32 x, Float32 y, Float32 z,
|
||||
static Object & Checkpoint_CreateEx(CPlayer & player, Int32 world, Float32 x, Float32 y, Float32 z,
|
||||
Uint8 r, Uint8 g, Uint8 b, Uint8 a, Float32 radius,
|
||||
Int32 header, Object & payload)
|
||||
{
|
||||
@ -332,7 +428,7 @@ static Object & CreateCheckpointEx(CPlayer & player, Int32 world, Float32 x, Flo
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static Object & CreateCheckpoint(CPlayer & player, Int32 world, const Vector3 & pos,
|
||||
static Object & Checkpoint_Create(CPlayer & player, Int32 world, const Vector3 & pos,
|
||||
const Color4 & color, Float32 radius)
|
||||
{
|
||||
return _Core->NewCheckpoint(player.GetID(), world, pos.x, pos.y, pos.z,
|
||||
@ -340,7 +436,7 @@ static Object & CreateCheckpoint(CPlayer & player, Int32 world, const Vector3 &
|
||||
SQMOD_CREATE_DEFAULT, NullObject());
|
||||
}
|
||||
|
||||
static Object & CreateCheckpoint(CPlayer & player, Int32 world, const Vector3 & pos,
|
||||
static Object & Checkpoint_Create(CPlayer & player, Int32 world, const Vector3 & pos,
|
||||
const Color4 & color, Float32 radius, Int32 header, Object & payload)
|
||||
{
|
||||
return _Core->NewCheckpoint(player.GetID(), world, pos.x, pos.y, pos.z,
|
||||
@ -352,22 +448,24 @@ void Register_CCheckpoint(HSQUIRRELVM vm)
|
||||
{
|
||||
RootTable(vm).Bind(_SC("SqCheckpoint"),
|
||||
Class< CCheckpoint, NoConstructor< CCheckpoint > >(vm, _SC("SqCheckpoint"))
|
||||
/* Metamethods */
|
||||
// Metamethods
|
||||
.Func(_SC("_cmp"), &CCheckpoint::Cmp)
|
||||
.SquirrelFunc(_SC("_typename"), &CCheckpoint::Typename)
|
||||
.Func(_SC("_tostring"), &CCheckpoint::ToString)
|
||||
/* Core Properties */
|
||||
// Static values
|
||||
.SetStaticValue(_SC("MaxID"), CCheckpoint::Max)
|
||||
// Core Properties
|
||||
.Prop(_SC("ID"), &CCheckpoint::GetID)
|
||||
.Prop(_SC("Tag"), &CCheckpoint::GetTag, &CCheckpoint::SetTag)
|
||||
.Prop(_SC("Data"), &CCheckpoint::GetData, &CCheckpoint::SetData)
|
||||
.Prop(_SC("MaxID"), &CCheckpoint::GetMaxID)
|
||||
.Prop(_SC("Active"), &CCheckpoint::IsActive)
|
||||
/* Core Functions */
|
||||
// Core Functions
|
||||
.Func(_SC("Bind"), &CCheckpoint::BindEvent)
|
||||
/* Core Overloads */
|
||||
// Core Overloads
|
||||
.Overload< bool (CCheckpoint::*)(void) >(_SC("Destroy"), &CCheckpoint::Destroy)
|
||||
.Overload< bool (CCheckpoint::*)(Int32) >(_SC("Destroy"), &CCheckpoint::Destroy)
|
||||
.Overload< bool (CCheckpoint::*)(Int32, Object &) >(_SC("Destroy"), &CCheckpoint::Destroy)
|
||||
/* Properties */
|
||||
// Properties
|
||||
.Prop(_SC("World"), &CCheckpoint::GetWorld, &CCheckpoint::SetWorld)
|
||||
.Prop(_SC("Color"), &CCheckpoint::GetColor, &CCheckpoint::SetColor)
|
||||
.Prop(_SC("Pos"), &CCheckpoint::GetPosition, &CCheckpoint::SetPosition)
|
||||
@ -382,22 +480,21 @@ void Register_CCheckpoint(HSQUIRRELVM vm)
|
||||
.Prop(_SC("G"), &CCheckpoint::GetColG, &CCheckpoint::SetColG)
|
||||
.Prop(_SC("B"), &CCheckpoint::GetColB, &CCheckpoint::SetColB)
|
||||
.Prop(_SC("A"), &CCheckpoint::GetColA, &CCheckpoint::SetColA)
|
||||
/* Functions */
|
||||
// Functions
|
||||
.Func(_SC("StreamedFor"), &CCheckpoint::IsStreamedFor)
|
||||
.Func(_SC("SetColor"), &CCheckpoint::SetColorEx)
|
||||
.Func(_SC("SetPos"), &CCheckpoint::SetPositionEx)
|
||||
.Func(_SC("SetPosition"), &CCheckpoint::SetPositionEx)
|
||||
// Static Overloads
|
||||
.StaticOverload< Object & (*)(CPlayer &, Int32, Float32, Float32, Float32, Uint8, Uint8, Uint8, Uint8, Float32) >
|
||||
(_SC("CreateEx"), &Checkpoint_CreateEx)
|
||||
.StaticOverload< Object & (*)(CPlayer &, Int32, Float32, Float32, Float32, Uint8, Uint8, Uint8, Uint8, Float32, Int32, Object &) >
|
||||
(_SC("CreateEx"), &Checkpoint_CreateEx)
|
||||
.StaticOverload< Object & (*)(CPlayer &, Int32, const Vector3 &, const Color4 &, Float32) >
|
||||
(_SC("Create"), &Checkpoint_Create)
|
||||
.StaticOverload< Object & (*)(CPlayer &, Int32, const Vector3 &, const Color4 &, Float32, Int32, Object &) >
|
||||
(_SC("Create"), &Checkpoint_Create)
|
||||
);
|
||||
|
||||
RootTable(vm)
|
||||
.Overload< Object & (*)(CPlayer &, Int32, Float32, Float32, Float32, Uint8, Uint8, Uint8, Uint8, Float32) >
|
||||
(_SC("CreateCheckpointEx"), &CreateCheckpointEx)
|
||||
.Overload< Object & (*)(CPlayer &, Int32, Float32, Float32, Float32, Uint8, Uint8, Uint8, Uint8, Float32, Int32, Object &) >
|
||||
(_SC("CreateCheckpointEx"), &CreateCheckpointEx)
|
||||
.Overload< Object & (*)(CPlayer &, Int32, const Vector3 &, const Color4 &, Float32) >
|
||||
(_SC("CreateCheckpoint"), &CreateCheckpoint)
|
||||
.Overload< Object & (*)(CPlayer &, Int32, const Vector3 &, const Color4 &, Float32, Int32, Object &) >
|
||||
(_SC("CreateCheckpoint"), &CreateCheckpoint);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
||||
} // Namespace:: SqMod
|
||||
|
@ -8,7 +8,7 @@
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Manages Checkpoint instances.
|
||||
* Manages a single checkpoint entity.
|
||||
*/
|
||||
class CCheckpoint
|
||||
{
|
||||
@ -24,20 +24,19 @@ private:
|
||||
// --------------------------------------------------------------------------------------------
|
||||
static Uint32 s_ColorR, s_ColorG, s_ColorB, s_ColorA;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Cached identifiers for fast integer to string conversion.
|
||||
*/
|
||||
static SQChar s_StrID[SQMOD_CHECKPOINT_POOL][8];
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Identifier of the managed entity.
|
||||
*/
|
||||
Int32 m_ID;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* User tag and data associated with this instance.
|
||||
* User tag associated with this instance.
|
||||
*/
|
||||
String m_Tag;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* User data associated with this instance.
|
||||
*/
|
||||
Object m_Data;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
@ -45,20 +44,22 @@ private:
|
||||
*/
|
||||
CCheckpoint(Int32 id);
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Maximum possible number that could represent an identifier for this entity type.
|
||||
*/
|
||||
static const Int32 Max;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor. (disabled)
|
||||
*/
|
||||
CCheckpoint(const CCheckpoint &);
|
||||
CCheckpoint(const CCheckpoint &) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator. (disabled)
|
||||
* Move constructor. (disabled)
|
||||
*/
|
||||
CCheckpoint & operator = (const CCheckpoint &);
|
||||
|
||||
public:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
static const Int32 Max;
|
||||
CCheckpoint(CCheckpoint &&) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
@ -66,14 +67,22 @@ public:
|
||||
~CCheckpoint();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether this instance manages a valid entity.
|
||||
* Copy assignment operator. (disabled)
|
||||
*/
|
||||
bool Validate() const
|
||||
CCheckpoint & operator = (const CCheckpoint &) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator. (disabled)
|
||||
*/
|
||||
CCheckpoint & operator = (CCheckpoint &&) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether this instance manages a valid entity otherwise throw an exception.
|
||||
*/
|
||||
void Validate() const
|
||||
{
|
||||
if (VALID_ENTITY(m_ID))
|
||||
return true;
|
||||
SqThrow("Invalid checkpoint reference [%s]", m_Tag.c_str());
|
||||
return false;
|
||||
if (INVALID_ENTITY(m_ID))
|
||||
SqThrowF("Invalid checkpoint reference [%s]", m_Tag.c_str());
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
@ -84,27 +93,33 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const;
|
||||
const String & ToString() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to retrieve the name from instances of this type.
|
||||
*/
|
||||
static SQInteger Typename(HSQUIRRELVM vm);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the identifier of the entity managed by this instance.
|
||||
*/
|
||||
Int32 GetID() const { return m_ID; }
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the maximum possible identifier to an entity of this type.
|
||||
*/
|
||||
Int32 GetMaxID() const { return SQMOD_CHECKPOINT_POOL; }
|
||||
Int32 GetID() const
|
||||
{
|
||||
return m_ID;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Check whether this instance manages a valid entity.
|
||||
*/
|
||||
bool IsActive() const { return VALID_ENTITY(m_ID); }
|
||||
bool IsActive() const
|
||||
{
|
||||
return VALID_ENTITY(m_ID);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the associated user tag.
|
||||
*/
|
||||
CSStr GetTag() const;
|
||||
const String & GetTag() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the associated user tag.
|
||||
@ -120,45 +135,166 @@ public:
|
||||
* Modify the associated user data.
|
||||
*/
|
||||
void SetData(Object & data);
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destroy the managed checkpoint entity.
|
||||
*/
|
||||
bool Destroy()
|
||||
{
|
||||
return Destroy(0, NullObject());
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destroy the managed checkpoint entity.
|
||||
*/
|
||||
bool Destroy(Int32 header)
|
||||
{
|
||||
return Destroy(header, NullObject());
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destroy the managed checkpoint entity.
|
||||
*/
|
||||
bool Destroy(Int32 header, Object & payload);
|
||||
bool Destroy() { return Destroy(0, NullObject()); }
|
||||
bool Destroy(Int32 header) { return Destroy(header, NullObject()); }
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
bool BindEvent(Int32 evid, Object & env, Function & func) const;
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Bind to an event supported by this entity type.
|
||||
*/
|
||||
void BindEvent(Int32 evid, Object & env, Function & func) const;
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See if the managed checkpoint entity is streamed for the specified player.
|
||||
*/
|
||||
bool IsStreamedFor(CPlayer & player) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the world in which the managed checkpoint entity exists.
|
||||
*/
|
||||
Int32 GetWorld() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the world in which the managed checkpoint entity exists.
|
||||
*/
|
||||
void SetWorld(Int32 world) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the color of the managed checkpoint entity.
|
||||
*/
|
||||
const Color4 & GetColor() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the color of the managed checkpoint entity.
|
||||
*/
|
||||
void SetColor(const Color4 & col) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the color of the managed checkpoint entity.
|
||||
*/
|
||||
void SetColorEx(Uint8 r, Uint8 g, Uint8 b, Uint8 a) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the position of the managed checkpoint entity.
|
||||
*/
|
||||
const Vector3 & GetPosition() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the position of the managed checkpoint entity.
|
||||
*/
|
||||
void SetPosition(const Vector3 & pos) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the position of the managed checkpoint entity.
|
||||
*/
|
||||
void SetPositionEx(Float32 x, Float32 y, Float32 z) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the radius of the managed checkpoint entity.
|
||||
*/
|
||||
Float32 GetRadius() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the radius of the managed checkpoint entity.
|
||||
*/
|
||||
void SetRadius(Float32 radius) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the owner of the managed checkpoint entity.
|
||||
*/
|
||||
Object & GetOwner() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the owner identifier of the managed checkpoint entity.
|
||||
*/
|
||||
Int32 GetOwnerID() const;
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the position on the x axis of the managed checkpoint entity.
|
||||
*/
|
||||
Float32 GetPosX() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the position on the y axis of the managed checkpoint entity.
|
||||
*/
|
||||
Float32 GetPosY() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the position on the z axis of the managed checkpoint entity.
|
||||
*/
|
||||
Float32 GetPosZ() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the position on the x axis of the managed checkpoint entity.
|
||||
*/
|
||||
void SetPosX(Float32 x) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the position on the y axis of the managed checkpoint entity.
|
||||
*/
|
||||
void SetPosY(Float32 y) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the position on the z axis of the managed checkpoint entity.
|
||||
*/
|
||||
void SetPosZ(Float32 z) const;
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the red color of the managed checkpoint entity.
|
||||
*/
|
||||
Uint32 GetColR() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the green color of the managed checkpoint entity.
|
||||
*/
|
||||
Uint32 GetColG() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the blue color of the managed checkpoint entity.
|
||||
*/
|
||||
Uint32 GetColB() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the alpha transparency of the managed checkpoint entity.
|
||||
*/
|
||||
Uint32 GetColA() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the red color of the managed checkpoint entity.
|
||||
*/
|
||||
void SetColR(Uint32 r) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the green color of the managed checkpoint entity.
|
||||
*/
|
||||
void SetColG(Uint32 g) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the blue color of the managed checkpoint entity.
|
||||
*/
|
||||
void SetColB(Uint32 b) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the alpha transparency of the managed checkpoint entity.
|
||||
*/
|
||||
void SetColA(Uint32 a) const;
|
||||
};
|
||||
|
||||
|
@ -18,15 +18,20 @@ Uint32 CForcefield::s_ColorG;
|
||||
Uint32 CForcefield::s_ColorB;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQChar CForcefield::s_StrID[SQMOD_FORCEFIELD_POOL][8];
|
||||
const Int32 CForcefield::Max = SQMOD_FORCEFIELD_POOL;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const Int32 CForcefield::Max = SQMOD_FORCEFIELD_POOL;
|
||||
SQInteger CForcefield::Typename(HSQUIRRELVM vm)
|
||||
{
|
||||
static SQChar name[] = _SC("SqForcefield");
|
||||
sq_pushstring(vm, name, sizeof(name));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CForcefield::CForcefield(Int32 id)
|
||||
: m_ID(VALID_ENTITYGETEX(id, SQMOD_FORCEFIELD_POOL))
|
||||
, m_Tag(VALID_ENTITY(m_ID) ? s_StrID[m_ID] : _SC("-1"))
|
||||
, m_Tag(ToStrF("%d", id))
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
@ -48,265 +53,349 @@ Int32 CForcefield::Cmp(const CForcefield & o) const
|
||||
return -1;
|
||||
}
|
||||
|
||||
CSStr CForcefield::ToString() const
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const String & CForcefield::ToString() const
|
||||
{
|
||||
return VALID_ENTITYEX(m_ID, SQMOD_FORCEFIELD_POOL) ? s_StrID[m_ID] : _SC("-1");
|
||||
return m_Tag;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr CForcefield::GetTag() const
|
||||
const String & CForcefield::GetTag() const
|
||||
{
|
||||
return m_Tag.c_str();
|
||||
return m_Tag;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CForcefield::SetTag(CSStr tag)
|
||||
{
|
||||
m_Tag.assign(tag);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Object & CForcefield::GetData()
|
||||
{
|
||||
if (Validate())
|
||||
return m_Data;
|
||||
return NullObject();
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return m_Data;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CForcefield::SetData(Object & data)
|
||||
{
|
||||
if (Validate())
|
||||
m_Data = data;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Apply the specified value
|
||||
m_Data = data;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool CForcefield::Destroy(Int32 header, Object & payload)
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
return _Core->DelForcefield(m_ID, header, payload);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool CForcefield::BindEvent(Int32 evid, Object & env, Function & func) const
|
||||
void CForcefield::BindEvent(Int32 evid, Object & env, Function & func) const
|
||||
{
|
||||
if (!Validate())
|
||||
return false;
|
||||
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Obtain the function instance called for this event
|
||||
Function & event = _Core->GetForcefieldEvent(m_ID, evid);
|
||||
|
||||
// Is the specified callback function null?
|
||||
if (func.IsNull())
|
||||
event.Release();
|
||||
event.Release(); // Then release the current callback
|
||||
// Assign the specified environment and function
|
||||
else
|
||||
event = Function(env.GetVM(), env, func.GetFunc());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool CForcefield::IsStreamedFor(CPlayer & player) const
|
||||
{
|
||||
// Is the specified player even valid?
|
||||
if (!player.IsActive())
|
||||
SqThrow("Invalid player argument: null");
|
||||
else if (Validate())
|
||||
return _Func->IsSphereStreamedForPlayer(m_ID, player.GetID());
|
||||
return false;
|
||||
SqThrowF("Invalid player argument: null");
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Func->IsSphereStreamedForPlayer(m_ID, player.GetID());
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 CForcefield::GetWorld() const
|
||||
{
|
||||
if (Validate())
|
||||
return _Func->GetSphereWorld(m_ID);
|
||||
return -1;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Func->GetSphereWorld(m_ID);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CForcefield::SetWorld(Int32 world) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->SetSphereWorld(m_ID, world);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->SetSphereWorld(m_ID, world);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const Color3 & CForcefield::GetColor() const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Clear previous color information, if any
|
||||
s_Color3.Clear();
|
||||
if (Validate())
|
||||
{
|
||||
_Func->GetSphereColor(m_ID, &s_ColorR, &s_ColorG, &s_ColorB);
|
||||
s_Color3.Set(s_ColorR, s_ColorG, s_ColorB);
|
||||
}
|
||||
// Query the server for the color values
|
||||
_Func->GetSphereColor(m_ID, &s_ColorR, &s_ColorG, &s_ColorB);
|
||||
// Convert and assign the retrieved values
|
||||
s_Color3.Set(s_ColorR, s_ColorG, s_ColorB);
|
||||
// Return the requested information
|
||||
return s_Color3;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CForcefield::SetColor(const Color3 & col) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->SetSphereColor(m_ID, col.r, col.g, col.b);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->SetSphereColor(m_ID, col.r, col.g, col.b);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CForcefield::SetColorEx(Uint8 r, Uint8 g, Uint8 b) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->SetSphereColor(m_ID, r, g, b);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->SetSphereColor(m_ID, r, g, b);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const Vector3 & CForcefield::GetPosition() const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Clear previous position information, if any
|
||||
s_Vector3.Clear();
|
||||
if (Validate())
|
||||
_Func->GetSpherePos(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z);
|
||||
// Query the server for the position values
|
||||
_Func->GetSpherePos(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z);
|
||||
// Return the requested information
|
||||
return s_Vector3;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CForcefield::SetPosition(const Vector3 & pos) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->SetSpherePos(m_ID, pos.x, pos.y, pos.z);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->SetSpherePos(m_ID, pos.x, pos.y, pos.z);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CForcefield::SetPositionEx(Float32 x, Float32 y, Float32 z) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->SetSpherePos(m_ID, x, y, z);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->SetSpherePos(m_ID, x, y, z);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Float32 CForcefield::GetRadius() const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->GetSphereRadius(m_ID);
|
||||
return 0;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Func->GetSphereRadius(m_ID);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CForcefield::SetRadius(Float32 radius) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->SetSphereRadius(m_ID, radius);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->SetSphereRadius(m_ID, radius);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Object & CForcefield::GetOwner() const
|
||||
{
|
||||
if (Validate())
|
||||
return _Core->GetPlayer(_Func->GetSphereOwner(m_ID)).mObj;
|
||||
return NullObject();
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Core->GetPlayer(_Func->GetSphereOwner(m_ID)).mObj;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 CForcefield::GetOwnerID() const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->GetSphereOwner(m_ID);
|
||||
return -1;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Func->GetSphereOwner(m_ID);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Float32 CForcefield::GetPosX() const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Clear previous position information, if any
|
||||
s_Vector3.x = 0;
|
||||
if (Validate())
|
||||
_Func->GetSpherePos(m_ID, &s_Vector3.x, NULL, NULL);
|
||||
// Query the server for the requested component value
|
||||
_Func->GetSpherePos(m_ID, &s_Vector3.x, NULL, NULL);
|
||||
// Return the requested information
|
||||
return s_Vector3.x;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Float32 CForcefield::GetPosY() const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Clear previous position information, if any
|
||||
s_Vector3.y = 0;
|
||||
if (Validate())
|
||||
_Func->GetSpherePos(m_ID, NULL, &s_Vector3.y, NULL);
|
||||
// Query the server for the requested component value
|
||||
_Func->GetSpherePos(m_ID, NULL, &s_Vector3.y, NULL);
|
||||
// Return the requested information
|
||||
return s_Vector3.y;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Float32 CForcefield::GetPosZ() const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Clear previous position information, if any
|
||||
s_Vector3.z = 0;
|
||||
if (Validate())
|
||||
_Func->GetSpherePos(m_ID, NULL, NULL, &s_Vector3.z);
|
||||
// Query the server for the requested component value
|
||||
_Func->GetSpherePos(m_ID, NULL, NULL, &s_Vector3.z);
|
||||
// Return the requested information
|
||||
return s_Vector3.z;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CForcefield::SetPosX(Float32 x) const
|
||||
{
|
||||
if (Validate())
|
||||
{
|
||||
_Func->GetSpherePos(m_ID, NULL, &s_Vector3.y, &s_Vector3.z);
|
||||
_Func->SetSpherePos(m_ID, x, s_Vector3.y, s_Vector3.z);
|
||||
}
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Retrieve the current values for unchanged components
|
||||
_Func->GetSpherePos(m_ID, NULL, &s_Vector3.y, &s_Vector3.z);
|
||||
// Perform the requested operation
|
||||
_Func->SetSpherePos(m_ID, x, s_Vector3.y, s_Vector3.z);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CForcefield::SetPosY(Float32 y) const
|
||||
{
|
||||
if (Validate())
|
||||
{
|
||||
_Func->GetSpherePos(m_ID, &s_Vector3.x, NULL, &s_Vector3.z);
|
||||
_Func->SetSpherePos(m_ID, s_Vector3.x, y, s_Vector3.z);
|
||||
}
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Retrieve the current values for unchanged components
|
||||
_Func->GetSpherePos(m_ID, &s_Vector3.x, NULL, &s_Vector3.z);
|
||||
// Perform the requested operation
|
||||
_Func->SetSpherePos(m_ID, s_Vector3.x, y, s_Vector3.z);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CForcefield::SetPosZ(Float32 z) const
|
||||
{
|
||||
if (Validate())
|
||||
{
|
||||
_Func->GetSpherePos(m_ID, &s_Vector3.x, &s_Vector3.y, NULL);
|
||||
_Func->SetSpherePos(m_ID, s_Vector3.z, s_Vector3.y, z);
|
||||
}
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Retrieve the current values for unchanged components
|
||||
_Func->GetSpherePos(m_ID, &s_Vector3.x, &s_Vector3.y, NULL);
|
||||
// Perform the requested operation
|
||||
_Func->SetSpherePos(m_ID, s_Vector3.z, s_Vector3.y, z);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Uint32 CForcefield::GetColR() const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Clear previous color information, if any
|
||||
s_ColorR = 0;
|
||||
if (Validate())
|
||||
_Func->GetSphereColor(m_ID, &s_ColorR, NULL, NULL);
|
||||
// Query the server for the requested component value
|
||||
_Func->GetSphereColor(m_ID, &s_ColorR, NULL, NULL);
|
||||
// Return the requested information
|
||||
return s_ColorR;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Uint32 CForcefield::GetColG() const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Query the server for the requested component value
|
||||
s_ColorG = 0;
|
||||
if (Validate())
|
||||
_Func->GetSphereColor(m_ID, NULL, &s_ColorG, NULL);
|
||||
// Query the server for the requested component value
|
||||
_Func->GetSphereColor(m_ID, NULL, &s_ColorG, NULL);
|
||||
// Return the requested information
|
||||
return s_ColorG;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Uint32 CForcefield::GetColB() const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Query the server for the requested component value
|
||||
s_ColorB = 0;
|
||||
if (Validate())
|
||||
_Func->GetSphereColor(m_ID, NULL, NULL, &s_ColorB);
|
||||
// Query the server for the requested component value
|
||||
_Func->GetSphereColor(m_ID, NULL, NULL, &s_ColorB);
|
||||
// Return the requested information
|
||||
return s_ColorB;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CForcefield::SetColR(Uint32 r) const
|
||||
{
|
||||
if (Validate())
|
||||
{
|
||||
_Func->GetSphereColor(m_ID, NULL, &s_ColorG, &s_ColorB);
|
||||
_Func->SetSphereColor(m_ID, r, s_ColorG, s_ColorB);
|
||||
}
|
||||
}
|
||||
|
||||
void CForcefield::SetColG(Uint32 g) const
|
||||
{
|
||||
if (Validate())
|
||||
{
|
||||
_Func->GetSphereColor(m_ID, &s_ColorR, NULL, &s_ColorB);
|
||||
_Func->SetSphereColor(m_ID, s_ColorR, g, s_ColorB);
|
||||
}
|
||||
}
|
||||
|
||||
void CForcefield::SetColB(Uint32 b) const
|
||||
{
|
||||
if (Validate())
|
||||
{
|
||||
_Func->GetSphereColor(m_ID, &s_ColorB, &s_ColorG, NULL);
|
||||
_Func->SetSphereColor(m_ID, s_ColorB, s_ColorG, b);
|
||||
}
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Retrieve the current values for unchanged components
|
||||
_Func->GetSphereColor(m_ID, NULL, &s_ColorG, &s_ColorB);
|
||||
// Perform the requested operation
|
||||
_Func->SetSphereColor(m_ID, r, s_ColorG, s_ColorB);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static Object & CreateForcefieldEx(CPlayer & player, Int32 world, Float32 x, Float32 y, Float32 z,
|
||||
void CForcefield::SetColG(Uint32 g) const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Retrieve the current values for unchanged components
|
||||
_Func->GetSphereColor(m_ID, &s_ColorR, NULL, &s_ColorB);
|
||||
// Perform the requested operation
|
||||
_Func->SetSphereColor(m_ID, s_ColorR, g, s_ColorB);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CForcefield::SetColB(Uint32 b) const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Retrieve the current values for unchanged components
|
||||
_Func->GetSphereColor(m_ID, &s_ColorB, &s_ColorG, NULL);
|
||||
// Perform the requested operation
|
||||
_Func->SetSphereColor(m_ID, s_ColorB, s_ColorG, b);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static Object & Forcefield_CreateEx(CPlayer & player, Int32 world, Float32 x, Float32 y, Float32 z,
|
||||
Uint8 r, Uint8 g, Uint8 b, Float32 radius)
|
||||
{
|
||||
return _Core->NewForcefield(player.GetID(), world, x, y, z, r, g, b, radius,
|
||||
SQMOD_CREATE_DEFAULT, NullObject());
|
||||
}
|
||||
|
||||
static Object & CreateForcefieldEx(CPlayer & player, Int32 world, Float32 x, Float32 y, Float32 z,
|
||||
static Object & Forcefield_CreateEx(CPlayer & player, Int32 world, Float32 x, Float32 y, Float32 z,
|
||||
Uint8 r, Uint8 g, Uint8 b, Float32 radius,
|
||||
Int32 header, Object & payload)
|
||||
{
|
||||
@ -314,14 +403,14 @@ static Object & CreateForcefieldEx(CPlayer & player, Int32 world, Float32 x, Flo
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static Object & CreateForcefield(CPlayer & player, Int32 world, const Vector3 & pos,
|
||||
static Object & Forcefield_Create(CPlayer & player, Int32 world, const Vector3 & pos,
|
||||
const Color3 & color, Float32 radius)
|
||||
{
|
||||
return _Core->NewForcefield(player.GetID(), world, pos.x, pos.y, pos.z, color.r, color.g, color.b, radius,
|
||||
SQMOD_CREATE_DEFAULT, NullObject());
|
||||
}
|
||||
|
||||
static Object & CreateForcefield(CPlayer & player, Int32 world, const Vector3 & pos,
|
||||
static Object & Forcefield_Create(CPlayer & player, Int32 world, const Vector3 & pos,
|
||||
const Color3 & color, Float32 radius, Int32 header, Object & payload)
|
||||
{
|
||||
return _Core->NewForcefield(player.GetID(), world, pos.x, pos.y, pos.z, color.r, color.g, color.b, radius,
|
||||
@ -333,22 +422,24 @@ void Register_CForcefield(HSQUIRRELVM vm)
|
||||
{
|
||||
RootTable(vm).Bind(_SC("SqForcefield"),
|
||||
Class< CForcefield, NoConstructor< CForcefield > >(vm, _SC("SqForcefield"))
|
||||
/* Metamethods */
|
||||
// Metamethods
|
||||
.Func(_SC("_cmp"), &CForcefield::Cmp)
|
||||
.SquirrelFunc(_SC("_typename"), &CForcefield::Typename)
|
||||
.Func(_SC("_tostring"), &CForcefield::ToString)
|
||||
/* Core Properties */
|
||||
// Static values
|
||||
.SetStaticValue(_SC("MaxID"), CForcefield::Max)
|
||||
// Core Properties
|
||||
.Prop(_SC("ID"), &CForcefield::GetID)
|
||||
.Prop(_SC("Tag"), &CForcefield::GetTag, &CForcefield::SetTag)
|
||||
.Prop(_SC("Data"), &CForcefield::GetData, &CForcefield::SetData)
|
||||
.Prop(_SC("MaxID"), &CForcefield::GetMaxID)
|
||||
.Prop(_SC("Active"), &CForcefield::IsActive)
|
||||
/* Core Functions */
|
||||
// Core Functions
|
||||
.Func(_SC("Bind"), &CForcefield::BindEvent)
|
||||
/* Core Overloads */
|
||||
// Core Overloads
|
||||
.Overload< bool (CForcefield::*)(void) >(_SC("Destroy"), &CForcefield::Destroy)
|
||||
.Overload< bool (CForcefield::*)(Int32) >(_SC("Destroy"), &CForcefield::Destroy)
|
||||
.Overload< bool (CForcefield::*)(Int32, Object &) >(_SC("Destroy"), &CForcefield::Destroy)
|
||||
/* Properties */
|
||||
// Properties
|
||||
.Prop(_SC("World"), &CForcefield::GetWorld, &CForcefield::SetWorld)
|
||||
.Prop(_SC("Color"), &CForcefield::GetColor, &CForcefield::SetColor)
|
||||
.Prop(_SC("Pos"), &CForcefield::GetPosition, &CForcefield::SetPosition)
|
||||
@ -362,22 +453,21 @@ void Register_CForcefield(HSQUIRRELVM vm)
|
||||
.Prop(_SC("R"), &CForcefield::GetColR, &CForcefield::SetColR)
|
||||
.Prop(_SC("G"), &CForcefield::GetColG, &CForcefield::SetColG)
|
||||
.Prop(_SC("B"), &CForcefield::GetColB, &CForcefield::SetColB)
|
||||
/* Functions */
|
||||
// Functions
|
||||
.Func(_SC("StreamedFor"), &CForcefield::IsStreamedFor)
|
||||
.Func(_SC("SetColor"), &CForcefield::SetColorEx)
|
||||
.Func(_SC("SetPos"), &CForcefield::SetPositionEx)
|
||||
.Func(_SC("SetPosition"), &CForcefield::SetPositionEx)
|
||||
// Static Overloads
|
||||
.StaticOverload< Object & (*)(CPlayer &, Int32, Float32, Float32, Float32, Uint8, Uint8, Uint8, Float32) >
|
||||
(_SC("CreateEx"), &Forcefield_CreateEx)
|
||||
.StaticOverload< Object & (*)(CPlayer &, Int32, Float32, Float32, Float32, Uint8, Uint8, Uint8, Float32, Int32, Object &) >
|
||||
(_SC("CreateEx"), &Forcefield_CreateEx)
|
||||
.StaticOverload< Object & (*)(CPlayer &, Int32, const Vector3 &, const Color3 &, Float32) >
|
||||
(_SC("Create"), &Forcefield_Create)
|
||||
.StaticOverload< Object & (*)(CPlayer &, Int32, const Vector3 &, const Color3 &, Float32, Int32, Object &) >
|
||||
(_SC("Create"), &Forcefield_Create)
|
||||
);
|
||||
|
||||
RootTable(vm)
|
||||
.Overload< Object & (*)(CPlayer &, Int32, Float32, Float32, Float32, Uint8, Uint8, Uint8, Float32) >
|
||||
(_SC("CreateForcefieldEx"), &CreateForcefieldEx)
|
||||
.Overload< Object & (*)(CPlayer &, Int32, Float32, Float32, Float32, Uint8, Uint8, Uint8, Float32, Int32, Object &) >
|
||||
(_SC("CreateForcefieldEx"), &CreateForcefieldEx)
|
||||
.Overload< Object & (*)(CPlayer &, Int32, const Vector3 &, const Color3 &, Float32) >
|
||||
(_SC("CreateForcefield"), &CreateForcefield)
|
||||
.Overload< Object & (*)(CPlayer &, Int32, const Vector3 &, const Color3 &, Float32, Int32, Object &) >
|
||||
(_SC("CreateForcefield"), &CreateForcefield);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
||||
} // Namespace:: SqMod
|
||||
|
@ -8,7 +8,7 @@
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Manages Forcefield instances.
|
||||
* Manages a single forcefield entity.
|
||||
*/
|
||||
class CForcefield
|
||||
{
|
||||
@ -24,20 +24,19 @@ private:
|
||||
// --------------------------------------------------------------------------------------------
|
||||
static Uint32 s_ColorR, s_ColorG, s_ColorB;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Cached identifiers for fast integer to string conversion.
|
||||
*/
|
||||
static SQChar s_StrID[SQMOD_FORCEFIELD_POOL][8];
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Identifier of the managed entity.
|
||||
*/
|
||||
Int32 m_ID;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* User tag and data associated with this instance.
|
||||
* User tag associated with this instance.
|
||||
*/
|
||||
String m_Tag;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* User data associated with this instance.
|
||||
*/
|
||||
Object m_Data;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
@ -45,20 +44,22 @@ private:
|
||||
*/
|
||||
CForcefield(Int32 id);
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Maximum possible number that could represent an identifier for this entity type.
|
||||
*/
|
||||
static const Int32 Max;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor. (disabled)
|
||||
*/
|
||||
CForcefield(const CForcefield &);
|
||||
CForcefield(const CForcefield &) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator. (disabled)
|
||||
* Move constructor. (disabled)
|
||||
*/
|
||||
CForcefield & operator = (const CForcefield &);
|
||||
|
||||
public:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
static const Int32 Max;
|
||||
CForcefield(CForcefield &&) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
@ -66,14 +67,22 @@ public:
|
||||
~CForcefield();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether this instance manages a valid entity.
|
||||
* Copy assignment operator. (disabled)
|
||||
*/
|
||||
bool Validate() const
|
||||
CForcefield & operator = (const CForcefield &) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator. (disabled)
|
||||
*/
|
||||
CForcefield & operator = (CForcefield &&) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether this instance manages a valid entity otherwise throw an exception.
|
||||
*/
|
||||
void Validate() const
|
||||
{
|
||||
if (VALID_ENTITY(m_ID))
|
||||
return true;
|
||||
SqThrow("Invalid forcefield reference [%s]", m_Tag.c_str());
|
||||
return false;
|
||||
if (INVALID_ENTITY(m_ID))
|
||||
SqThrowF("Invalid forcefield reference [%s]", m_Tag.c_str());
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
@ -84,27 +93,33 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const;
|
||||
const String & ToString() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to retrieve the name from instances of this type.
|
||||
*/
|
||||
static SQInteger Typename(HSQUIRRELVM vm);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the identifier of the entity managed by this instance.
|
||||
*/
|
||||
Int32 GetID() const { return m_ID; }
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the maximum possible identifier to an entity of this type.
|
||||
*/
|
||||
Int32 GetMaxID() const { return SQMOD_FORCEFIELD_POOL; }
|
||||
Int32 GetID() const
|
||||
{
|
||||
return m_ID;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Check whether this instance manages a valid entity.
|
||||
*/
|
||||
bool IsActive() const { return VALID_ENTITY(m_ID); }
|
||||
bool IsActive() const
|
||||
{
|
||||
return VALID_ENTITY(m_ID);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the associated user tag.
|
||||
*/
|
||||
CSStr GetTag() const;
|
||||
const String & GetTag() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the associated user tag.
|
||||
@ -121,43 +136,155 @@ public:
|
||||
*/
|
||||
void SetData(Object & data);
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destroy the managed forcefield entity.
|
||||
*/
|
||||
bool Destroy()
|
||||
{
|
||||
return Destroy(0, NullObject());
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destroy the managed forcefield entity.
|
||||
*/
|
||||
bool Destroy(Int32 header)
|
||||
{
|
||||
return Destroy(header, NullObject());
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destroy the managed forcefield entity.
|
||||
*/
|
||||
bool Destroy(Int32 header, Object & payload);
|
||||
bool Destroy() { return Destroy(0, NullObject()); }
|
||||
bool Destroy(Int32 header) { return Destroy(header, NullObject()); }
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
bool BindEvent(Int32 evid, Object & env, Function & func) const;
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Bind to an event supported by this entity type.
|
||||
*/
|
||||
void BindEvent(Int32 evid, Object & env, Function & func) const;
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See if the managed forcefield entity is streamed for the specified player.
|
||||
*/
|
||||
bool IsStreamedFor(CPlayer & player) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the world in which the managed forcefield entity exists.
|
||||
*/
|
||||
Int32 GetWorld() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the world in which the managed forcefield entity exists.
|
||||
*/
|
||||
void SetWorld(Int32 world) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the color of the managed forcefield entity.
|
||||
*/
|
||||
const Color3 & GetColor() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the color of the managed forcefield entity.
|
||||
*/
|
||||
void SetColor(const Color3 & col) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the color of the managed forcefield entity.
|
||||
*/
|
||||
void SetColorEx(Uint8 r, Uint8 g, Uint8 b) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the position of the managed forcefield entity.
|
||||
*/
|
||||
const Vector3 & GetPosition() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the position of the managed forcefield entity.
|
||||
*/
|
||||
void SetPosition(const Vector3 & pos) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the position of the managed forcefield entity.
|
||||
*/
|
||||
void SetPositionEx(Float32 x, Float32 y, Float32 z) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the radius of the managed forcefield entity.
|
||||
*/
|
||||
Float32 GetRadius() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the radius of the managed forcefield entity.
|
||||
*/
|
||||
void SetRadius(Float32 radius) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the owner of the managed forcefield entity.
|
||||
*/
|
||||
Object & GetOwner() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the owner identifier of the managed forcefield entity.
|
||||
*/
|
||||
Int32 GetOwnerID() const;
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the position on the x axis of the managed forcefield entity.
|
||||
*/
|
||||
Float32 GetPosX() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the position on the y axis of the managed forcefield entity.
|
||||
*/
|
||||
Float32 GetPosY() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the position on the z axis of the managed forcefield entity.
|
||||
*/
|
||||
Float32 GetPosZ() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the position on the x axis of the managed forcefield entity.
|
||||
*/
|
||||
void SetPosX(Float32 x) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the position on the y axis of the managed forcefield entity.
|
||||
*/
|
||||
void SetPosY(Float32 y) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the position on the z axis of the managed forcefield entity.
|
||||
*/
|
||||
void SetPosZ(Float32 z) const;
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the red color of the managed forcefield entity.
|
||||
*/
|
||||
Uint32 GetColR() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the green color of the managed forcefield entity.
|
||||
*/
|
||||
Uint32 GetColG() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the blue color of the managed forcefield entity.
|
||||
*/
|
||||
Uint32 GetColB() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the red color of the managed forcefield entity.
|
||||
*/
|
||||
void SetColR(Uint32 r) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the green color of the managed forcefield entity.
|
||||
*/
|
||||
void SetColG(Uint32 g) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the blue color of the managed forcefield entity.
|
||||
*/
|
||||
void SetColB(Uint32 b) const;
|
||||
};
|
||||
|
||||
|
@ -6,15 +6,20 @@
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQChar CKeybind::s_StrID[SQMOD_KEYBIND_POOL][8];
|
||||
const Int32 CKeybind::Max = SQMOD_KEYBIND_POOL;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const Int32 CKeybind::Max = SQMOD_KEYBIND_POOL;
|
||||
SQInteger CKeybind::Typename(HSQUIRRELVM vm)
|
||||
{
|
||||
static SQChar name[] = _SC("SqKeybind");
|
||||
sq_pushstring(vm, name, sizeof(name));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CKeybind::CKeybind(Int32 id)
|
||||
: m_ID(VALID_ENTITYGETEX(id, SQMOD_KEYBIND_POOL))
|
||||
, m_Tag(VALID_ENTITY(m_ID) ? s_StrID[m_ID] : _SC("-1"))
|
||||
, m_Tag(ToStrF("%d", id))
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
@ -36,108 +41,124 @@ Int32 CKeybind::Cmp(const CKeybind & o) const
|
||||
return -1;
|
||||
}
|
||||
|
||||
CSStr CKeybind::ToString() const
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const String & CKeybind::ToString() const
|
||||
{
|
||||
return VALID_ENTITYEX(m_ID, SQMOD_KEYBIND_POOL) ? s_StrID[m_ID] : _SC("-1");
|
||||
return m_Tag;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr CKeybind::GetTag() const
|
||||
const String & CKeybind::GetTag() const
|
||||
{
|
||||
return m_Tag.c_str();
|
||||
return m_Tag;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CKeybind::SetTag(CSStr tag)
|
||||
{
|
||||
m_Tag.assign(tag);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Object & CKeybind::GetData()
|
||||
{
|
||||
if (Validate())
|
||||
return m_Data;
|
||||
return NullObject();
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return m_Data;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CKeybind::SetData(Object & data)
|
||||
{
|
||||
if (Validate())
|
||||
m_Data = data;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Apply the specified value
|
||||
m_Data = data;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool CKeybind::Destroy(Int32 header, Object & payload)
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
return _Core->DelKeybind(m_ID, header, payload);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool CKeybind::BindEvent(Int32 evid, Object & env, Function & func) const
|
||||
void CKeybind::BindEvent(Int32 evid, Object & env, Function & func) const
|
||||
{
|
||||
if (!Validate())
|
||||
return false;
|
||||
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Obtain the function instance called for this event
|
||||
Function & event = _Core->GetKeybindEvent(m_ID, evid);
|
||||
|
||||
// Is the specified callback function null?
|
||||
if (func.IsNull())
|
||||
event.Release();
|
||||
event.Release(); // Then release the current callback
|
||||
// Assign the specified environment and function
|
||||
else
|
||||
event = Function(env.GetVM(), env, func.GetFunc());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 CKeybind::GetPrimary() const
|
||||
Int32 CKeybind::GetFirst() const
|
||||
{
|
||||
if (Validate())
|
||||
return _Core->GetKeybind(m_ID).mPrimary;
|
||||
return -1;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Core->GetKeybind(m_ID).mFirst;
|
||||
}
|
||||
|
||||
Int32 CKeybind::GetSecondary() const
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 CKeybind::GetSecond() const
|
||||
{
|
||||
if (Validate())
|
||||
return _Core->GetKeybind(m_ID).mSecondary;
|
||||
return -1;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Core->GetKeybind(m_ID).mSecond;
|
||||
}
|
||||
|
||||
Int32 CKeybind::GetAlternative() const
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 CKeybind::GetThird() const
|
||||
{
|
||||
if (Validate())
|
||||
return _Core->GetKeybind(m_ID).mAlternative;
|
||||
return -1;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Core->GetKeybind(m_ID).mThird;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool CKeybind::IsRelease() const
|
||||
{
|
||||
if (Validate())
|
||||
return _Core->GetKeybind(m_ID).mRelease;
|
||||
return false;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Core->GetKeybind(m_ID).mRelease;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static Object & CreateKeybindEx(Int32 slot, bool release, Int32 primary, Int32 secondary,
|
||||
static Object & Keybind_CreateEx(Int32 slot, bool release, Int32 primary, Int32 secondary,
|
||||
Int32 alternative)
|
||||
{
|
||||
return _Core->NewKeybind(slot, release, primary, secondary, alternative,
|
||||
SQMOD_CREATE_DEFAULT, NullObject());
|
||||
}
|
||||
|
||||
static Object & CreateKeybindEx(Int32 slot, bool release, Int32 primary, Int32 secondary,
|
||||
static Object & Keybind_CreateEx(Int32 slot, bool release, Int32 primary, Int32 secondary,
|
||||
Int32 alternative, Int32 header, Object & payload)
|
||||
{
|
||||
return _Core->NewKeybind(slot, release, primary, secondary, alternative, header, payload);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static Object & CreateKeybind(bool release, Int32 primary, Int32 secondary, Int32 alternative)
|
||||
static Object & Keybind_Create(bool release, Int32 primary, Int32 secondary, Int32 alternative)
|
||||
{
|
||||
return _Core->NewKeybind(-1, release, primary, secondary, alternative,
|
||||
SQMOD_CREATE_DEFAULT, NullObject());
|
||||
}
|
||||
|
||||
static Object & CreateKeybind(bool release, Int32 primary, Int32 secondary, Int32 alternative,
|
||||
static Object & Keybind_Create(bool release, Int32 primary, Int32 secondary, Int32 alternative,
|
||||
Int32 header, Object & payload)
|
||||
{
|
||||
return _Core->NewKeybind(-1, release, primary, secondary, alternative, header, payload);
|
||||
@ -148,37 +169,38 @@ void Register_CKeybind(HSQUIRRELVM vm)
|
||||
{
|
||||
RootTable(vm).Bind(_SC("SqKeybind"),
|
||||
Class< CKeybind, NoConstructor< CKeybind > >(vm, _SC("SqKeybind"))
|
||||
/* Metamethods */
|
||||
// Metamethods
|
||||
.Func(_SC("_cmp"), &CKeybind::Cmp)
|
||||
.SquirrelFunc(_SC("_typename"), &CKeybind::Typename)
|
||||
.Func(_SC("_tostring"), &CKeybind::ToString)
|
||||
/* Core Properties */
|
||||
// Static values
|
||||
.SetStaticValue(_SC("MaxID"), CKeybind::Max)
|
||||
// Core Properties
|
||||
.Prop(_SC("ID"), &CKeybind::GetID)
|
||||
.Prop(_SC("Tag"), &CKeybind::GetTag, &CKeybind::SetTag)
|
||||
.Prop(_SC("Data"), &CKeybind::GetData, &CKeybind::SetData)
|
||||
.Prop(_SC("MaxID"), &CKeybind::GetMaxID)
|
||||
.Prop(_SC("Active"), &CKeybind::IsActive)
|
||||
/* Core Functions */
|
||||
// Core Functions
|
||||
.Func(_SC("Bind"), &CKeybind::BindEvent)
|
||||
/* Core Overloads */
|
||||
// Core Overloads
|
||||
.Overload< bool (CKeybind::*)(void) >(_SC("Destroy"), &CKeybind::Destroy)
|
||||
.Overload< bool (CKeybind::*)(Int32) >(_SC("Destroy"), &CKeybind::Destroy)
|
||||
.Overload< bool (CKeybind::*)(Int32, Object &) >(_SC("Destroy"), &CKeybind::Destroy)
|
||||
/* Properties */
|
||||
.Prop(_SC("Primary"), &CKeybind::GetPrimary)
|
||||
.Prop(_SC("Secondary"), &CKeybind::GetSecondary)
|
||||
.Prop(_SC("Alternative"), &CKeybind::GetAlternative)
|
||||
// Properties
|
||||
.Prop(_SC("First"), &CKeybind::GetFirst)
|
||||
.Prop(_SC("Second"), &CKeybind::GetSecond)
|
||||
.Prop(_SC("Third"), &CKeybind::GetThird)
|
||||
.Prop(_SC("Release"), &CKeybind::IsRelease)
|
||||
// Static Overloads
|
||||
.StaticOverload< Object & (*)(Int32, bool, Int32, Int32, Int32) >
|
||||
(_SC("CreateEx"), &Keybind_CreateEx)
|
||||
.StaticOverload< Object & (*)(Int32, bool, Int32, Int32, Int32, Int32, Object &) >
|
||||
(_SC("CreateEx"), &Keybind_CreateEx)
|
||||
.StaticOverload< Object & (*)(bool, Int32, Int32, Int32) >
|
||||
(_SC("Create"), &Keybind_Create)
|
||||
.StaticOverload< Object & (*)(bool, Int32, Int32, Int32, Int32, Object &) >
|
||||
(_SC("Create"), &Keybind_Create)
|
||||
);
|
||||
|
||||
RootTable(vm)
|
||||
.Overload< Object & (*)(Int32, bool, Int32, Int32, Int32) >
|
||||
(_SC("CreateKeybindEx"), &CreateKeybindEx)
|
||||
.Overload< Object & (*)(Int32, bool, Int32, Int32, Int32, Int32, Object &) >
|
||||
(_SC("CreateKeybindEx"), &CreateKeybindEx)
|
||||
.Overload< Object & (*)(bool, Int32, Int32, Int32) >
|
||||
(_SC("CreateKeybind"), &CreateKeybind)
|
||||
.Overload< Object & (*)(bool, Int32, Int32, Int32, Int32, Object &) >
|
||||
(_SC("CreateKeybind"), &CreateKeybind);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
@ -8,7 +8,7 @@
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Manages Keybind instances.
|
||||
* Manages a single keybind entity.
|
||||
*/
|
||||
class CKeybind
|
||||
{
|
||||
@ -17,20 +17,19 @@ class CKeybind
|
||||
|
||||
private:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Cached identifiers for fast integer to string conversion.
|
||||
*/
|
||||
static SQChar s_StrID[SQMOD_KEYBIND_POOL][8];
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Identifier of the managed entity.
|
||||
*/
|
||||
Int32 m_ID;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* User tag and data associated with this instance.
|
||||
* User tag associated with this instance.
|
||||
*/
|
||||
String m_Tag;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* User data associated with this instance.
|
||||
*/
|
||||
Object m_Data;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
@ -38,20 +37,22 @@ private:
|
||||
*/
|
||||
CKeybind(Int32 id);
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Maximum possible number that could represent an identifier for this entity type.
|
||||
*/
|
||||
static const Int32 Max;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor. (disabled)
|
||||
*/
|
||||
CKeybind(const CKeybind &);
|
||||
CKeybind(const CKeybind &) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator. (disabled)
|
||||
* Move constructor. (disabled)
|
||||
*/
|
||||
CKeybind & operator = (const CKeybind &);
|
||||
|
||||
public:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
static const Int32 Max;
|
||||
CKeybind(CKeybind &&) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
@ -59,14 +60,22 @@ public:
|
||||
~CKeybind();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether this instance manages a valid entity.
|
||||
* Copy assignment operator. (disabled)
|
||||
*/
|
||||
bool Validate() const
|
||||
CKeybind & operator = (const CKeybind &) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator. (disabled)
|
||||
*/
|
||||
CKeybind & operator = (CKeybind &&) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether this instance manages a valid entity instance otherwise throw an exception.
|
||||
*/
|
||||
void Validate() const
|
||||
{
|
||||
if (VALID_ENTITY(m_ID))
|
||||
return true;
|
||||
SqThrow("Invalid keybind reference [%s]", m_Tag.c_str());
|
||||
return false;
|
||||
if (INVALID_ENTITY(m_ID))
|
||||
SqThrowF("Invalid keybind reference [%s]", m_Tag.c_str());
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
@ -77,27 +86,33 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const;
|
||||
const String & ToString() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to retrieve the name from instances of this type.
|
||||
*/
|
||||
static SQInteger Typename(HSQUIRRELVM vm);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the identifier of the entity managed by this instance.
|
||||
*/
|
||||
Int32 GetID() const { return m_ID; }
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the maximum possible identifier to an entity of this type.
|
||||
*/
|
||||
Int32 GetMaxID() const { return SQMOD_KEYBIND_POOL; }
|
||||
Int32 GetID() const
|
||||
{
|
||||
return m_ID;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Check whether this instance manages a valid entity.
|
||||
*/
|
||||
bool IsActive() const { return VALID_ENTITY(m_ID); }
|
||||
bool IsActive() const
|
||||
{
|
||||
return VALID_ENTITY(m_ID);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the associated user tag.
|
||||
*/
|
||||
CSStr GetTag() const;
|
||||
const String & GetTag() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the associated user tag.
|
||||
@ -114,18 +129,50 @@ public:
|
||||
*/
|
||||
void SetData(Object & data);
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destroy the managed destroy entity.
|
||||
*/
|
||||
bool Destroy()
|
||||
{
|
||||
return Destroy(0, NullObject());
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destroy the managed destroy entity.
|
||||
*/
|
||||
bool Destroy(Int32 header)
|
||||
{
|
||||
return Destroy(header, NullObject());
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destroy the managed destroy entity.
|
||||
*/
|
||||
bool Destroy(Int32 header, Object & payload);
|
||||
bool Destroy() { return Destroy(0, NullObject()); }
|
||||
bool Destroy(Int32 header) { return Destroy(header, NullObject()); }
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
bool BindEvent(Int32 evid, Object & env, Function & func) const;
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Bind to an event supported by this entity type.
|
||||
*/
|
||||
void BindEvent(Int32 evid, Object & env, Function & func) const;
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
Int32 GetPrimary() const;
|
||||
Int32 GetSecondary() const;
|
||||
Int32 GetAlternative() const;
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the first key code of the managed keybind entity.
|
||||
*/
|
||||
Int32 GetFirst() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the second key code of the managed keybind entity.
|
||||
*/
|
||||
Int32 GetSecond() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the third key code of the managed keybind entity.
|
||||
*/
|
||||
Int32 GetThird() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether the managed keybind entity reacts to key release events.
|
||||
*/
|
||||
bool IsRelease() const;
|
||||
};
|
||||
|
||||
|
@ -13,15 +13,20 @@ Vector3 CObject::s_Vector3;
|
||||
Quaternion CObject::s_Quaternion;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQChar CObject::s_StrID[SQMOD_OBJECT_POOL][8];
|
||||
const Int32 CObject::Max = SQMOD_OBJECT_POOL;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const Int32 CObject::Max = SQMOD_OBJECT_POOL;
|
||||
SQInteger CObject::Typename(HSQUIRRELVM vm)
|
||||
{
|
||||
static SQChar name[] = _SC("SqObject");
|
||||
sq_pushstring(vm, name, sizeof(name));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CObject::CObject(Int32 id)
|
||||
: m_ID(VALID_ENTITYGETEX(id, SQMOD_OBJECT_POOL))
|
||||
, m_Tag(VALID_ENTITY(m_ID) ? s_StrID[m_ID] : _SC("-1"))
|
||||
, m_Tag(ToStrF("%d", id))
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
@ -43,372 +48,517 @@ Int32 CObject::Cmp(const CObject & o) const
|
||||
return -1;
|
||||
}
|
||||
|
||||
CSStr CObject::ToString() const
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const String & CObject::ToString() const
|
||||
{
|
||||
return VALID_ENTITYEX(m_ID, SQMOD_OBJECT_POOL) ? s_StrID[m_ID] : _SC("-1");
|
||||
return m_Tag;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr CObject::GetTag() const
|
||||
const String & CObject::GetTag() const
|
||||
{
|
||||
return m_Tag.c_str();
|
||||
return m_Tag;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CObject::SetTag(CSStr tag)
|
||||
{
|
||||
m_Tag.assign(tag);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Object & CObject::GetData()
|
||||
{
|
||||
if (Validate())
|
||||
return m_Data;
|
||||
return NullObject();
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return m_Data;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CObject::SetData(Object & data)
|
||||
{
|
||||
if (Validate())
|
||||
m_Data = data;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Apply the specified value
|
||||
m_Data = data;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool CObject::Destroy(Int32 header, Object & payload)
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
return _Core->DelObject(m_ID, header, payload);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool CObject::BindEvent(Int32 evid, Object & env, Function & func) const
|
||||
void CObject::BindEvent(Int32 evid, Object & env, Function & func) const
|
||||
{
|
||||
if (!Validate())
|
||||
return false;
|
||||
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Obtain the function instance called for this event
|
||||
Function & event = _Core->GetObjectEvent(m_ID, evid);
|
||||
|
||||
// Is the specified callback function null?
|
||||
if (func.IsNull())
|
||||
event.Release();
|
||||
event.Release(); // Then release the current callback
|
||||
// Assign the specified environment and function
|
||||
else
|
||||
event = Function(env.GetVM(), env, func.GetFunc());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool CObject::IsStreamedFor(CPlayer & player) const
|
||||
{
|
||||
// Is the specified player even valid?
|
||||
if (!player.IsActive())
|
||||
SqThrow("Invalid player argument: null");
|
||||
else if (Validate())
|
||||
return _Func->IsObjectStreamedForPlayer(m_ID, player.GetID());
|
||||
return false;
|
||||
SqThrowF("Invalid player argument: null");
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Func->IsObjectStreamedForPlayer(m_ID, player.GetID());
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 CObject::GetModel() const
|
||||
{
|
||||
if (Validate())
|
||||
return _Func->GetObjectModel(m_ID);
|
||||
return -1;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Func->GetObjectModel(m_ID);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 CObject::GetWorld() const
|
||||
{
|
||||
if (Validate())
|
||||
return _Func->GetObjectWorld(m_ID);
|
||||
return -1;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Func->GetObjectWorld(m_ID);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CObject::SetWorld(Int32 world) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->SetObjectWorld(m_ID, world);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->SetObjectWorld(m_ID, world);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 CObject::GetAlpha() const
|
||||
{
|
||||
if (Validate())
|
||||
return _Func->GetObjectAlpha(m_ID);
|
||||
return -1;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Func->GetObjectAlpha(m_ID);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CObject::SetAlpha(Int32 alpha) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->SetObjectAlpha(m_ID, alpha, 0);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->SetObjectAlpha(m_ID, alpha, 0);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CObject::SetAlphaEx(Int32 alpha, Int32 time) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->SetObjectAlpha(m_ID, alpha, time);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->SetObjectAlpha(m_ID, alpha, time);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CObject::MoveTo(const Vector3 & pos, Int32 time) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->MoveObjectTo(m_ID, pos.x, pos.y, pos.z, time);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->MoveObjectTo(m_ID, pos.x, pos.y, pos.z, time);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CObject::MoveToEx(Float32 x, Float32 y, Float32 z, Int32 time) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->MoveObjectTo(m_ID, x, y, z, time);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->MoveObjectTo(m_ID, x, y, z, time);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CObject::MoveBy(const Vector3 & pos, Int32 time) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->MoveObjectBy(m_ID, pos.x, pos.y, pos.z, time);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->MoveObjectBy(m_ID, pos.x, pos.y, pos.z, time);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CObject::MoveByEx(Float32 x, Float32 y, Float32 z, Int32 time) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->MoveObjectBy(m_ID, x, y, z, time);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->MoveObjectBy(m_ID, x, y, z, time);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const Vector3 & CObject::GetPosition()
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Clear previous position information
|
||||
s_Vector3.Clear();
|
||||
if (Validate())
|
||||
_Func->GetObjectPos(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z);
|
||||
// Query the server for the position values
|
||||
_Func->GetObjectPos(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z);
|
||||
// Return the requested information
|
||||
return s_Vector3;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CObject::SetPosition(const Vector3 & pos) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->SetObjectPos(m_ID, pos.x, pos.y, pos.z);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->SetObjectPos(m_ID, pos.x, pos.y, pos.z);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CObject::SetPositionEx(Float32 x, Float32 y, Float32 z) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->SetObjectPos(m_ID, x, y, z);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->SetObjectPos(m_ID, x, y, z);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CObject::RotateTo(const Quaternion & rot, Int32 time) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->RotObjectTo(m_ID, rot.x, rot.y, rot.z, rot.w, time);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->RotObjectTo(m_ID, rot.x, rot.y, rot.z, rot.w, time);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CObject::RotateToEx(Float32 x, Float32 y, Float32 z, Float32 w, Int32 time) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->RotObjectTo(m_ID, x, y, z, w, time);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->RotObjectTo(m_ID, x, y, z, w, time);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CObject::RotateToEuler(const Vector3 & rot, Int32 time) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->RotObjectToEuler(m_ID, rot.x, rot.y, rot.z, time);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->RotObjectToEuler(m_ID, rot.x, rot.y, rot.z, time);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CObject::RotateToEulerEx(Float32 x, Float32 y, Float32 z, Int32 time) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->RotObjectToEuler(m_ID, x, y, z, time);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->RotObjectToEuler(m_ID, x, y, z, time);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CObject::RotateBy(const Quaternion & rot, Int32 time) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->RotObjectBy(m_ID, rot.x, rot.y, rot.z, rot.w, time);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->RotObjectBy(m_ID, rot.x, rot.y, rot.z, rot.w, time);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CObject::RotateByEx(Float32 x, Float32 y, Float32 z, Float32 w, Int32 time) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->RotObjectBy(m_ID, x, y, z, w, time);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->RotObjectBy(m_ID, x, y, z, w, time);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CObject::RotateByEuler(const Vector3 & rot, Int32 time) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->RotObjectByEuler(m_ID, rot.x, rot.y, rot.z, time);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->RotObjectByEuler(m_ID, rot.x, rot.y, rot.z, time);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CObject::RotateByEulerEx(Float32 x, Float32 y, Float32 z, Int32 time) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->RotObjectByEuler(m_ID, x, y, z, time);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->RotObjectByEuler(m_ID, x, y, z, time);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const Quaternion & CObject::GetRotation()
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Clear previous rotation information
|
||||
s_Quaternion.Clear();
|
||||
if (Validate())
|
||||
_Func->GetObjectRot(m_ID, &s_Quaternion.x, &s_Quaternion.y, &s_Quaternion.z, &s_Quaternion.w);
|
||||
// Query the server for the rotation values
|
||||
_Func->GetObjectRot(m_ID, &s_Quaternion.x, &s_Quaternion.y, &s_Quaternion.z, &s_Quaternion.w);
|
||||
// Return the requested information
|
||||
return s_Quaternion;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const Vector3 & CObject::GetRotationEuler()
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Clear previous rotation information
|
||||
s_Vector3.Clear();
|
||||
if (Validate())
|
||||
_Func->GetObjectRotEuler(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z);
|
||||
// Query the server for the rotation values
|
||||
_Func->GetObjectRotEuler(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z);
|
||||
// Return the requested information
|
||||
return s_Vector3;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool CObject::GetShotReport() const
|
||||
{
|
||||
if (Validate())
|
||||
return _Func->IsObjectShotReport(m_ID);
|
||||
return false;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Func->IsObjectShotReport(m_ID);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CObject::SetShotReport(bool toggle) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->SetObjectShotReport(m_ID, toggle);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->SetObjectShotReport(m_ID, toggle);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool CObject::GetBumpReport() const
|
||||
{
|
||||
if (Validate())
|
||||
return _Func->IsObjectBumpReport(m_ID);
|
||||
return false;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Func->IsObjectBumpReport(m_ID);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CObject::SetBumpReport(bool toggle) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->SetObjectBumpReport(m_ID, toggle);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->SetObjectBumpReport(m_ID, toggle);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Float32 CObject::GetPosX() const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Clear previous position information, if any
|
||||
s_Vector3.x = 0;
|
||||
if (Validate())
|
||||
_Func->GetObjectPos(m_ID, &s_Vector3.x, NULL, NULL);
|
||||
// Query the server for the requested component value
|
||||
_Func->GetObjectPos(m_ID, &s_Vector3.x, NULL, NULL);
|
||||
// Return the requested information
|
||||
return s_Vector3.x;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Float32 CObject::GetPosY() const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Clear previous position information, if any
|
||||
s_Vector3.y = 0;
|
||||
if (Validate())
|
||||
_Func->GetObjectPos(m_ID, NULL, &s_Vector3.y, NULL);
|
||||
// Query the server for the requested component value
|
||||
_Func->GetObjectPos(m_ID, NULL, &s_Vector3.y, NULL);
|
||||
// Return the requested information
|
||||
return s_Vector3.y;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Float32 CObject::GetPosZ() const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Clear previous position information, if any
|
||||
s_Vector3.z = 0;
|
||||
if (Validate())
|
||||
_Func->GetObjectPos(m_ID, NULL, NULL, &s_Vector3.z);
|
||||
// Query the server for the requested component value
|
||||
_Func->GetObjectPos(m_ID, NULL, NULL, &s_Vector3.z);
|
||||
// Return the requested information
|
||||
return s_Vector3.z;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CObject::SetPosX(Float32 x) const
|
||||
{
|
||||
if (Validate())
|
||||
{
|
||||
_Func->GetObjectPos(m_ID, NULL, &s_Vector3.y, &s_Vector3.z);
|
||||
_Func->SetObjectPos(m_ID, x, s_Vector3.y, s_Vector3.z);
|
||||
}
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Retrieve the current values for unchanged components
|
||||
_Func->GetObjectPos(m_ID, NULL, &s_Vector3.y, &s_Vector3.z);
|
||||
// Perform the requested operation
|
||||
_Func->SetObjectPos(m_ID, x, s_Vector3.y, s_Vector3.z);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CObject::SetPosY(Float32 y) const
|
||||
{
|
||||
if (Validate())
|
||||
{
|
||||
_Func->GetObjectPos(m_ID, &s_Vector3.x, NULL, &s_Vector3.z);
|
||||
_Func->SetObjectPos(m_ID, s_Vector3.x, y, s_Vector3.z);
|
||||
}
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Retrieve the current values for unchanged components
|
||||
_Func->GetObjectPos(m_ID, &s_Vector3.x, NULL, &s_Vector3.z);
|
||||
// Perform the requested operation
|
||||
_Func->SetObjectPos(m_ID, s_Vector3.x, y, s_Vector3.z);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CObject::SetPosZ(Float32 z) const
|
||||
{
|
||||
if (Validate())
|
||||
{
|
||||
_Func->GetObjectPos(m_ID, &s_Vector3.x, &s_Vector3.y, NULL);
|
||||
_Func->SetObjectPos(m_ID, s_Vector3.z, s_Vector3.y, z);
|
||||
}
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Retrieve the current values for unchanged components
|
||||
_Func->GetObjectPos(m_ID, &s_Vector3.x, &s_Vector3.y, NULL);
|
||||
// Perform the requested operation
|
||||
_Func->SetObjectPos(m_ID, s_Vector3.z, s_Vector3.y, z);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Float32 CObject::GetRotX() const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Clear previous rotation information, if any
|
||||
s_Quaternion.x = 0;
|
||||
if (Validate())
|
||||
_Func->GetObjectRot(m_ID, &s_Quaternion.x, NULL, NULL, NULL);
|
||||
// Query the server for the requested component value
|
||||
_Func->GetObjectRot(m_ID, &s_Quaternion.x, NULL, NULL, NULL);
|
||||
// Return the requested information
|
||||
return s_Quaternion.x;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Float32 CObject::GetRotY() const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Clear previous rotation information, if any
|
||||
s_Quaternion.y = 0;
|
||||
if (Validate())
|
||||
_Func->GetObjectRot(m_ID, NULL, &s_Quaternion.y, NULL, NULL);
|
||||
// Query the server for the requested component value
|
||||
_Func->GetObjectRot(m_ID, NULL, &s_Quaternion.y, NULL, NULL);
|
||||
// Return the requested information
|
||||
return s_Quaternion.y;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Float32 CObject::GetRotZ() const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Clear previous rotation information, if any
|
||||
s_Quaternion.z = 0;
|
||||
if (Validate())
|
||||
_Func->GetObjectRot(m_ID, NULL, NULL, &s_Quaternion.z, NULL);
|
||||
// Query the server for the requested component value
|
||||
_Func->GetObjectRot(m_ID, NULL, NULL, &s_Quaternion.z, NULL);
|
||||
// Return the requested information
|
||||
return s_Quaternion.z;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Float32 CObject::GetRotW() const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Clear previous rotation information, if any
|
||||
s_Quaternion.w = 0;
|
||||
if (Validate())
|
||||
_Func->GetObjectRot(m_ID, NULL, NULL, NULL, &s_Quaternion.w);
|
||||
// Query the server for the requested component value
|
||||
_Func->GetObjectRot(m_ID, NULL, NULL, NULL, &s_Quaternion.w);
|
||||
// Return the requested information
|
||||
return s_Quaternion.w;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Float32 CObject::GetERotX() const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Clear previous rotation information, if any
|
||||
s_Vector3.x = 0;
|
||||
if (Validate())
|
||||
_Func->GetObjectRotEuler(m_ID, &s_Vector3.x, NULL, NULL);
|
||||
// Query the server for the requested component value
|
||||
_Func->GetObjectRotEuler(m_ID, &s_Vector3.x, NULL, NULL);
|
||||
// Return the requested information
|
||||
return s_Vector3.x;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Float32 CObject::GetERotY() const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Clear previous rotation information, if any
|
||||
s_Vector3.y = 0;
|
||||
if (Validate())
|
||||
_Func->GetObjectRotEuler(m_ID, NULL, &s_Vector3.y, NULL);
|
||||
// Query the server for the requested component value
|
||||
_Func->GetObjectRotEuler(m_ID, NULL, &s_Vector3.y, NULL);
|
||||
// Return the requested information
|
||||
return s_Vector3.y;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Float32 CObject::GetERotZ() const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Clear previous rotation information, if any
|
||||
s_Vector3.z = 0;
|
||||
if (Validate())
|
||||
_Func->GetObjectRotEuler(m_ID, NULL, NULL, &s_Vector3.z);
|
||||
// Query the server for the requested component value
|
||||
_Func->GetObjectRotEuler(m_ID, NULL, NULL, &s_Vector3.z);
|
||||
// Return the requested information
|
||||
return s_Vector3.z;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static Object & CreateObjectEx(Int32 model, Int32 world, Float32 x, Float32 y, Float32 z,
|
||||
static Object & Object_CreateEx(Int32 model, Int32 world, Float32 x, Float32 y, Float32 z,
|
||||
Int32 alpha)
|
||||
{
|
||||
return _Core->NewObject(model, world, x, y, z, alpha, SQMOD_CREATE_DEFAULT, NullObject());
|
||||
}
|
||||
|
||||
static Object & CreateObjectEx(Int32 model, Int32 world, Float32 x, Float32 y, Float32 z,
|
||||
static Object & Object_CreateEx(Int32 model, Int32 world, Float32 x, Float32 y, Float32 z,
|
||||
Int32 alpha, Int32 header, Object & payload)
|
||||
{
|
||||
return _Core->NewObject(model, world, x, y, z, alpha, header, payload);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static Object & CreateObject(Int32 model, Int32 world, const Vector3 & pos, Int32 alpha)
|
||||
static Object & Object_Create(Int32 model, Int32 world, const Vector3 & pos, Int32 alpha)
|
||||
{
|
||||
return _Core->NewObject(model, world, pos.x, pos.y, pos.z, alpha,
|
||||
SQMOD_CREATE_DEFAULT, NullObject());
|
||||
}
|
||||
|
||||
static Object & CreateObject(Int32 model, Int32 world, const Vector3 & pos, Int32 alpha,
|
||||
static Object & Object_Create(Int32 model, Int32 world, const Vector3 & pos, Int32 alpha,
|
||||
Int32 header, Object & payload)
|
||||
{
|
||||
return _Core->NewObject(model, world, pos.x, pos.y, pos.z, alpha, header, payload);
|
||||
@ -419,22 +569,24 @@ void Register_CObject(HSQUIRRELVM vm)
|
||||
{
|
||||
RootTable(vm).Bind(_SC("SqObject"),
|
||||
Class< CObject, NoConstructor< CObject > >(vm, _SC("SqObject"))
|
||||
/* Metamethods */
|
||||
// Metamethods
|
||||
.Func(_SC("_cmp"), &CObject::Cmp)
|
||||
.SquirrelFunc(_SC("_typename"), &CObject::Typename)
|
||||
.Func(_SC("_tostring"), &CObject::ToString)
|
||||
/* Core Properties */
|
||||
// Static values
|
||||
.SetStaticValue(_SC("MaxID"), CObject::Max)
|
||||
// Core Properties
|
||||
.Prop(_SC("ID"), &CObject::GetID)
|
||||
.Prop(_SC("Tag"), &CObject::GetTag, &CObject::SetTag)
|
||||
.Prop(_SC("Data"), &CObject::GetData, &CObject::SetData)
|
||||
.Prop(_SC("MaxID"), &CObject::GetMaxID)
|
||||
.Prop(_SC("Active"), &CObject::IsActive)
|
||||
/* Core Functions */
|
||||
// Core Functions
|
||||
.Func(_SC("Bind"), &CObject::BindEvent)
|
||||
/* Core Overloads */
|
||||
// Core Overloads
|
||||
.Overload< bool (CObject::*)(void) >(_SC("Destroy"), &CObject::Destroy)
|
||||
.Overload< bool (CObject::*)(Int32) >(_SC("Destroy"), &CObject::Destroy)
|
||||
.Overload< bool (CObject::*)(Int32, Object &) >(_SC("Destroy"), &CObject::Destroy)
|
||||
/* Properties */
|
||||
// Properties
|
||||
.Prop(_SC("Model"), &CObject::GetModel)
|
||||
.Prop(_SC("World"), &CObject::GetWorld, &CObject::SetWorld)
|
||||
.Prop(_SC("Alpha"), &CObject::GetAlpha, &CObject::SetAlpha)
|
||||
@ -455,11 +607,11 @@ void Register_CObject(HSQUIRRELVM vm)
|
||||
.Prop(_SC("EX"), &CObject::GetERotX)
|
||||
.Prop(_SC("EY"), &CObject::GetERotY)
|
||||
.Prop(_SC("EZ"), &CObject::GetERotZ)
|
||||
/* Functions */
|
||||
// Functions
|
||||
.Func(_SC("StreamedFor"), &CObject::IsStreamedFor)
|
||||
.Func(_SC("SetAlpha"), &CObject::SetAlphaEx)
|
||||
.Func(_SC("SetPosition"), &CObject::SetPositionEx)
|
||||
/* Overloads */
|
||||
// Overloads
|
||||
.Overload< void (CObject::*)(const Vector3 &, Int32) const >
|
||||
(_SC("MoveTo"), &CObject::MoveTo)
|
||||
.Overload< void (CObject::*)(Float32, Float32, Float32, Int32) const >
|
||||
@ -484,17 +636,16 @@ void Register_CObject(HSQUIRRELVM vm)
|
||||
(_SC("RotateByEuler"), &CObject::RotateByEuler)
|
||||
.Overload< void (CObject::*)(Float32, Float32, Float32, Int32) const >
|
||||
(_SC("RotateByEuler"), &CObject::RotateByEulerEx)
|
||||
// Static Overloads
|
||||
.StaticOverload< Object & (*)(Int32, Int32, Float32, Float32, Float32, Int32) >
|
||||
(_SC("CreateEx"), &Object_CreateEx)
|
||||
.StaticOverload< Object & (*)(Int32, Int32, Float32, Float32, Float32, Int32, Int32, Object &) >
|
||||
(_SC("CreateEx"), &Object_CreateEx)
|
||||
.StaticOverload< Object & (*)(Int32, Int32, const Vector3 &, Int32) >
|
||||
(_SC("Create"), &Object_Create)
|
||||
.StaticOverload< Object & (*)(Int32, Int32, const Vector3 &, Int32, Int32, Object &) >
|
||||
(_SC("Create"), &Object_Create)
|
||||
);
|
||||
|
||||
RootTable(vm)
|
||||
.Overload< Object & (*)(Int32, Int32, Float32, Float32, Float32, Int32) >
|
||||
(_SC("CreateObjectEx"), &CreateObjectEx)
|
||||
.Overload< Object & (*)(Int32, Int32, Float32, Float32, Float32, Int32, Int32, Object &) >
|
||||
(_SC("CreateObjectEx"), &CreateObjectEx)
|
||||
.Overload< Object & (*)(Int32, Int32, const Vector3 &, Int32) >
|
||||
(_SC("CreateObject"), &CreateObject)
|
||||
.Overload< Object & (*)(Int32, Int32, const Vector3 &, Int32, Int32, Object &) >
|
||||
(_SC("CreateObject"), &CreateObject);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
||||
} // Namespace:: SqMod
|
||||
|
@ -8,7 +8,7 @@
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Manages Object instances.
|
||||
* Manages a single object entity.
|
||||
*/
|
||||
class CObject
|
||||
{
|
||||
@ -21,20 +21,19 @@ private:
|
||||
static Vector3 s_Vector3;
|
||||
static Quaternion s_Quaternion;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Cached identifiers for fast integer to string conversion.
|
||||
*/
|
||||
static SQChar s_StrID[SQMOD_OBJECT_POOL][8];
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Identifier of the managed entity.
|
||||
*/
|
||||
Int32 m_ID;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* User tag and data associated with this instance.
|
||||
* User tag associated with this instance.
|
||||
*/
|
||||
String m_Tag;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* User data associated with this instance.
|
||||
*/
|
||||
Object m_Data;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
@ -42,20 +41,22 @@ private:
|
||||
*/
|
||||
CObject(Int32 id);
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Maximum possible number that could represent an identifier for this entity type.
|
||||
*/
|
||||
static const Int32 Max;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor. (disabled)
|
||||
*/
|
||||
CObject(const CObject &);
|
||||
CObject(const CObject &) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator. (disabled)
|
||||
* Move constructor. (disabled)
|
||||
*/
|
||||
CObject & operator = (const CObject &);
|
||||
|
||||
public:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
static const Int32 Max;
|
||||
CObject(CObject &&) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
@ -63,14 +64,22 @@ public:
|
||||
~CObject();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether this instance manages a valid entity.
|
||||
* Copy assignment operator. (disabled)
|
||||
*/
|
||||
bool Validate() const
|
||||
CObject & operator = (const CObject &) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator. (disabled)
|
||||
*/
|
||||
CObject & operator = (CObject &&) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether this instance manages a valid entity instance otherwise throw an exception.
|
||||
*/
|
||||
void Validate() const
|
||||
{
|
||||
if (VALID_ENTITY(m_ID))
|
||||
return true;
|
||||
SqThrow("Invalid object reference [%s]", m_Tag.c_str());
|
||||
return false;
|
||||
if (INVALID_ENTITY(m_ID))
|
||||
SqThrowF("Invalid object reference [%s]", m_Tag.c_str());
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
@ -81,27 +90,33 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const;
|
||||
const String & ToString() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to retrieve the name from instances of this type.
|
||||
*/
|
||||
static SQInteger Typename(HSQUIRRELVM vm);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the identifier of the entity managed by this instance.
|
||||
*/
|
||||
Int32 GetID() const { return m_ID; }
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the maximum possible identifier to an entity of this type.
|
||||
*/
|
||||
Int32 GetMaxID() const { return SQMOD_OBJECT_POOL; }
|
||||
Int32 GetID() const
|
||||
{
|
||||
return m_ID;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Check whether this instance manages a valid entity.
|
||||
*/
|
||||
bool IsActive() const { return VALID_ENTITY(m_ID); }
|
||||
bool IsActive() const
|
||||
{
|
||||
return VALID_ENTITY(m_ID);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the associated user tag.
|
||||
*/
|
||||
CSStr GetTag() const;
|
||||
const String & GetTag() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the associated user tag.
|
||||
@ -118,59 +133,235 @@ public:
|
||||
*/
|
||||
void SetData(Object & data);
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destroy the managed object entity.
|
||||
*/
|
||||
bool Destroy()
|
||||
{
|
||||
return Destroy(0, NullObject());
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destroy the managed object entity.
|
||||
*/
|
||||
bool Destroy(Int32 header)
|
||||
{
|
||||
return Destroy(header, NullObject());
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destroy the managed object entity.
|
||||
*/
|
||||
bool Destroy(Int32 header, Object & payload);
|
||||
bool Destroy() { return Destroy(0, NullObject()); }
|
||||
bool Destroy(Int32 header) { return Destroy(header, NullObject()); }
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
bool BindEvent(Int32 evid, Object & env, Function & func) const;
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Bind to an event supported by this entity type.
|
||||
*/
|
||||
void BindEvent(Int32 evid, Object & env, Function & func) const;
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See if the managed object entity is streamed for the specified player.
|
||||
*/
|
||||
bool IsStreamedFor(CPlayer & player) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the model of the managed object entity.
|
||||
*/
|
||||
Int32 GetModel() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the world in which the managed object entity exists.
|
||||
*/
|
||||
Int32 GetWorld() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the world in which the managed object entity exists.
|
||||
*/
|
||||
void SetWorld(Int32 world) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the alpha of the managed object entity.
|
||||
*/
|
||||
Int32 GetAlpha() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the alpha of the managed object entity.
|
||||
*/
|
||||
void SetAlpha(Int32 alpha) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the alpha of the managed object entity over the specified time.
|
||||
*/
|
||||
void SetAlphaEx(Int32 alpha, Int32 time) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move the managed object entity to the specified position over the specified time.
|
||||
*/
|
||||
void MoveTo(const Vector3 & pos, Int32 time) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move the managed object entity to the specified position over the specified time.
|
||||
*/
|
||||
void MoveToEx(Float32 x, Float32 y, Float32 z, Int32 time) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move the managed object entity by the specified position over the specified time.
|
||||
*/
|
||||
void MoveBy(const Vector3 & pos, Int32 time) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move the managed object entity by the specified position over the specified time.
|
||||
*/
|
||||
void MoveByEx(Float32 x, Float32 y, Float32 z, Int32 time) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the position of the managed object entity.
|
||||
*/
|
||||
const Vector3 & GetPosition();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the position of the managed object entity.
|
||||
*/
|
||||
void SetPosition(const Vector3 & pos) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the position of the managed object entity.
|
||||
*/
|
||||
void SetPositionEx(Float32 x, Float32 y, Float32 z) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Rotate the managed object entity to the specified rotation over the specified time.
|
||||
*/
|
||||
void RotateTo(const Quaternion & rot, Int32 time) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Rotate the managed object entity to the specified rotation over the specified time.
|
||||
*/
|
||||
void RotateToEx(Float32 x, Float32 y, Float32 z, Float32 w, Int32 time) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Rotate the managed object entity to the specified euler rotation over the specified time.
|
||||
*/
|
||||
void RotateToEuler(const Vector3 & rot, Int32 time) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Rotate the managed object entity to the specified euler rotation over the specified time.
|
||||
*/
|
||||
void RotateToEulerEx(Float32 x, Float32 y, Float32 z, Int32 time) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Rotate the managed object entity by the specified rotation over the specified time.
|
||||
*/
|
||||
void RotateBy(const Quaternion & rot, Int32 time) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Rotate the managed object entity by the specified rotation over the specified time.
|
||||
*/
|
||||
void RotateByEx(Float32 x, Float32 y, Float32 z, Float32 w, Int32 time) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Rotate the managed object entity by the specified euler rotation over the specified time.
|
||||
*/
|
||||
void RotateByEuler(const Vector3 & rot, Int32 time) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Rotate the managed object entity by the specified euler rotation over the specified time.
|
||||
*/
|
||||
void RotateByEulerEx(Float32 x, Float32 y, Float32 z, Int32 time) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the rotation of the managed object entity.
|
||||
*/
|
||||
const Quaternion & GetRotation();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the euler rotation of the managed object entity.
|
||||
*/
|
||||
const Vector3 & GetRotationEuler();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether the managed object entity reports gunshots.
|
||||
*/
|
||||
bool GetShotReport() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Set whether the managed object entity reports gunshots.
|
||||
*/
|
||||
void SetShotReport(bool toggle) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether the managed object entity reports player bumps.
|
||||
*/
|
||||
bool GetBumpReport() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Set whether the managed object entity reports player bumps.
|
||||
*/
|
||||
void SetBumpReport(bool toggle) const;
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the position on the x axis of the managed object entity.
|
||||
*/
|
||||
Float32 GetPosX() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the position on the y axis of the managed object entity.
|
||||
*/
|
||||
Float32 GetPosY() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the position on the z axis of the managed object entity.
|
||||
*/
|
||||
Float32 GetPosZ() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the position on the x axis of the managed object entity.
|
||||
*/
|
||||
void SetPosX(Float32 x) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the position on the y axis of the managed object entity.
|
||||
*/
|
||||
void SetPosY(Float32 y) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the position on the z axis of the managed object entity.
|
||||
*/
|
||||
void SetPosZ(Float32 z) const;
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the rotation on the x axis of the managed object entity.
|
||||
*/
|
||||
Float32 GetRotX() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the rotation on the y axis of the managed object entity.
|
||||
*/
|
||||
Float32 GetRotY() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the rotation on the z axis of the managed object entity.
|
||||
*/
|
||||
Float32 GetRotZ() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the rotation amount of the managed object entity.
|
||||
*/
|
||||
Float32 GetRotW() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the euler rotation on the x axis of the managed object entity.
|
||||
*/
|
||||
Float32 GetERotX() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the euler rotation on the y axis of the managed object entity.
|
||||
*/
|
||||
Float32 GetERotY() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the euler rotation on the z axis of the managed object entity.
|
||||
*/
|
||||
Float32 GetERotZ() const;
|
||||
};
|
||||
|
||||
|
@ -11,15 +11,20 @@ namespace SqMod {
|
||||
Vector3 CPickup::s_Vector3;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQChar CPickup::s_StrID[SQMOD_PICKUP_POOL][8];
|
||||
const Int32 CPickup::Max = SQMOD_PICKUP_POOL;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const Int32 CPickup::Max = SQMOD_PICKUP_POOL;
|
||||
SQInteger CPickup::Typename(HSQUIRRELVM vm)
|
||||
{
|
||||
static SQChar name[] = _SC("SqPickup");
|
||||
sq_pushstring(vm, name, sizeof(name));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CPickup::CPickup(Int32 id)
|
||||
: m_ID(VALID_ENTITYGETEX(id, SQMOD_PICKUP_POOL))
|
||||
, m_Tag(VALID_ENTITY(m_ID) ? s_StrID[m_ID] : _SC("-1"))
|
||||
, m_Tag(ToStrF("%d", id))
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
@ -41,221 +46,289 @@ Int32 CPickup::Cmp(const CPickup & o) const
|
||||
return -1;
|
||||
}
|
||||
|
||||
CSStr CPickup::ToString() const
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const String & CPickup::ToString() const
|
||||
{
|
||||
return VALID_ENTITYEX(m_ID, SQMOD_PICKUP_POOL) ? s_StrID[m_ID] : _SC("-1");
|
||||
return m_Tag;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr CPickup::GetTag() const
|
||||
const String & CPickup::GetTag() const
|
||||
{
|
||||
return m_Tag.c_str();
|
||||
return m_Tag;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CPickup::SetTag(CSStr tag)
|
||||
{
|
||||
m_Tag.assign(tag);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Object & CPickup::GetData()
|
||||
{
|
||||
if (Validate())
|
||||
return m_Data;
|
||||
return NullObject();
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return m_Data;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CPickup::SetData(Object & data)
|
||||
{
|
||||
if (Validate())
|
||||
m_Data = data;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Apply the specified value
|
||||
m_Data = data;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool CPickup::Destroy(Int32 header, Object & payload)
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
return _Core->DelPickup(m_ID, header, payload);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool CPickup::BindEvent(Int32 evid, Object & env, Function & func) const
|
||||
void CPickup::BindEvent(Int32 evid, Object & env, Function & func) const
|
||||
{
|
||||
if (!Validate())
|
||||
return false;
|
||||
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Obtain the function instance called for this event
|
||||
Function & event = _Core->GetPickupEvent(m_ID, evid);
|
||||
|
||||
// Is the specified callback function null?
|
||||
if (func.IsNull())
|
||||
event.Release();
|
||||
event.Release(); // Then release the current callback
|
||||
// Assign the specified environment and function
|
||||
else
|
||||
event = Function(env.GetVM(), env, func.GetFunc());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool CPickup::IsStreamedFor(CPlayer & player) const
|
||||
{
|
||||
// Is the specified player even valid?
|
||||
if (!player.IsActive())
|
||||
SqThrow("Invalid player argument: null");
|
||||
else if (Validate())
|
||||
return _Func->IsPickupStreamedForPlayer(m_ID, player.GetID());
|
||||
return false;
|
||||
SqThrowF("Invalid player argument: null");
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Func->IsPickupStreamedForPlayer(m_ID, player.GetID());
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 CPickup::GetModel() const
|
||||
{
|
||||
if (Validate())
|
||||
return _Func->PickupGetModel(m_ID);
|
||||
return -1;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Func->PickupGetModel(m_ID);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 CPickup::GetWorld() const
|
||||
{
|
||||
if (Validate())
|
||||
return _Func->GetPickupWorld(m_ID);
|
||||
return -1;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Func->GetPickupWorld(m_ID);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CPickup::SetWorld(Int32 world) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->SetPickupWorld(m_ID, world);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->SetPickupWorld(m_ID, world);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 CPickup::GetAlpha() const
|
||||
{
|
||||
if (Validate())
|
||||
return _Func->GetVehicleModel(m_ID);
|
||||
return -1;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Func->GetVehicleModel(m_ID);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CPickup::SetAlpha(Int32 alpha) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->PickupSetAlpha(m_ID, alpha);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->PickupSetAlpha(m_ID, alpha);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
bool CPickup::GetAutomatic() const
|
||||
{
|
||||
if (Validate())
|
||||
return _Func->PickupIsAutomatic(m_ID);
|
||||
return false;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Func->PickupIsAutomatic(m_ID);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CPickup::SetAutomatic(bool toggle) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->PickupSetAutomatic(m_ID, toggle);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->PickupSetAutomatic(m_ID, toggle);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 CPickup::GetAutoTimer() const
|
||||
{
|
||||
if (Validate())
|
||||
return _Func->GetPickupAutoTimer(m_ID);
|
||||
return -1;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Func->GetPickupAutoTimer(m_ID);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CPickup::SetAutoTimer(Int32 timer) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->SetPickupAutoTimer(m_ID, timer);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->SetPickupAutoTimer(m_ID, timer);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CPickup::Refresh() const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->PickupRefresh(m_ID);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->PickupRefresh(m_ID);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const Vector3 & CPickup::GetPosition()
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Clear previous position information, if any
|
||||
s_Vector3.Clear();
|
||||
if (Validate())
|
||||
_Func->PickupGetPos(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z);
|
||||
// Query the server for the position values
|
||||
_Func->PickupGetPos(m_ID, &s_Vector3.x, &s_Vector3.y, &s_Vector3.z);
|
||||
// Return the requested information
|
||||
return s_Vector3;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CPickup::SetPosition(const Vector3 & pos) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->PickupSetPos(m_ID, pos.x, pos.y, pos.z);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->PickupSetPos(m_ID, pos.x, pos.y, pos.z);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CPickup::SetPositionEx(Float32 x, Float32 y, Float32 z) const
|
||||
{
|
||||
if (Validate())
|
||||
_Func->PickupSetPos(m_ID, x, y, z);
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Perform the requested operation
|
||||
_Func->PickupSetPos(m_ID, x, y, z);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Int32 CPickup::GetQuantity() const
|
||||
{
|
||||
if (Validate())
|
||||
return _Func->PickupGetQuantity(m_ID);
|
||||
return -1;
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Return the requested information
|
||||
return _Func->PickupGetQuantity(m_ID);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Float32 CPickup::GetPosX() const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Clear previous position information, if any
|
||||
s_Vector3.x = 0;
|
||||
if (Validate())
|
||||
_Func->PickupGetPos(m_ID, &s_Vector3.x, NULL, NULL);
|
||||
// Query the server for the requested component value
|
||||
_Func->PickupGetPos(m_ID, &s_Vector3.x, NULL, NULL);
|
||||
// Return the requested information
|
||||
return s_Vector3.x;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Float32 CPickup::GetPosY() const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Clear previous position information, if any
|
||||
s_Vector3.y = 0;
|
||||
if (Validate())
|
||||
_Func->PickupGetPos(m_ID, NULL, &s_Vector3.y, NULL);
|
||||
// Query the server for the requested component value
|
||||
_Func->PickupGetPos(m_ID, NULL, &s_Vector3.y, NULL);
|
||||
// Return the requested information
|
||||
return s_Vector3.y;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Float32 CPickup::GetPosZ() const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Clear previous position information, if any
|
||||
s_Vector3.z = 0;
|
||||
if (Validate())
|
||||
_Func->PickupGetPos(m_ID, NULL, NULL, &s_Vector3.z);
|
||||
// Query the server for the requested component value
|
||||
_Func->PickupGetPos(m_ID, NULL, NULL, &s_Vector3.z);
|
||||
// Return the requested information
|
||||
return s_Vector3.z;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CPickup::SetPosX(Float32 x) const
|
||||
{
|
||||
if (Validate())
|
||||
{
|
||||
_Func->PickupGetPos(m_ID, NULL, &s_Vector3.y, &s_Vector3.z);
|
||||
_Func->PickupSetPos(m_ID, x, s_Vector3.y, s_Vector3.z);
|
||||
}
|
||||
}
|
||||
|
||||
void CPickup::SetPosY(Float32 y) const
|
||||
{
|
||||
if (Validate())
|
||||
{
|
||||
_Func->PickupGetPos(m_ID, &s_Vector3.x, NULL, &s_Vector3.z);
|
||||
_Func->PickupSetPos(m_ID, s_Vector3.x, y, s_Vector3.z);
|
||||
}
|
||||
}
|
||||
|
||||
void CPickup::SetPosZ(Float32 z) const
|
||||
{
|
||||
if (Validate())
|
||||
{
|
||||
_Func->PickupGetPos(m_ID, &s_Vector3.x, &s_Vector3.y, NULL);
|
||||
_Func->PickupSetPos(m_ID, s_Vector3.z, s_Vector3.y, z);
|
||||
}
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Retrieve the current values for unchanged components
|
||||
_Func->PickupGetPos(m_ID, NULL, &s_Vector3.y, &s_Vector3.z);
|
||||
// Perform the requested operation
|
||||
_Func->PickupSetPos(m_ID, x, s_Vector3.y, s_Vector3.z);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static Object & CreatePickupEx(Int32 model, Int32 world, Int32 quantity,
|
||||
void CPickup::SetPosY(Float32 y) const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Retrieve the current values for unchanged components
|
||||
_Func->PickupGetPos(m_ID, &s_Vector3.x, NULL, &s_Vector3.z);
|
||||
// Perform the requested operation
|
||||
_Func->PickupSetPos(m_ID, s_Vector3.x, y, s_Vector3.z);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void CPickup::SetPosZ(Float32 z) const
|
||||
{
|
||||
// Validate the managed identifier
|
||||
Validate();
|
||||
// Retrieve the current values for unchanged components
|
||||
_Func->PickupGetPos(m_ID, &s_Vector3.x, &s_Vector3.y, NULL);
|
||||
// Perform the requested operation
|
||||
_Func->PickupSetPos(m_ID, s_Vector3.z, s_Vector3.y, z);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static Object & Pickup_CreateEx(Int32 model, Int32 world, Int32 quantity,
|
||||
Float32 x, Float32 y, Float32 z, Int32 alpha, bool automatic)
|
||||
{
|
||||
return _Core->NewPickup(model, world, quantity, x, y, z, alpha, automatic,
|
||||
SQMOD_CREATE_DEFAULT, NullObject());
|
||||
}
|
||||
|
||||
static Object & CreatePickupEx(Int32 model, Int32 world, Int32 quantity,
|
||||
static Object & Pickup_CreateEx(Int32 model, Int32 world, Int32 quantity,
|
||||
Float32 x, Float32 y, Float32 z, Int32 alpha, bool automatic,
|
||||
Int32 header, Object & payload)
|
||||
{
|
||||
@ -263,14 +336,14 @@ static Object & CreatePickupEx(Int32 model, Int32 world, Int32 quantity,
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static Object & CreatePickup(Int32 model, Int32 world, Int32 quantity, const Vector3 & pos,
|
||||
static Object & Pickup_Create(Int32 model, Int32 world, Int32 quantity, const Vector3 & pos,
|
||||
Int32 alpha, bool automatic)
|
||||
{
|
||||
return _Core->NewPickup(model, world, quantity, pos.x, pos.y, pos.z, alpha, automatic,
|
||||
SQMOD_CREATE_DEFAULT, NullObject());
|
||||
}
|
||||
|
||||
static Object & CreatePickup(Int32 model, Int32 world, Int32 quantity, const Vector3 & pos,
|
||||
static Object & Pickup_Create(Int32 model, Int32 world, Int32 quantity, const Vector3 & pos,
|
||||
Int32 alpha, bool automatic, Int32 header, Object & payload)
|
||||
{
|
||||
return _Core->NewPickup(model, world, quantity, pos.x, pos.y, pos.z, alpha, automatic,
|
||||
@ -282,22 +355,24 @@ void Register_CPickup(HSQUIRRELVM vm)
|
||||
{
|
||||
RootTable(vm).Bind(_SC("SqPickup"),
|
||||
Class< CPickup, NoConstructor< CPickup > >(vm, _SC("SqPickup"))
|
||||
/* Metamethods */
|
||||
// Metamethods
|
||||
.Func(_SC("_cmp"), &CPickup::Cmp)
|
||||
.SquirrelFunc(_SC("_typename"), &CPickup::Typename)
|
||||
.Func(_SC("_tostring"), &CPickup::ToString)
|
||||
/* Core Properties */
|
||||
// Static values
|
||||
.SetStaticValue(_SC("MaxID"), CPickup::Max)
|
||||
// Core Properties
|
||||
.Prop(_SC("ID"), &CPickup::GetID)
|
||||
.Prop(_SC("Tag"), &CPickup::GetTag, &CPickup::SetTag)
|
||||
.Prop(_SC("Data"), &CPickup::GetData, &CPickup::SetData)
|
||||
.Prop(_SC("MaxID"), &CPickup::GetMaxID)
|
||||
.Prop(_SC("Active"), &CPickup::IsActive)
|
||||
/* Core Functions */
|
||||
// Core Functions
|
||||
.Func(_SC("Bind"), &CPickup::BindEvent)
|
||||
/* Core Overloads */
|
||||
// Core Overloads
|
||||
.Overload< bool (CPickup::*)(void) >(_SC("Destroy"), &CPickup::Destroy)
|
||||
.Overload< bool (CPickup::*)(Int32) >(_SC("Destroy"), &CPickup::Destroy)
|
||||
.Overload< bool (CPickup::*)(Int32, Object &) >(_SC("Destroy"), &CPickup::Destroy)
|
||||
/* Properties */
|
||||
// Properties
|
||||
.Prop(_SC("Model"), &CPickup::GetModel)
|
||||
.Prop(_SC("World"), &CPickup::GetWorld, &CPickup::SetWorld)
|
||||
.Prop(_SC("Alpha"), &CPickup::GetAlpha, &CPickup::SetAlpha)
|
||||
@ -311,22 +386,21 @@ void Register_CPickup(HSQUIRRELVM vm)
|
||||
.Prop(_SC("X"), &CPickup::GetPosX, &CPickup::SetPosX)
|
||||
.Prop(_SC("Y"), &CPickup::GetPosY, &CPickup::SetPosY)
|
||||
.Prop(_SC("Z"), &CPickup::GetPosZ, &CPickup::SetPosZ)
|
||||
/* Functions */
|
||||
// Functions
|
||||
.Func(_SC("StreamedFor"), &CPickup::IsStreamedFor)
|
||||
.Func(_SC("Refresh"), &CPickup::Refresh)
|
||||
.Func(_SC("SetPos"), &CPickup::SetPositionEx)
|
||||
.Func(_SC("SetPosition"), &CPickup::SetPositionEx)
|
||||
// Static Overloads
|
||||
.StaticOverload< Object & (*)(Int32, Int32, Int32, Float32, Float32, Float32, Int32, bool) >
|
||||
(_SC("CreateEx"), &Pickup_CreateEx)
|
||||
.StaticOverload< Object & (*)(Int32, Int32, Int32, Float32, Float32, Float32, Int32, bool, Int32, Object &) >
|
||||
(_SC("CreateEx"), &Pickup_CreateEx)
|
||||
.StaticOverload< Object & (*)(Int32, Int32, Int32, const Vector3 &, Int32, bool) >
|
||||
(_SC("Create"), &Pickup_Create)
|
||||
.StaticOverload< Object & (*)(Int32, Int32, Int32, const Vector3 &, Int32, bool, Int32, Object &) >
|
||||
(_SC("Create"), &Pickup_Create)
|
||||
);
|
||||
|
||||
RootTable(vm)
|
||||
.Overload< Object & (*)(Int32, Int32, Int32, Float32, Float32, Float32, Int32, bool) >
|
||||
(_SC("CreatePickupEx"), &CreatePickupEx)
|
||||
.Overload< Object & (*)(Int32, Int32, Int32, Float32, Float32, Float32, Int32, bool, Int32, Object &) >
|
||||
(_SC("CreatePickupEx"), &CreatePickupEx)
|
||||
.Overload< Object & (*)(Int32, Int32, Int32, const Vector3 &, Int32, bool) >
|
||||
(_SC("CreatePickup"), &CreatePickup)
|
||||
.Overload< Object & (*)(Int32, Int32, Int32, const Vector3 &, Int32, bool, Int32, Object &) >
|
||||
(_SC("CreatePickup"), &CreatePickup);
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
@ -8,7 +8,7 @@
|
||||
namespace SqMod {
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
* Manages Pickup instances.
|
||||
* Manages a single pickup entity.
|
||||
*/
|
||||
class CPickup
|
||||
{
|
||||
@ -20,20 +20,19 @@ private:
|
||||
// --------------------------------------------------------------------------------------------
|
||||
static Vector3 s_Vector3;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Cached identifiers for fast integer to string conversion.
|
||||
*/
|
||||
static SQChar s_StrID[SQMOD_PICKUP_POOL][8];
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Identifier of the managed entity.
|
||||
*/
|
||||
Int32 m_ID;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* User tag and data associated with this instance.
|
||||
* User tag associated with this instance.
|
||||
*/
|
||||
String m_Tag;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* User data associated with this instance.
|
||||
*/
|
||||
Object m_Data;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
@ -41,20 +40,22 @@ private:
|
||||
*/
|
||||
CPickup(Int32 id);
|
||||
|
||||
public:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Maximum possible number that could represent an identifier for this entity type.
|
||||
*/
|
||||
static const Int32 Max;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy constructor. (disabled)
|
||||
*/
|
||||
CPickup(const CPickup &);
|
||||
CPickup(const CPickup &) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copy assignment operator. (disabled)
|
||||
* Move constructor. (disabled)
|
||||
*/
|
||||
CPickup & operator = (const CPickup &);
|
||||
|
||||
public:
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
static const Int32 Max;
|
||||
CPickup(CPickup &&) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destructor.
|
||||
@ -62,14 +63,22 @@ public:
|
||||
~CPickup();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether this instance manages a valid entity.
|
||||
* Copy assignment operator. (disabled)
|
||||
*/
|
||||
bool Validate() const
|
||||
CPickup & operator = (const CPickup &) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Move assignment operator. (disabled)
|
||||
*/
|
||||
CPickup & operator = (CPickup &&) = delete;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether this instance manages a valid entity instance otherwise throw an exception.
|
||||
*/
|
||||
void Validate() const
|
||||
{
|
||||
if (VALID_ENTITY(m_ID))
|
||||
return true;
|
||||
SqThrow("Invalid pickup reference [%s]", m_Tag.c_str());
|
||||
return false;
|
||||
if (INVALID_ENTITY(m_ID))
|
||||
SqThrowF("Invalid pickup reference [%s]", m_Tag.c_str());
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
@ -80,27 +89,33 @@ public:
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to convert an instance of this type to a string.
|
||||
*/
|
||||
CSStr ToString() const;
|
||||
const String & ToString() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Used by the script engine to retrieve the name from instances of this type.
|
||||
*/
|
||||
static SQInteger Typename(HSQUIRRELVM vm);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the identifier of the entity managed by this instance.
|
||||
*/
|
||||
Int32 GetID() const { return m_ID; }
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the maximum possible identifier to an entity of this type.
|
||||
*/
|
||||
Int32 GetMaxID() const { return SQMOD_PICKUP_POOL; }
|
||||
Int32 GetID() const
|
||||
{
|
||||
return m_ID;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Check whether this instance manages a valid entity.
|
||||
*/
|
||||
bool IsActive() const { return VALID_ENTITY(m_ID); }
|
||||
bool IsActive() const
|
||||
{
|
||||
return VALID_ENTITY(m_ID);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the associated user tag.
|
||||
*/
|
||||
CSStr GetTag() const;
|
||||
const String & GetTag() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the associated user tag.
|
||||
@ -117,37 +132,135 @@ public:
|
||||
*/
|
||||
void SetData(Object & data);
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destroy the managed pickup entity.
|
||||
*/
|
||||
bool Destroy()
|
||||
{
|
||||
return Destroy(0, NullObject());
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destroy the managed pickup entity.
|
||||
*/
|
||||
bool Destroy(Int32 header)
|
||||
{
|
||||
return Destroy(header, NullObject());
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Destroy the managed pickup entity.
|
||||
*/
|
||||
bool Destroy(Int32 header, Object & payload);
|
||||
bool Destroy() { return Destroy(0, NullObject()); }
|
||||
bool Destroy(Int32 header) { return Destroy(header, NullObject()); }
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
bool BindEvent(Int32 evid, Object & env, Function & func) const;
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Bind to an event supported by this entity type.
|
||||
*/
|
||||
void BindEvent(Int32 evid, Object & env, Function & func) const;
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See if the managed pickup entity is streamed for the specified player.
|
||||
*/
|
||||
bool IsStreamedFor(CPlayer & player) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the model of the managed pickup entity.
|
||||
*/
|
||||
Int32 GetModel() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the world in which the managed pickup entity exists.
|
||||
*/
|
||||
Int32 GetWorld() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Mpdify the world in which the managed pickup entity exists.
|
||||
*/
|
||||
void SetWorld(Int32 world) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the alpha of the managed pickup entity.
|
||||
*/
|
||||
Int32 GetAlpha() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Mpdify the alpha of the managed pickup entity.
|
||||
*/
|
||||
void SetAlpha(Int32 alpha) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* See whether the managed pickup entity is automatic.
|
||||
*/
|
||||
bool GetAutomatic() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Set whether the managed pickup entity is automatic.
|
||||
*/
|
||||
void SetAutomatic(bool toggle) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the automatic timer of the managed pickup entity.
|
||||
*/
|
||||
Int32 GetAutoTimer() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Mpdify the automatic timer of the managed pickup entity.
|
||||
*/
|
||||
void SetAutoTimer(Int32 timer) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Refresh the managed pickup entity.
|
||||
*/
|
||||
void Refresh() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the position of the managed pickup entity.
|
||||
*/
|
||||
const Vector3 & GetPosition();
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Mpdify the position of the managed pickup entity.
|
||||
*/
|
||||
void SetPosition(const Vector3 & pos) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Mpdify the position of the managed pickup entity.
|
||||
*/
|
||||
void SetPositionEx(Float32 x, Float32 y, Float32 z) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the quantity of the managed pickup entity.
|
||||
*/
|
||||
Int32 GetQuantity() const;
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the position on the x axis of the managed pickup entity.
|
||||
*/
|
||||
Float32 GetPosX() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the position on the y axis of the managed pickup entity.
|
||||
*/
|
||||
Float32 GetPosY() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Retrieve the position on the z axis of the managed pickup entity.
|
||||
*/
|
||||
Float32 GetPosZ() const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the position on the x axis of the managed pickup entity.
|
||||
*/
|
||||
void SetPosX(Float32 x) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the position on the y axis of the managed pickup entity.
|
||||
*/
|
||||
void SetPosY(Float32 y) const;
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Modify the position on the z axis of the managed pickup entity.
|
||||
*/
|
||||
void SetPosZ(Float32 z) const;
|
||||
};
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user