diff --git a/default_scripts_install.sh b/default_scripts_install.sh new file mode 100755 index 0000000000..11751167e6 --- /dev/null +++ b/default_scripts_install.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env sh + +# Remove old Gamescope default configs and add our own. +mkdir -p "${DESTDIR}/${MESON_INSTALL_PREFIX}/share/gamescope" +rm -rf "${DESTDIR}/${MESON_INSTALL_PREFIX}/share/gamescope/scripts" || true +cp -r "${MESON_SOURCE_ROOT}/scripts" "${DESTDIR}/${MESON_INSTALL_PREFIX}/share/gamescope/scripts" diff --git a/meson.build b/meson.build index b562ec3512..24c9c777ef 100644 --- a/meson.build +++ b/meson.build @@ -94,3 +94,6 @@ endif if get_option('enable_gamescope') subdir('src') endif + +# Handle default script/config stuff +meson.add_install_script('default_scripts_install.sh') diff --git a/scripts/00-gamescope/common/inspect.lua b/scripts/00-gamescope/common/inspect.lua new file mode 100644 index 0000000000..774c4c55a1 --- /dev/null +++ b/scripts/00-gamescope/common/inspect.lua @@ -0,0 +1,359 @@ +-- Slightly modified from https://github.com/kikito/inspect.lua +-- MIT license. + +local _tl_compat; if (tonumber((_VERSION or ''):match('[%d.]*$')) or 0) < 5.3 then local p, m = pcall(require, 'compat53.module'); if p then _tl_compat = m end end; local math = _tl_compat and _tl_compat.math or math; local string = _tl_compat and _tl_compat.string or string; local table = _tl_compat and _tl_compat.table or table + +inspect = {Options = {}, } + +inspect._VERSION = 'inspect.lua 3.1.0' +inspect._URL = 'http://github.com/kikito/inspect.lua' +inspect._DESCRIPTION = 'human-readable representations of tables' +inspect._LICENSE = [[ + MIT LICENSE + + Copyright (c) 2022 Enrique García Cota + + 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. +]] +inspect.KEY = setmetatable({}, { __tostring = function() return 'inspect.KEY' end }) +inspect.METATABLE = setmetatable({}, { __tostring = function() return 'inspect.METATABLE' end }) + +local tostring = tostring +local rep = string.rep +local match = string.match +local char = string.char +local gsub = string.gsub +local fmt = string.format + +local _rawget +if rawget then + _rawget = rawget +else + _rawget = function(t, k) return t[k] end +end + +local function rawpairs(t) + return next, t, nil +end + + + +local function smartQuote(str) + if match(str, '"') and not match(str, "'") then + return "'" .. str .. "'" + end + return '"' .. gsub(str, '"', '\\"') .. '"' +end + + +local shortControlCharEscapes = { + ["\a"] = "\\a", ["\b"] = "\\b", ["\f"] = "\\f", ["\n"] = "\\n", + ["\r"] = "\\r", ["\t"] = "\\t", ["\v"] = "\\v", ["\127"] = "\\127", +} +local longControlCharEscapes = { ["\127"] = "\127" } +for i = 0, 31 do + local ch = char(i) + if not shortControlCharEscapes[ch] then + shortControlCharEscapes[ch] = "\\" .. i + longControlCharEscapes[ch] = fmt("\\%03d", i) + end +end + +local function escape(str) + return (gsub(gsub(gsub(str, "\\", "\\\\"), + "(%c)%f[0-9]", longControlCharEscapes), + "%c", shortControlCharEscapes)) +end + +local luaKeywords = { + ['and'] = true, + ['break'] = true, + ['do'] = true, + ['else'] = true, + ['elseif'] = true, + ['end'] = true, + ['false'] = true, + ['for'] = true, + ['function'] = true, + ['goto'] = true, + ['if'] = true, + ['in'] = true, + ['local'] = true, + ['nil'] = true, + ['not'] = true, + ['or'] = true, + ['repeat'] = true, + ['return'] = true, + ['then'] = true, + ['true'] = true, + ['until'] = true, + ['while'] = true, +} + +local function isIdentifier(str) + return type(str) == "string" and + not not str:match("^[_%a][_%a%d]*$") and + not luaKeywords[str] +end + +local flr = math.floor +local function isSequenceKey(k, sequenceLength) + return type(k) == "number" and + flr(k) == k and + 1 <= (k) and + k <= sequenceLength +end + +local defaultTypeOrders = { + ['number'] = 1, ['boolean'] = 2, ['string'] = 3, ['table'] = 4, + ['function'] = 5, ['userdata'] = 6, ['thread'] = 7, +} + +local function sortKeys(a, b) + local ta, tb = type(a), type(b) + + + if ta == tb and (ta == 'string' or ta == 'number') then + return (a) < (b) + end + + local dta = defaultTypeOrders[ta] or 100 + local dtb = defaultTypeOrders[tb] or 100 + + + return dta == dtb and ta < tb or dta < dtb +end + +local function getKeys(t) + + local seqLen = 1 + while _rawget(t, seqLen) ~= nil do + seqLen = seqLen + 1 + end + seqLen = seqLen - 1 + + local keys, keysLen = {}, 0 + for k in rawpairs(t) do + if not isSequenceKey(k, seqLen) then + keysLen = keysLen + 1 + keys[keysLen] = k + end + end + table.sort(keys, sortKeys) + return keys, keysLen, seqLen +end + +local function countCycles(x, cycles) + if type(x) == "table" then + if cycles[x] then + cycles[x] = cycles[x] + 1 + else + cycles[x] = 1 + for k, v in rawpairs(x) do + countCycles(k, cycles) + countCycles(v, cycles) + end + countCycles(getmetatable(x), cycles) + end + end +end + +local function makePath(path, a, b) + local newPath = {} + local len = #path + for i = 1, len do newPath[i] = path[i] end + + newPath[len + 1] = a + newPath[len + 2] = b + + return newPath +end + + +local function processRecursive(process, + item, + path, + visited) + if item == nil then return nil end + if visited[item] then return visited[item] end + + local processed = process(item, path) + if type(processed) == "table" then + local processedCopy = {} + visited[item] = processedCopy + local processedKey + + for k, v in rawpairs(processed) do + processedKey = processRecursive(process, k, makePath(path, k, inspect.KEY), visited) + if processedKey ~= nil then + processedCopy[processedKey] = processRecursive(process, v, makePath(path, processedKey), visited) + end + end + + local mt = processRecursive(process, getmetatable(processed), makePath(path, inspect.METATABLE), visited) + if type(mt) ~= 'table' then mt = nil end + setmetatable(processedCopy, mt) + processed = processedCopy + end + return processed +end + +local function puts(buf, str) + buf.n = buf.n + 1 + buf[buf.n] = str +end + + + +local Inspector = {} + + + + + + + + + + +local Inspector_mt = { __index = Inspector } + +local function tabify(inspector) + puts(inspector.buf, inspector.newline .. rep(inspector.indent, inspector.level)) +end + +function Inspector:getId(v) + local id = self.ids[v] + local ids = self.ids + if not id then + local tv = type(v) + id = (ids[tv] or 0) + 1 + ids[v], ids[tv] = id, id + end + return tostring(id) +end + +function Inspector:putValue(v) + local buf = self.buf + local tv = type(v) + if tv == 'string' then + puts(buf, smartQuote(escape(v))) + elseif tv == 'number' or tv == 'boolean' or tv == 'nil' or + tv == 'cdata' or tv == 'ctype' then + puts(buf, tostring(v)) + elseif tv == 'table' and not self.ids[v] then + local t = v + + if t == inspect.KEY or t == inspect.METATABLE then + puts(buf, tostring(t)) + elseif self.level >= self.depth then + puts(buf, '{...}') + else + if self.cycles[t] > 1 then puts(buf, fmt('<%d>', self:getId(t))) end + + local keys, keysLen, seqLen = getKeys(t) + + puts(buf, '{') + self.level = self.level + 1 + + for i = 1, seqLen + keysLen do + if i > 1 then puts(buf, ',') end + if i <= seqLen then + puts(buf, ' ') + self:putValue(t[i]) + else + local k = keys[i - seqLen] + tabify(self) + if isIdentifier(k) then + puts(buf, k) + else + puts(buf, "[") + self:putValue(k) + puts(buf, "]") + end + puts(buf, ' = ') + self:putValue(t[k]) + end + end + + local mt = getmetatable(t) + if type(mt) == 'table' then + if seqLen + keysLen > 0 then puts(buf, ',') end + tabify(self) + puts(buf, ' = ') + self:putValue(mt) + end + + self.level = self.level - 1 + + if keysLen > 0 or type(mt) == 'table' then + tabify(self) + elseif seqLen > 0 then + puts(buf, ' ') + end + + puts(buf, '}') + end + + else + puts(buf, fmt('<%s %d>', tv, self:getId(v))) + end +end + + + + +function inspect.inspect(root, options) + options = options or {} + + local depth = options.depth or (math.huge) + local newline = options.newline or '\n' + local indent = options.indent or ' ' + local process = options.process + + if process then + root = processRecursive(process, root, {}, {}) + end + + local cycles = {} + countCycles(root, cycles) + + local inspector = setmetatable({ + buf = { n = 0 }, + ids = {}, + cycles = cycles, + depth = depth, + level = 0, + newline = newline, + indent = indent, + }, Inspector_mt) + + inspector:putValue(root) + + return table.concat(inspector.buf) +end + +setmetatable(inspect, { + __call = function(_, root, options) + return inspect.inspect(root, options) + end, +}) + +return inspect diff --git a/scripts/00-gamescope/common/modegen.lua b/scripts/00-gamescope/common/modegen.lua new file mode 100644 index 0000000000..90db2ed7aa --- /dev/null +++ b/scripts/00-gamescope/common/modegen.lua @@ -0,0 +1,36 @@ +gamescope.modegen = {} + +gamescope.modegen.adjust_front_porch = function(mode, vfp) + local vsync = mode.vsync_end - mode.vsync_start + local vbp = mode.vtotal - mode.vsync_end + + mode.vsync_start = mode.vdisplay + vfp + mode.vsync_end = mode.vsync_start + vsync + mode.vtotal = mode.vsync_end + vbp +end + +gamescope.modegen.set_h_timings = function(mode, hfp, hsync, hbp) + mode.hsync_start = mode.hdisplay + hfp + mode.hsync_end = mode.hsync_start + hsync + mode.htotal = mode.hsync_end + hbp +end + +gamescope.modegen.set_v_timings = function(mode, vfp, vsync, vbp) + mode.vsync_start = mode.vdisplay + vfp + mode.vsync_end = mode.vsync_start + vsync + mode.vtotal = mode.vsync_end + vbp +end + +gamescope.modegen.set_resolution = function(mode, width, height) + mode.hdisplay = width + mode.vdisplay = height +end + +gamescope.modegen.calc_max_clock = function(mode, refresh) + -- LuaJIT does not have // operator, sad face. + return math.floor( ( ( mode.htotal * mode.vtotal * refresh ) + 999 ) / 1000 ) +end + +gamescope.modegen.calc_vrefresh = function(mode, refresh) + return math.floor( (1000 * mode.clock) / (mode.htotal * mode.vtotal) ) +end diff --git a/scripts/00-gamescope/common/util.lua b/scripts/00-gamescope/common/util.lua new file mode 100644 index 0000000000..98cf66b480 --- /dev/null +++ b/scripts/00-gamescope/common/util.lua @@ -0,0 +1,19 @@ +function zero_index(index) + return index + 1 +end + +function error(text) + gamescope.log(gamescope.log_priority.error, text) +end + +function warn(text) + gamescope.log(gamescope.log_priority.warning, text) +end + +function info(text) + gamescope.log(gamescope.log_priority.info, text) +end + +function debug(text) + gamescope.log(gamescope.log_priority.debug, text) +end diff --git a/scripts/00-gamescope/displays/deckhd.steamdeck.deckhd-lcd.lua b/scripts/00-gamescope/displays/deckhd.steamdeck.deckhd-lcd.lua new file mode 100644 index 0000000000..5d1e3755ce --- /dev/null +++ b/scripts/00-gamescope/displays/deckhd.steamdeck.deckhd-lcd.lua @@ -0,0 +1,50 @@ +gamescope.config.known_displays.steamdeck_deckhd_lcd = { + pretty_name = "Steam Deck DeckHD - Unofficial Screen Replacement", + dynamic_refresh_rates = { + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60 + }, + hdr = { + -- Setup some fallbacks or undocking with HDR + -- for this display. + supported = false, + force_enabled = false, + eotf = gamescope.eotf.gamma22, + max_content_light_level = 400, + max_frame_average_luminance = 400, + min_content_light_level = 0.5 + }, + -- No colorimetry was provided in the original PR, + -- and I have no idea if their BIOS mod/whatever has colorimetry + -- in their edid. + -- Someone that works on this or uses this should go fix that. + dynamic_modegen = function(base_mode, refresh) + debug("Generating mode "..refresh.."Hz for DeckHD") + local mode = base_mode + + -- These are only tuned for 1200x1920. + gamescope.modegen.set_resolution(mode, 1200, 1920) + + -- hfp, hsync, hbp + gamescope.modegen.set_h_timings(mode, 40, 20, 40) + -- vfp, vsync, vbp + gamescope.modegen.set_v_timings(mode, 18, 2, 20) + + mode.clock = gamescope.modegen.calc_max_clock(mode, refresh) + mode.vrefresh = gamescope.modegen.calc_vrefresh(mode) + + --debug(inspect(mode)) + return mode + end, + matches = function(vendor, product, model) + if vendor == "DHD" and model == "DeckHD-1200p" and product == 0x4001 then + debug("[steamdeck_deckhd_lcd] Matched vendor: "..value.vendor.." model: "..value.model.." product:"..value.product) + return 5000 + end + + return -1 + end +} +debug("Registered Steam Deck DeckHD - Unofficial Screen Replacement as a known display") +--debug(inspect(gamescope.config.known_displays.steamdeck_deckhd_lcd)) diff --git a/scripts/00-gamescope/displays/valve.steamdeck.lcd.lua b/scripts/00-gamescope/displays/valve.steamdeck.lcd.lua new file mode 100644 index 0000000000..56923c1e51 --- /dev/null +++ b/scripts/00-gamescope/displays/valve.steamdeck.lcd.lua @@ -0,0 +1,73 @@ +-- TODO: Make a vec2 class so we can alias .x and indices. + +local steamdeck_lcd_colorimetry_spec = { + r = { x = 0.602, y = 0.355 }, + g = { x = 0.340, y = 0.574 }, + b = { x = 0.164, y = 0.121 }, + w = { x = 0.3070, y = 0.3220 } +} + +local steamdeck_lcd_colorimetry_measured = { + r = { x = 0.603, y = 0.349 }, + g = { x = 0.335, y = 0.571 }, + b = { x = 0.163, y = 0.115 }, + w = { x = 0.296, y = 0.307 } +} + +gamescope.config.known_displays.steamdeck_lcd = { + pretty_name = "Steam Deck LCD", + dynamic_refresh_rates = { + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60 + }, + hdr = { + -- Setup some fallbacks or undocking with HDR + -- for this display. + supported = false, + force_enabled = false, + eotf = gamescope.eotf.gamma22, + max_content_light_level = 500, + max_frame_average_luminance = 500, + min_content_light_level = 0.5 + }, + -- Use measured colorimetry instead. + --colorimetry = steamdeck_lcd_colorimetry_spec, + colorimetry = steamdeck_lcd_colorimetry_measured, + dynamic_modegen = function(base_mode, refresh) + debug("Generating mode "..refresh.."Hz for Steam Deck LCD") + local mode = base_mode + + -- These are only tuned for 800x1280. + gamescope.modegen.set_resolution(mode, 800, 1280) + + -- hfp, hsync, hbp + gamescope.modegen.set_h_timings(mode, 40, 4, 40) + -- vfp, vsync, vbp + gamescope.modegen.set_v_timings(mode, 30, 4, 8) + mode.clock = gamescope.modegen.calc_max_clock(mode, refresh) + mode.vrefresh = gamescope.modegen.calc_vrefresh(mode) + + --debug(inspect(mode)) + return mode + end, + matches = function(vendor, product, model) + local lcd_types = { + { vendor = "WLC", model = "ANX7530 U" }, + { vendor = "ANX", model = "ANX7530 U" }, + { vendor = "VLV", model = "ANX7530 U" }, + { vendor = "VLV", model = "Jupiter" }, + } + + for index, value in ipairs(lcd_types) do + if value.vendor == vendor and value.model == model then + debug("[steamdeck_lcd] Matched vendor: "..value.vendor.." model: "..value.model) + return 5000 + end + end + + return -1 + end +} +debug("Registered Steam Deck LCD as a known display") +--debug(inspect(gamescope.config.known_displays.steamdeck_lcd)) diff --git a/scripts/00-gamescope/displays/valve.steamdeck.oled.lua b/scripts/00-gamescope/displays/valve.steamdeck.oled.lua new file mode 100644 index 0000000000..4b6375f2ee --- /dev/null +++ b/scripts/00-gamescope/displays/valve.steamdeck.oled.lua @@ -0,0 +1,100 @@ +local steamdeck_oled_hdr = { + supported = true, + force_enabled = true, + eotf = gamescope.eotf.gamma22, + max_content_light_level = 1000, + max_frame_average_luminance = 800, + min_content_light_level = 0 +} + +local steamdeck_oled_refresh_rates = { + 45, 47, 48, 49, + 50, 51, 53, 55, 56, 59, + 60, 62, 64, 65, 66, 68, + 72, 73, 76, 77, 78, + 80, 81, 82, 84, 85, 86, 87, 88, + 90 +} + +gamescope.config.known_displays.steamdeck_oled_sdc = { + pretty_name = "Steam Deck OLED (SDC)", + hdr = steamdeck_oled_hdr, + dynamic_refresh_rates = steamdeck_oled_refresh_rates, + dynamic_modegen = function(base_mode, refresh) + debug("Generating mode "..refresh.."Hz for Steam Deck OLED (SDC)") + local vfps = { + 1321, 1264, 1209, 1157, 1106, + 1058, 993, 967, 925, 883, 829, 805, 768, 732, 698, + 665, 632, 601, 571, 542, 501, 486, 459, 433, 408, + 383, 360, 337, 314, 292, 271, 250, 230, 210, 191, + 173, 154, 137, 119, 102, 86, 70, 54, 38, 23, + 9 + } + local vfp = vfps[zero_index(refresh - 45)] + if vfp == nil then + warn("Couldn't do refresh "..refresh.." on Steam Deck OLED (SDC)") + return base_mode + end + + local mode = base_mode + + gamescope.modegen.adjust_front_porch(mode, vfp) + mode.vrefresh = gamescope.modegen.calc_vrefresh(mode) + + --debug(inspect(mode)) + return mode + end, + matches = function(vendor, product, model) + if vendor == "VLV" and product == 0x3003 then + debug("[steamdeck_oled_sdc] Matched VLV and product 0x3003") + -- Higher priorty than LCD. + return 5100 + end + + return -1 + end +} +debug("Registered Steam Deck OLED (SDC) as a known display") +--debug(inspect(gamescope.config.known_displays.steamdeck_oled_sdc)) + +gamescope.config.known_displays.steamdeck_oled_boe = { + pretty_name = "Steam Deck OLED (BOE)", + hdr = steamdeck_oled_hdr, + dynamic_refresh_rates = steamdeck_oled_refresh_rates, + dynamic_modegen = function(base_mode, refresh) + debug("Generating mode for "..refresh.." for Steam Deck OLED (BOE)") + + local vfps = { + 1320, 1272, 1216, 1156, 1112, + 1064, 992, 972, 928, 888, 828, 808, 772, 736, 700, + 664, 636, 604, 572, 544, 500, 488, 460, 436, 408, + 384, 360, 336, 316, 292, 272, 252, 228, 212, 192, + 172, 152, 136, 120, 100, 84, 68, 52, 36, 20, + 8 + } + local vfp = vfps[zero_index(refresh - 45)] + if vfp == nil then + warn("Couldn't do refresh "..refresh.." on Steam Deck OLED (BOE)") + return base_mode + end + + local mode = base_mode + + gamescope.modegen.adjust_front_porch(mode, vfp) + mode.vrefresh = gamescope.modegen.calc_vrefresh(mode) + + --debug(inspect(mode)) + return mode + end, + matches = function(vendor, product, model) + if vendor == "VLV" and product == 0x3004 then + debug("[steamdeck_oled_boe] Matched VLV and product 0x3004") + -- Higher priorty than LCD. + return 5100 + end + + return -1 + end +} +debug("Registered Steam Deck OLED (BOE) as a known display") +--debug(inspect(gamescope.config.known_displays.steamdeck_oled_boe)) diff --git a/scripts/README.md b/scripts/README.md new file mode 100644 index 0000000000..337719b9c4 --- /dev/null +++ b/scripts/README.md @@ -0,0 +1,75 @@ +# Gamescope Script/Config Files + +## ⚠️ Health Warning ⚠️ + +Gamescope scripting/configuration is currently experimental and subject to change massively. + +Scripts and configs working between revisions is not guaranteed to work, it should at least not crash... probably. + +## The Basics + +Gamescope uses Lua for it's configuration and scripting system. + +Scripts ending in `.lua` are executed recursively in alphabetical order from the following directories: + - `/usr/share/gamescope` + - `/etc/gamescope` + - `$XDG_CONFIG_DIR/gamescope` + +You can develop easily without overriding your installation by setting `script_use_local_scripts` which will eliminate `/usr/share/gamescope` and `/etc/gamescope` from being read, and instead read from `../config` of where Gamescope is run instead of those. + +When errors are encountered, it will simply output that to the terminal. There is no visual indicator of this currently. + +Things should mostly fail-safe, unless you actually made an egregious mistake in your config like setting the refresh rate to 0 or the colorimetry to all 0, 0 or something. + +# Making modifications as a user + +If you wish to make modifications that will persist as a user, simply make a new `.lua` file in `$XDG_CONFIG_DIR/gamescope` which is usually `$HOME/.config/gamescope` with what you want to change. + +For example, to make the Steam Deck LCD use spec colorimetry instead of the measured colorimetry you could create the following file `~/.config/gamescope/my_deck_lcd_colorimetry.lua` with the following contents: + +```lua +local steamdeck_lcd_colorimetry_spec = { + r = { x = 0.602, y = 0.355 }, + g = { x = 0.340, y = 0.574 }, + b = { x = 0.164, y = 0.121 }, + w = { x = 0.3070, y = 0.3220 } +} + +gamescope.config.known_displays.steamdeck_lcd.colorimetry = steamdeck_lcd_colorimetry_spec +``` + +and it would override that. + +You could also place this in `/etc/gamescope` if you really want it to apply to all users/system-wide, but that would need root privelages. + +# Features + +Being able to set known displays (`gamescope.config.known_displays`) + +The ability to set convars. + +Hooks + +# Examples + +A script that will enable composite debug and force composition on and off every 60 frames. + +```lua +my_counter = 0 + +gamescope.convars.composite_debug.value = 3 + +gamescope.hook("OnPostPaint", function() + my_counter = my_counter + 1 + + if my_counter > 60 then + gamescope.convars.composite_force.value = not gamescope.convars.composite_force.value + my_counter = 0 + warn("Changed composite_force to "..tostring(gamescope.convars.composite_force.value)..".") + end +end) +``` + +# Hot Reloading? + +Coming soon... diff --git a/src/Backends/DRMBackend.cpp b/src/Backends/DRMBackend.cpp index c62635f190..224d76f5d7 100644 --- a/src/Backends/DRMBackend.cpp +++ b/src/Backends/DRMBackend.cpp @@ -1,5 +1,7 @@ // DRM output stuff +#include "Script/Script.h" + #include #include #include @@ -287,7 +289,6 @@ namespace gamescope const char *GetModel() const override { return m_Mutable.szModel; } uint32_t GetPossibleCRTCMask() const { return m_Mutable.uPossibleCRTCMask; } std::span GetValidDynamicRefreshRates() const override { return m_Mutable.ValidDynamicRefreshRates; } - GamescopeKnownDisplays GetKnownDisplayType() const { return m_Mutable.eKnownDisplay; } const displaycolorimetry_t& GetDisplayColorimetry() const { return m_Mutable.DisplayColorimetry; } std::span GetRawEDID() const override { return std::span{ m_Mutable.EdidData.begin(), m_Mutable.EdidData.end() }; } @@ -372,11 +373,15 @@ namespace gamescope void UpdateEffectiveOrientation( const drmModeModeInfo *pMode ); + using DRMModeGenerator = std::function; + const DRMModeGenerator &GetModeGenerator() const + { + return m_Mutable.fnDynamicModeGenerator; + } + private: void ParseEDID(); - static std::optional GetKnownDisplayHDRInfo( GamescopeKnownDisplays eKnownDisplay ); - CAutoDeletePtr m_pConnector; struct MutableConnectorState @@ -388,8 +393,8 @@ namespace gamescope char szMakePNP[4]{}; char szModel[16]{}; const char *pszMake = ""; // Not owned, no free. This is a pointer to pnp db or szMakePNP. - GamescopeKnownDisplays eKnownDisplay = GAMESCOPE_KNOWN_DISPLAY_UNKNOWN; - std::span ValidDynamicRefreshRates{}; + std::vector ValidDynamicRefreshRates{}; + DRMModeGenerator fnDynamicModeGenerator; std::vector EdidData; // Raw, unmodified. std::vector BackendModes; @@ -2111,71 +2116,113 @@ namespace gamescope drm_log.infof("Connector %s -> %s - %s", m_Mutable.szName, m_Mutable.szMakePNP, m_Mutable.szModel ); - const bool bIsDeckHDUnofficial = ( m_Mutable.szMakePNP == "DHD"sv && m_Mutable.szModel == "DeckHD-1200p"sv ); + bool bHasKnownColorimetry = false; + bool bHasKnownHDRInfo = false; - const bool bSteamDeckDisplay = - ( m_Mutable.szMakePNP == "WLC"sv && m_Mutable.szModel == "ANX7530 U"sv ) || - ( m_Mutable.szMakePNP == "ANX"sv && m_Mutable.szModel == "ANX7530 U"sv ) || - ( m_Mutable.szMakePNP == "VLV"sv && m_Mutable.szModel == "ANX7530 U"sv ) || - ( m_Mutable.szMakePNP == "VLV"sv && m_Mutable.szModel == "Jupiter"sv ) || - ( m_Mutable.szMakePNP == "VLV"sv && m_Mutable.szModel == "Galileo"sv ); - - if ( bSteamDeckDisplay ) { - static constexpr uint32_t kPIDGalileoSDC = 0x3003; - static constexpr uint32_t kPIDGalileoBOE = 0x3004; + CScriptScopedLock script; - if ( pProduct->product == kPIDGalileoSDC ) - { - m_Mutable.eKnownDisplay = GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_OLED_SDC; - m_Mutable.ValidDynamicRefreshRates = std::span( s_kSteamDeckOLEDRates ); - } - else if ( pProduct->product == kPIDGalileoBOE ) - { - m_Mutable.eKnownDisplay = GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_OLED_BOE; - m_Mutable.ValidDynamicRefreshRates = std::span( s_kSteamDeckOLEDRates ); - } - else + auto oKnownDisplay = script.Manager().Gamescope().Config.LookupDisplay( m_Mutable.szMakePNP, pProduct->product, m_Mutable.szModel ); + if ( oKnownDisplay ) { - m_Mutable.eKnownDisplay = GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD; - m_Mutable.ValidDynamicRefreshRates = std::span( s_kSteamDeckLCDRates ); - } - } + sol::table tTable = oKnownDisplay->second; - if ( bIsDeckHDUnofficial ) - { - static constexpr uint32_t kPIDJupiterDHD = 0x4001; + std::string_view psvPrettyName = tTable.get_or( "pretty_name", std::string_view{ "Untitled Display" } ); + drm_log.infof( "Got known display: %.*s (%.*s)", + (int)oKnownDisplay->first.size(), oKnownDisplay->first.data(), + (int)psvPrettyName.size(), psvPrettyName.data() ); - if ( pProduct->product == kPIDJupiterDHD ) - { - m_Mutable.eKnownDisplay = GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD_DHD; - m_Mutable.ValidDynamicRefreshRates = std::span( s_kSteamDeckLCDRates ); - } - } + m_Mutable.fnDynamicModeGenerator = nullptr; + m_Mutable.ValidDynamicRefreshRates.clear(); - // Colorimetry - const char *pszColorOverride = getenv( "GAMESCOPE_INTERNAL_COLORIMETRY_OVERRIDE" ); - if ( pszColorOverride && *pszColorOverride && GetScreenType() == GAMESCOPE_SCREEN_TYPE_INTERNAL ) - { - if ( sscanf( pszColorOverride, "%f %f %f %f %f %f %f %f", - &m_Mutable.DisplayColorimetry.primaries.r.x, &m_Mutable.DisplayColorimetry.primaries.r.y, - &m_Mutable.DisplayColorimetry.primaries.g.x, &m_Mutable.DisplayColorimetry.primaries.g.y, - &m_Mutable.DisplayColorimetry.primaries.b.x, &m_Mutable.DisplayColorimetry.primaries.b.y, - &m_Mutable.DisplayColorimetry.white.x, &m_Mutable.DisplayColorimetry.white.y ) == 8 ) - { - drm_log.infof( "[colorimetry]: GAMESCOPE_INTERNAL_COLORIMETRY_OVERRIDE detected" ); - } - else - { - drm_log.errorf( "[colorimetry]: GAMESCOPE_INTERNAL_COLORIMETRY_OVERRIDE specified, but could not parse \"rx ry gx gy bx by wx wy\"" ); + sol::optional otDynamicRefreshRates = tTable["dynamic_refresh_rates"]; + sol::optional ofnDynamicModegen = tTable["dynamic_modegen"]; + + if ( otDynamicRefreshRates && ofnDynamicModegen ) + { + m_Mutable.ValidDynamicRefreshRates = TableToVector( *otDynamicRefreshRates ); + + m_Mutable.fnDynamicModeGenerator = [ fnDynamicModegen = *ofnDynamicModegen ]( const drmModeModeInfo *pBaseMode, int nRefreshHz ) -> drmModeModeInfo + { + CScriptScopedLock script; + + sol::table tInMode = script->create_table(); + tInMode["clock"] = pBaseMode->clock; + + tInMode["hdisplay"] = pBaseMode->hdisplay; + tInMode["hsync_start"] = pBaseMode->hsync_start; + tInMode["hsync_end"] = pBaseMode->hsync_end; + tInMode["htotal"] = pBaseMode->htotal; + + tInMode["vdisplay"] = pBaseMode->vdisplay; + tInMode["vsync_start"] = pBaseMode->vsync_start; + tInMode["vsync_end"] = pBaseMode->vsync_end; + tInMode["vtotal"] = pBaseMode->vtotal; + + tInMode["vrefresh"] = pBaseMode->vrefresh; + + sol::function_result ret = fnDynamicModegen(tInMode, nRefreshHz); + if ( !ret.valid() || !ret.get() ) + return *pBaseMode; + + sol::table tOutMode = ret; + + drmModeModeInfo outMode = *pBaseMode; + outMode.clock = tOutMode["clock"]; + + outMode.hdisplay = tOutMode["hdisplay"]; + outMode.hsync_start = tOutMode["hsync_start"]; + outMode.hsync_end = tOutMode["hsync_end"]; + outMode.htotal = tOutMode["htotal"]; + + outMode.vdisplay = tOutMode["vdisplay"]; + outMode.vsync_start = tOutMode["vsync_start"]; + outMode.vsync_end = tOutMode["vsync_end"]; + outMode.vtotal = tOutMode["vtotal"]; + + outMode.vrefresh = tOutMode["vrefresh"]; + + snprintf( outMode.name, sizeof( outMode.name ), "%dx%d@%d.00", outMode.hdisplay, outMode.vdisplay, nRefreshHz ); + + return outMode; + }; + } + + if ( sol::optional otColorimetry = tTable["colorimetry"] ) + { + sol::table tColorimetry = *otColorimetry; + + // TODO: Add a vec2 + colorimetry type? + sol::optional otR = tColorimetry["r"]; + sol::optional otG = tColorimetry["g"]; + sol::optional otB = tColorimetry["b"]; + sol::optional otW = tColorimetry["w"]; + + if ( otR && otG && otB && otW ) + { + m_Mutable.DisplayColorimetry.primaries.r = TableToVec( *otR ); + m_Mutable.DisplayColorimetry.primaries.g = TableToVec( *otG ); + m_Mutable.DisplayColorimetry.primaries.b = TableToVec( *otB ); + m_Mutable.DisplayColorimetry.white = TableToVec( *otW ); + + bHasKnownColorimetry = true; + } + } + + if ( sol::optional otHDRInfo = tTable["hdr"] ) + { + m_Mutable.HDR.bExposeHDRSupport = otHDRInfo->get_or( "supported", false ); + m_Mutable.HDR.eOutputEncodingEOTF = otHDRInfo->get_or( "eotf", EOTF_Gamma22 ); + m_Mutable.HDR.uMaxContentLightLevel = nits_to_u16( otHDRInfo->get_or( "max_content_light_level", 400.0f ) ); + m_Mutable.HDR.uMaxFrameAverageLuminance = nits_to_u16( otHDRInfo->get_or( "max_frame_average_luminance", 400.0f ) ); + m_Mutable.HDR.uMinContentLightLevel = nits_to_u16_dark( otHDRInfo->get_or( "min_content_light_level", 0.1f ) ); + + bHasKnownHDRInfo = true; + } } } - else if ( m_Mutable.eKnownDisplay == GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD ) - { - drm_log.infof( "[colorimetry]: Steam Deck LCD detected. Using known colorimetry" ); - m_Mutable.DisplayColorimetry = displaycolorimetry_steamdeck_measured; - } - else + + if ( !bHasKnownColorimetry ) { // Steam Deck OLED has calibrated chromaticity coordinates in the EDID // for each unit. @@ -2191,6 +2238,11 @@ namespace gamescope .white = { pChroma->white_x, pChroma->white_y }, }; } + else + { + // Assume 709 if we have no data at all. + m_Mutable.DisplayColorimetry = displaycolorimetry_709; + } } drm_log.infof( "[colorimetry]: r %f %f", m_Mutable.DisplayColorimetry.primaries.r.x, m_Mutable.DisplayColorimetry.primaries.r.y ); @@ -2201,12 +2253,7 @@ namespace gamescope ///////////////////// // Parse HDR stuff. ///////////////////// - std::optional oKnownHDRInfo = GetKnownDisplayHDRInfo( m_Mutable.eKnownDisplay ); - if ( oKnownHDRInfo ) - { - m_Mutable.HDR = *oKnownHDRInfo; - } - else + if ( !bHasKnownHDRInfo ) { const di_cta_hdr_static_metadata_block *pHDRStaticMetadata = nullptr; const di_cta_colorimetry_block *pColorimetry = nullptr; @@ -2289,38 +2336,6 @@ namespace gamescope } } - /*static*/ std::optional CDRMConnector::GetKnownDisplayHDRInfo( GamescopeKnownDisplays eKnownDisplay ) - { - if ( eKnownDisplay == GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_OLED_BOE || eKnownDisplay == GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_OLED_SDC ) - { - // The stuff in the EDID for the HDR metadata does not fully - // reflect what we can achieve on the display by poking at more - // things out-of-band. - return BackendConnectorHDRInfo - { - .bExposeHDRSupport = true, - .eOutputEncodingEOTF = EOTF_Gamma22, - .uMaxContentLightLevel = nits_to_u16( 1000.0f ), - .uMaxFrameAverageLuminance = nits_to_u16( 800.0f ), // Full-frame sustained. - .uMinContentLightLevel = nits_to_u16_dark( 0 ), - }; - } - else if ( eKnownDisplay == GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD || eKnownDisplay == GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD_DHD ) - { - // Set up some HDR fallbacks for undocking - return BackendConnectorHDRInfo - { - .bExposeHDRSupport = false, - .eOutputEncodingEOTF = EOTF_Gamma22, - .uMaxContentLightLevel = nits_to_u16( 500.0f ), - .uMaxFrameAverageLuminance = nits_to_u16( 500.0f ), - .uMinContentLightLevel = nits_to_u16_dark( 0.5f ), - }; - } - - return std::nullopt; - } - ///////////////////////// // CDRMFb ///////////////////////// @@ -3015,17 +3030,25 @@ bool drm_set_refresh( struct drm_t *drm, int refresh ) } else { - /* TODO: check refresh is within the EDID limits */ - switch ( g_eGamescopeModeGeneration ) + if ( g_DRM.pConnector && g_DRM.pConnector->GetModeGenerator() ) { - case gamescope::GAMESCOPE_MODE_GENERATE_CVT: - generate_cvt_mode( &mode, width, height, refresh, true, false ); - break; - case gamescope::GAMESCOPE_MODE_GENERATE_FIXED: + const drmModeModeInfo *preferred_mode = find_mode(connector, 0, 0, 0); + mode = g_DRM.pConnector->GetModeGenerator()( preferred_mode, refresh ); + } + else + { + /* TODO: check refresh is within the EDID limits */ + switch ( g_eGamescopeModeGeneration ) { - const drmModeModeInfo *preferred_mode = find_mode(connector, 0, 0, 0); - generate_fixed_mode( &mode, preferred_mode, refresh, drm->pConnector->GetKnownDisplayType() ); + case gamescope::GAMESCOPE_MODE_GENERATE_CVT: + generate_cvt_mode( &mode, width, height, refresh, true, false ); break; + case gamescope::GAMESCOPE_MODE_GENERATE_FIXED: + { + const drmModeModeInfo *preferred_mode = find_mode(connector, 0, 0, 0); + generate_fixed_mode( &mode, preferred_mode, refresh ); + break; + } } } } diff --git a/src/Script/Script.cpp b/src/Script/Script.cpp new file mode 100644 index 0000000000..261b2b03da --- /dev/null +++ b/src/Script/Script.cpp @@ -0,0 +1,245 @@ +#include "Script.h" +#include "convar.h" +#include "color_helpers.h" +#include "../log.hpp" + +#include +#include + +std::string_view GetHomeDir(); + +namespace gamescope +{ + using namespace std::literals; + + static LogScope s_ScriptLog{ "script" }; + static LogScope s_ScriptMgrLog{ "scriptmgr" }; + + static ConVar cv_script_use_local_scripts{ "script_use_local_scripts", false, "Whether or not to use the local scripts (../config) as opposed to the ones in /etc/gamescope.d" }; + static ConVar cv_script_use_user_scripts{ "script_use_user_scripts", true, "Whether or not to use user config scripts ($XDG_CONFIG_DIR/gamescope) at all." }; + + static std::string_view GetConfigDir() + { + static std::string s_sConfigDir = []() -> std::string + { + const char *pszConfigHome = getenv( "XDG_CONFIG_HOME" ); + if ( pszConfigHome && *pszConfigHome ) + return pszConfigHome; + + return std::string{ GetHomeDir() } + "/.config"; + }(); + + return s_sConfigDir; + } + + static inline void PanicFunction( sol::optional oMsg ) + { + s_ScriptLog.errorf( "Lua is in a panic state and will now abort() the application" ); + if ( oMsg ) + { + s_ScriptLog.errorf( "\tError Message: %s", oMsg->c_str() ); + } + // When this function exits, Lua will exhibit default behavior and abort() + } + + static inline int ExceptionFunction( lua_State* pState, sol::optional oException, sol::string_view psvDescription ) + { + // L is the lua state, which you can wrap in a state_view if necessary + // maybe_exception will contain exception, if it exists + // description will either be the what() of the exception or a description saying that we hit the general-case catch(...) + + s_ScriptLog.errorf( "An exception occurred:\n %.*s", + (int)psvDescription.length(), psvDescription.data() ); + + // you must push 1 element onto the stack to be + // transported through as the error object in Lua + // note that Lua -- and 99.5% of all Lua users and libraries -- expects a string + // so we push a single string (in our case, the description of the error) + return sol::stack::push( pState, psvDescription ); + } + + static inline void LuaErrorHandler( const std::string &msg ) + { + s_ScriptLog.errorf( "An error occurred:\n %.*s", + (int)msg.length(), msg.data() ); + } + + int32_t CScriptManager::s_nNextScriptId = 0; + + CScriptManager &CScriptManager::GlobalScriptScope() + { + static CScriptManager s_State; + return s_State; + } + + CScriptManager::CScriptManager() + { + m_State.open_libraries(); + + static bool s_bSetDefaultHandler = false; + if ( !s_bSetDefaultHandler ) + { + m_State["_gamescope_error_handler"] = LuaErrorHandler; + + sol::protected_function::set_default_handler( m_State["_gamescope_error_handler"] ); + s_bSetDefaultHandler = true; + } + + m_State.set_panic( sol::c_call ); + m_State.set_exception_handler( &ExceptionFunction ); + + m_Gamescope.Base = m_State.create_named_table( "gamescope" ); + m_Gamescope.Base["hook"] = [this]( std::string_view svName, sol::function fnFunc ) + { + m_Hooks.emplace( std::make_pair( svName, Hook_t{ std::move( fnFunc ), m_nCurrentScriptId } ) ); + }; + m_Gamescope.Base.new_enum( "eotf", + { + { "gamma22", EOTF_Gamma22 }, + { "pq", EOTF_PQ }, + { "count", EOTF_Count }, + } + ); + m_Gamescope.Base.new_enum( "log_priority", + { + { "silent", LOG_SILENT }, + { "error", LOG_ERROR }, + { "warning", LOG_WARNING }, + { "info", LOG_INFO }, + { "debug", LOG_DEBUG }, + } + ); + m_Gamescope.Base["log"] = []( LogPriority ePriority, std::string_view svText ) { s_ScriptLog.log( ePriority, svText ); }; + + m_Gamescope.Convars.Base = m_State.create_table(); + m_Gamescope.Base.set( "convars", m_Gamescope.Convars.Base ); + + m_Gamescope.Config.Base = m_State.create_table(); + m_Gamescope.Base.set( "config", m_Gamescope.Config.Base ); + + m_Gamescope.Config.KnownDisplays = m_State.create_table(); + m_Gamescope.Config.Base.set( "known_displays", m_Gamescope.Config.KnownDisplays ); + } + + void CScriptManager::RunDefaultScripts() + { + if ( cv_script_use_local_scripts ) + { + RunFolder( "../scripts", true ); + } + else + { + RunFolder( "/usr/share/gamescope/scripts", true ); + RunFolder( "/etc/gamescope/scripts", true ); + } + + if ( cv_script_use_user_scripts ) + { + std::string sUserConfigs = std::string{ GetConfigDir() } + "/gamescope/scripts"; + RunFolder( sUserConfigs, true ); + } + } + + void CScriptManager::RunScriptText( std::string_view svContents ) + { + uint32_t uScriptId = s_nNextScriptId++; + + { + int32_t nPreviousScriptId = m_nCurrentScriptId; + + m_nCurrentScriptId = uScriptId; + State().script( svContents ); + m_nCurrentScriptId = nPreviousScriptId; + } + } + void CScriptManager::RunFile( std::string_view svPath ) + { + uint32_t uScriptId = s_nNextScriptId++; + + s_ScriptMgrLog.infof( "Running script file '%.*s' (id: %u)", + int( svPath.length() ), svPath.data(), + uScriptId ); + + std::string sPath = std::string( svPath ); + + { + int32_t nPreviousScriptId = m_nCurrentScriptId; + + m_nCurrentScriptId = uScriptId; + State().script_file( std::move( sPath ) ); + m_nCurrentScriptId = nPreviousScriptId; + } + } + bool CScriptManager::RunFolder( std::string_view svDirectory, bool bRecursive ) + { + s_ScriptMgrLog.infof( "Loading scripts from: '%.*s'", + int( svDirectory.size() ), svDirectory.data() ); + + std::filesystem::path dirConfig = std::filesystem::path{ svDirectory }; + if ( !std::filesystem::is_directory( dirConfig ) ) + { + s_ScriptMgrLog.warnf( "Directory '%.*s' does not exist", + int( svDirectory.size() ), svDirectory.data() ); + return false; + } + + if ( access( dirConfig.c_str(), R_OK | X_OK ) != 0 ) + { + s_ScriptMgrLog.warnf( "Cannot open directory '%.*s'", + int( svDirectory.size() ), svDirectory.data() ); + return false; + } + + std::vector sFiles; + std::vector sDirectories; + for ( const auto &iter : std::filesystem::directory_iterator( dirConfig ) ) + { + const std::filesystem::path &path = iter.path(); + // XXX: is_regular_file -> What about symlinks? + if ( std::filesystem::is_regular_file( iter.status() ) && path.extension() == ".lua"sv ) + { + sFiles.push_back( path ); + } + + if ( bRecursive && std::filesystem::is_directory( iter.status() ) ) + { + sDirectories.push_back( path ); + } + } + + std::sort( sFiles.begin(), sFiles.end() ); + std::sort( sDirectories.begin(), sDirectories.end() ); + + for ( const auto &sPath : sFiles ) + { + RunFile( sPath ); + } + + if ( bRecursive ) + { + for ( const auto &sPath : sDirectories ) + { + RunFolder( sPath, bRecursive ); + } + } + + return true; + } + + void CScriptManager::InvalidateAllHooks() + { + m_Hooks.clear(); + } + + void CScriptManager::InvalidateHooksForScript( int32_t nScriptId ) + { + if ( nScriptId < 0 ) + return; + + std::erase_if( m_Hooks, [ nScriptId ]( const auto &iter ) -> bool + { + return iter.second.nScriptId == nScriptId; + }); + } + +} diff --git a/src/Script/Script.h b/src/Script/Script.h new file mode 100644 index 0000000000..7f671b814f --- /dev/null +++ b/src/Script/Script.h @@ -0,0 +1,208 @@ +#pragma once + +#include "../Utils/Dict.h" + +#include + +#if HAVE_SCRIPTING + +#include + +namespace gamescope +{ + struct GamescopeScript_t + { + // Stores table entries, and caches sol::table + // handles for things we use frequently. + + sol::table Base; + + struct ConVars_t + { + sol::table Base; + } Convars; + + struct Config_t + { + sol::table Base; + + sol::table KnownDisplays; + + std::optional> LookupDisplay( std::string_view psvVendor, uint16_t uProduct, std::string_view psvModel ) + { + int nMaxPrority = -1; + std::optional> oOutDisplay; + + for ( auto iter : KnownDisplays ) + { + sol::table tTable = iter.second.as(); + if ( !tTable ) + continue; + + sol::function fnMatches = tTable["matches"]; + if ( !fnMatches ) + continue; + + int nPriority = fnMatches( psvVendor, uProduct, psvModel ); + if ( nPriority <= nMaxPrority ) + continue; + + std::string_view psvKey = iter.first.as(); + + nMaxPrority = nPriority; + oOutDisplay = std::make_pair( psvKey, tTable ); + } + + return oOutDisplay; + } + } Config; + }; + + class CScriptScopedLock; + + class CScriptManager + { + public: + CScriptManager(); + + template + void CallHook( std::string_view svName, Args&&... args ) + { + auto range = m_Hooks.equal_range( svName ); + for ( auto iter = range.first; iter != range.second; iter++ ) + { + int32_t nPreviousScriptId = m_nCurrentScriptId; + + Hook_t *pHook = &iter->second; + + m_nCurrentScriptId = pHook->nScriptId; + iter->second.fnCallback( std::forward( args )... ); + m_nCurrentScriptId = nPreviousScriptId; + } + } + + void RunDefaultScripts(); + + void RunScriptText( std::string_view svContents ); + + void RunFile( std::string_view svPath ); + bool RunFolder( std::string_view svPath, bool bRecursive = false ); + + void InvalidateAllHooks(); + void InvalidateHooksForScript( int32_t nScriptId ); + + sol::state *operator->() { return &m_State; } + + sol::state &State() { return m_State; } + GamescopeScript_t &Gamescope() { return m_Gamescope; } + + std::mutex &Mutex() { return m_mutMutex; } + + protected: + static CScriptManager &GlobalScriptScope(); + friend CScriptScopedLock; + private: + mutable std::mutex m_mutMutex; + + sol::state m_State; + GamescopeScript_t m_Gamescope; + + struct Hook_t + { + sol::function fnCallback; + int32_t nScriptId = -1; + }; + + MultiDict m_Hooks; + + int32_t m_nCurrentScriptId = -1; + + static int32_t s_nNextScriptId; + }; + + class CScriptScopedLock + { + public: + CScriptScopedLock() + : CScriptScopedLock{ CScriptManager::GlobalScriptScope() } + { + } + + CScriptScopedLock( CScriptManager &manager ) + : m_Lock{ manager.Mutex() } + , m_ScriptManager{ manager } + { + } + + ~CScriptScopedLock() + { + } + + CScriptManager &Manager() { return m_ScriptManager; } + sol::state *operator ->() { return &m_ScriptManager.State(); } + private: + std::scoped_lock m_Lock; + CScriptManager &m_ScriptManager; + }; + + template + T TableToVec( const sol::table &table ) + { + if ( !table ) + return T{}; + + T out{}; + for ( int i = 0; i < T::length(); i++ ) + { + std::array ppsvIndices + { + "x", "y", "z", "w" + }; + + if ( table[ppsvIndices[i]] ) + out[i] = (float)table[ppsvIndices[i]]; + else + out[i] = 0; + } + return out; + } + + template + std::vector TableToVector( const sol::table &table ) + { + std::vector out; + + if ( table ) + { + for ( auto &iter : table ) + { + out.emplace_back( iter.second.as() ); + } + } + + return out; + } + + #define SCRIPTDESC_TEMPLATE( type ) template + #define DECLARE_SCRIPTDESC( type ) \ + static sol::usertype< type > s_ScriptType; \ + class CEnsureScriptTypeInstantiation { public: CEnsureScriptTypeInstantiation() { (void) type :: s_ScriptType; } } m_EnsureTemplateInstantiation_ScriptDesc; + + #define START_SCRIPTDESC( type, lua_name ) \ + inline sol::usertype type::s_ScriptType = CScriptScopedLock()->new_usertype( lua_name + #define START_SCRIPTDESC_ANON( type ) \ + inline sol::usertype type::s_ScriptType = CScriptScopedLock()->new_usertype( typeid( type ).name() + #define SCRIPTDESC( x, y ) , x, y + #define END_SCRIPTDESC() ); +} + +#else + + #define SCRIPTDESC_TEMPLATE( type ) + #define DECLARE_SCRIPTDESC( x ) + #define START_SCRIPTDESC( type, lua_name ) + #define START_SCRIPTDESC_ANON( type ) + #define SCRIPTDESC( x, y ) + #define END_SCRIPTDESC() + +#endif \ No newline at end of file diff --git a/src/Utils/Dict.h b/src/Utils/Dict.h new file mode 100644 index 0000000000..c17efd77c6 --- /dev/null +++ b/src/Utils/Dict.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include +#include +#include + +namespace gamescope +{ + struct StringHash + { + using is_transparent = void; + [[nodiscard]] size_t operator()( const char *string ) const { return std::hash{}( string ); } + [[nodiscard]] size_t operator()( std::string_view string ) const { return std::hash{}( string ); } + [[nodiscard]] size_t operator()( const std::string &string ) const { return std::hash{}( string ); } + }; + + template + using Dict = std::unordered_map>; + + template + using MultiDict = std::unordered_multimap>; +} diff --git a/src/convar.cpp b/src/convar.cpp index ed2d0b125c..7fdc8a450e 100644 --- a/src/convar.cpp +++ b/src/convar.cpp @@ -8,6 +8,25 @@ extern void PrintGamescopeVersion(); namespace gamescope { + ConCommand::ConCommand( std::string_view pszName, std::string_view pszDescription, ConCommandFunc func, bool bRegisterScript ) + : m_pszName{ pszName } + , m_pszDescription{ pszDescription } + , m_Func{ func } + { + assert( !GetCommands().contains( pszName ) ); + GetCommands()[ std::string( pszName ) ] = this; + +#if HAVE_SCRIPTING + if ( bRegisterScript ) + CScriptScopedLock().Manager().Gamescope().Convars.Base[pszName] = this; +#endif + } + + ConCommand::~ConCommand() + { + GetCommands().erase( GetCommands().find( m_pszName ) ); + } + bool ConCommand::Exec( std::span args ) { if ( args.size() < 1 ) diff --git a/src/convar.h b/src/convar.h index 0bcdcff7d8..5a90bfbdcd 100644 --- a/src/convar.h +++ b/src/convar.h @@ -12,6 +12,9 @@ #include #include +#include "Script/Script.h" +#include "Utils/Dict.h" + #include "log.hpp" extern LogScope console_log; @@ -62,10 +65,8 @@ namespace gamescope return false; } - inline std::vector Split( std::string_view string, std::string_view delims = " " ) + inline void Split( std::vector &tokens, std::string_view string, std::string_view delims = " " ) { - std::vector tokens; - size_t end = 0; for ( size_t start = 0; start < string.size() && end != std::string_view::npos; start = end + 1 ) { @@ -74,39 +75,24 @@ namespace gamescope if ( start != end ) tokens.emplace_back( string.substr( start, end-start ) ); } - - return tokens; } - struct StringHash + inline std::vector Split( std::string_view string, std::string_view delims = " " ) { - using is_transparent = void; - [[nodiscard]] size_t operator()( const char *string ) const { return std::hash{}( string ); } - [[nodiscard]] size_t operator()( std::string_view string ) const { return std::hash{}( string ); } - [[nodiscard]] size_t operator()( const std::string &string ) const { return std::hash{}( string ); } - }; - - template - using Dict = std::unordered_map>; + std::vector tokens; + Split( tokens, string, delims ); + return tokens; + } class ConCommand { using ConCommandFunc = std::function )>; public: - ConCommand( std::string_view pszName, std::string_view pszDescription, ConCommandFunc func ) - : m_pszName{ pszName } - , m_pszDescription{ pszDescription } - , m_Func{ func } - { - assert( !GetCommands().contains( pszName ) ); - GetCommands()[ std::string( pszName ) ] = this; - } + DECLARE_SCRIPTDESC( ConCommand ); - ~ConCommand() - { - GetCommands().erase( GetCommands().find( m_pszName ) ); - } + ConCommand( std::string_view pszName, std::string_view pszDescription, ConCommandFunc func, bool bRegisterScript = true ); + ~ConCommand(); void Invoke( std::span args ) { @@ -114,6 +100,16 @@ namespace gamescope m_Func( args ); } + // Calls it with space separated args. + void CallWithArgString( std::string_view args ) + { + std::vector sArgs; + sArgs.push_back( m_pszName ); + Split( sArgs, args, " " ); + + Invoke( sArgs ); + } + static bool Exec( std::span args ); std::string_view GetName() const { return m_pszName; } @@ -126,13 +122,21 @@ namespace gamescope ConCommandFunc m_Func; }; + START_SCRIPTDESC( ConCommand, "concommand" ) + SCRIPTDESC( "name", &ConCommand::m_pszName ) + SCRIPTDESC( "description", &ConCommand::m_pszDescription ) + SCRIPTDESC( "call", &ConCommand::CallWithArgString ) + END_SCRIPTDESC() + template class ConVar : public ConCommand { using ConVarCallbackFunc = std::function &)>; public: - ConVar( std::string_view pszName, T defaultValue = T{}, std::string_view pszDescription = "", ConVarCallbackFunc func = nullptr, bool bRunCallbackAtStartup = false ) - : ConCommand( pszName, pszDescription, [this]( std::span pArgs ){ this->InvokeFunc( pArgs ); } ) + DECLARE_SCRIPTDESC( ConVar ); + + ConVar( std::string_view pszName, T defaultValue = T{}, std::string_view pszDescription = "", ConVarCallbackFunc func = nullptr, bool bRunCallbackAtStartup = false, bool bRegisterScript = true ) + : ConCommand( pszName, pszDescription, [this]( std::span pArgs ){ this->InvokeFunc( pArgs ); }, false ) , m_Value{ defaultValue } , m_Callback{ func } { @@ -140,6 +144,13 @@ namespace gamescope { RunCallback(); } + +#if HAVE_SCRIPTING + if ( bRegisterScript ) + { + CScriptScopedLock().Manager().Gamescope().Convars.Base[pszName] = this; + } +#endif } const T& Get() const @@ -177,6 +188,10 @@ namespace gamescope template bool operator != ( const J &other ) const { return m_Value != other; } template auto operator <=>( const J &other ) const { return m_Value <=> other; } + template bool operator == ( const ConVar &other ) const { return *this == other.Get(); } + template bool operator != ( const ConVar &other ) const { return *this != other.Get(); } + template auto operator <=>( const ConVar &other ) const { return *this <=> other.Get(); } + T operator | (T other) { return m_Value | other; } T &operator |=(T other) { return m_Value |= other; } T operator & (T other) { return m_Value & other; } @@ -221,4 +236,14 @@ namespace gamescope ConVarCallbackFunc m_Callback; bool m_bInCallback; }; + + SCRIPTDESC_TEMPLATE( T ) + START_SCRIPTDESC_ANON( ConVar ) + SCRIPTDESC( "name", &ConVar::m_pszName ) + SCRIPTDESC( "description", &ConVar::m_pszDescription ) + SCRIPTDESC( "call", &ConVar::CallWithArgString ) + + SCRIPTDESC( "value", &ConVar::m_Value ) + END_SCRIPTDESC() + } diff --git a/src/gamescope_shared.h b/src/gamescope_shared.h index 5ce859123c..1ff54bdcff 100644 --- a/src/gamescope_shared.h +++ b/src/gamescope_shared.h @@ -6,15 +6,6 @@ namespace gamescope { class BackendBlob; - enum GamescopeKnownDisplays - { - GAMESCOPE_KNOWN_DISPLAY_UNKNOWN, - GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD, // Jupiter - GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD_DHD, // Jupiter Deck HD - GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_OLED_SDC, // Galileo SDC - GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_OLED_BOE, // Galileo BOE - }; - enum GamescopeModeGeneration { GAMESCOPE_MODE_GENERATE_CVT, diff --git a/src/log.cpp b/src/log.cpp index 50e5bb48c3..7b502a4ae1 100644 --- a/src/log.cpp +++ b/src/log.cpp @@ -104,18 +104,27 @@ void LogScope::vlogf(enum LogPriority priority, const char *fmt, va_list args) return; defer( free(buf); ); + std::string_view svBuf = buf; + log(priority, svBuf); +} + +void LogScope::log(enum LogPriority priority, std::string_view psvText) +{ + if ( !Enabled( priority ) ) + return; + for (auto& listener : m_LoggingListeners) - listener.second( priority, m_psvPrefix, buf ); + listener.second( priority, m_psvPrefix, psvText ); std::string_view psvLogName = GetLogPriorityText( priority ); if ( bPrefixEnabled ) - fprintf(stderr, "[%s] %.*s \e[0;37m%.*s:\e[0m %s\n", + fprintf(stderr, "[%s] %.*s \e[0;37m%.*s:\e[0m %.*s\n", gamescope::Process::GetProcessName(), (int)psvLogName.size(), psvLogName.data(), (int)this->m_psvPrefix.size(), this->m_psvPrefix.data(), - buf); + (int)psvText.size(), psvText.data()); else - fprintf(stderr, "%s\n", buf); + fprintf(stderr, "%.*s\n", (int)psvText.size(), psvText.data()); } void LogScope::logf(enum LogPriority priority, const char *fmt, ...) { diff --git a/src/log.hpp b/src/log.hpp index 5d28da6106..8225b0038e 100644 --- a/src/log.hpp +++ b/src/log.hpp @@ -35,6 +35,7 @@ class LogScope void SetPriority( LogPriority ePriority ) { m_eMaxPriority = ePriority; } void vlogf(enum LogPriority priority, const char *fmt, va_list args) ATTRIB_PRINTF(3, 0); + void log(enum LogPriority priority, std::string_view psvText); void warnf(const char *fmt, ...) ATTRIB_PRINTF(2, 3); void errorf(const char *fmt, ...) ATTRIB_PRINTF(2, 3); @@ -45,7 +46,7 @@ class LogScope bool bPrefixEnabled = true; - using LoggingListenerFunc = std::function; + using LoggingListenerFunc = std::function; std::unordered_map m_LoggingListeners; private: diff --git a/src/main.cpp b/src/main.cpp index a9cdaa2e21..c074f82e2e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,3 +1,5 @@ +#include "Script/Script.h" + #include #include @@ -808,6 +810,11 @@ int main(int argc, char **argv) fprintf( stderr, "Tracing is enabled\n"); } + { + gamescope::CScriptScopedLock script; + script.Manager().RunDefaultScripts(); + } + XInitThreads(); g_mainThread = pthread_self(); diff --git a/src/meson.build b/src/meson.build index 5174de6700..74fc0334d4 100644 --- a/src/meson.build +++ b/src/meson.build @@ -90,6 +90,8 @@ reshade_include = include_directories([ '../thirdparty/SPIRV-Headers/include/spirv/unified1' ]) +sol2_include = include_directories(['../thirdparty']) + required_wlroots_features = ['xwayland'] src = [ @@ -98,6 +100,7 @@ src = [ 'Utils/TempFiles.cpp', 'Utils/Version.cpp', 'Utils/Process.cpp', + 'Script/Script.cpp', 'BufferMemo.cpp', 'steamcompmgr.cpp', 'convar.cpp', @@ -118,6 +121,8 @@ src = [ 'InputEmulation.cpp', ] +luajit_dep = dependency( 'luajit' ) + gamescope_cpp_args = [] if drm_dep.found() src += 'Backends/DRMBackend.cpp' @@ -142,6 +147,7 @@ gamescope_cpp_args += '-DHAVE_SDL2=@0@'.format(sdl2_dep.found().to_int()) gamescope_cpp_args += '-DHAVE_AVIF=@0@'.format(avif_dep.found().to_int()) gamescope_cpp_args += '-DHAVE_LIBCAP=@0@'.format(cap_dep.found().to_int()) gamescope_cpp_args += '-DHAVE_LIBEIS=@0@'.format(eis_dep.found().to_int()) +gamescope_cpp_args += '-DHAVE_SCRIPTING=1' src += spirv_shaders src += protocols_server_src @@ -181,14 +187,14 @@ gamescope_version = configure_file( executable( 'gamescope', src, reshade_src, gamescope_version, - include_directories : [reshade_include], + include_directories : [reshade_include, sol2_include], dependencies: [ dep_wayland, dep_x11, dep_xdamage, dep_xcomposite, dep_xrender, dep_xext, dep_xfixes, dep_xxf86vm, dep_xres, glm_dep, drm_dep, wayland_server, xkbcommon, thread_dep, sdl2_dep, wlroots_dep, vulkan_dep, liftoff_dep, dep_xtst, dep_xmu, cap_dep, epoll_dep, pipewire_dep, librt_dep, stb_dep, displayinfo_dep, openvr_dep, dep_xcursor, avif_dep, dep_xi, - libdecor_dep, eis_dep, + libdecor_dep, eis_dep, luajit_dep ], install: true, cpp_args: gamescope_cpp_args, diff --git a/src/modegen.cpp b/src/modegen.cpp index 5dd113697c..1cf317c6c9 100644 --- a/src/modegen.cpp +++ b/src/modegen.cpp @@ -268,127 +268,13 @@ void generate_cvt_mode(drmModeModeInfo *mode, int hdisplay, int vdisplay, } } -// galielo SDC rev B ds.10 spec'd rates -// fps 45 48 51 55 60 65 72 80 90 -// VFP 1321 1157 993 829 665 501 337 173 9 - -// galielo BOE spec'd rates -// fps 45 48 51 55 60 65 72 80 90 -// VFP 1320 1156 992 828 664 500 336 172 8 - -// SDC VFP values for 45 Hz to 90 Hz -unsigned int galileo_sdc_vfp[] = -{ - 1321,1264,1209,1157,1106,1058,993,967,925,883,829,805,768,732,698, - 665,632,601,571,542,501,486,459,433,408,383,360,337,314,292,271,250,230,210,191, - 173,154,137,119,102,86,70,54,38,23,9 -}; - -// BOE VFP values for 45 Hz to 90 Hz -// BOE Vtotal must be a multiple of 4 -unsigned int galileo_boe_vfp[] = -{ - 1320,1272,1216,1156,1112,1064,992,972,928,888,828,808,772,736,700, - 664,636,604,572,544,500,488,460,436,408,384,360,336,316,292,272,252,228,212,192, - 172,152,136,120,100,84,68,52,36,20,8 -}; - -//SD LCD Stock Timings -#define JUPITER_BOE_PID 0x3001 -#define JUPITER_B_PID 0x3002 -#define JUPITER_HFP 40 -#define JUPITER_HSYNC 4 -#define JUPITER_HBP 40 -#define JUPITER_VFP 30 -#define JUPITER_VSYNC 4 -#define JUPITER_VBP 8 -//SD LCD DeckHD Timings -#define JUPITER_DHD_PID 0x4001 -#define JUPITER_DHD_HFP 40 -#define JUPITER_DHD_HSYNC 20 -#define JUPITER_DHD_HBP 40 -#define JUPITER_DHD_VFP 18 -#define JUPITER_DHD_VSYNC 2 -#define JUPITER_DHD_VBP 20 -//SD OLED SDC Timings -#define GALILEO_SDC_PID 0x3003 -#define GALILEO_SDC_VSYNC 1 -#define GALILEO_SDC_VBP 22 -//SD OLED BOE Timings -#define GALILEO_BOE_PID 0x3004 -#define GALILEO_BOE_VSYNC 2 -#define GALILEO_BOE_VBP 30 -#define GALILEO_MIN_REFRESH 45 -#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) - -unsigned int get_galileo_vfp( int vrefresh, unsigned int * vfp_array, unsigned int num_rates ) -{ - for ( unsigned int i = 0; i < num_rates; i++ ) { - if ( i+GALILEO_MIN_REFRESH == (unsigned int)vrefresh ) { - return vfp_array[i]; - } - } - return 0; -} - -void generate_fixed_mode(drmModeModeInfo *mode, const drmModeModeInfo *base, int vrefresh, gamescope::GamescopeKnownDisplays eKnownDisplay ) +void generate_fixed_mode(drmModeModeInfo *mode, const drmModeModeInfo *base, int vrefresh ) { *mode = *base; if (!vrefresh) vrefresh = 60; - if ( eKnownDisplay == gamescope::GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_OLED_SDC || - eKnownDisplay == gamescope::GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_OLED_BOE ) { - unsigned int vfp = 0, vsync = 0, vbp = 0; - if ( eKnownDisplay == gamescope::GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_OLED_SDC ) - { - vfp = get_galileo_vfp( vrefresh, galileo_sdc_vfp, ARRAY_SIZE(galileo_sdc_vfp) ); - // if we did not find a matching rate then we default to 60 Hz - if ( !vfp ) { - vrefresh = 60; - vfp = 665; - } - vsync = GALILEO_SDC_VSYNC; - vbp = GALILEO_SDC_VBP; - } else if ( eKnownDisplay == gamescope::GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_OLED_BOE ) { // BOE Panel - vfp = get_galileo_vfp( vrefresh, galileo_boe_vfp, ARRAY_SIZE(galileo_boe_vfp) ); - // if we did not find a matching rate then we default to 60 Hz - if ( !vfp ) { - vrefresh = 60; - vfp = 664; - } - vsync = GALILEO_BOE_VSYNC; - vbp = GALILEO_BOE_VBP; - } - mode->vsync_start = mode->vdisplay + vfp; - mode->vsync_end = mode->vsync_start + vsync; - mode->vtotal = mode->vsync_end + vbp; - } else { - if ( eKnownDisplay == gamescope::GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD_DHD ) { - mode->hdisplay = 1200; - mode->hsync_start = mode->hdisplay + JUPITER_DHD_HFP; - mode->hsync_end = mode->hsync_start + JUPITER_DHD_HSYNC; - mode->htotal = mode->hsync_end + JUPITER_DHD_HBP; - - mode->vdisplay = 1920; - mode->vsync_start = mode->vdisplay + JUPITER_DHD_VFP; - mode->vsync_end = mode->vsync_start + JUPITER_DHD_VSYNC; - mode->vtotal = mode->vsync_end + JUPITER_DHD_VBP; - } - else if ( eKnownDisplay == gamescope::GAMESCOPE_KNOWN_DISPLAY_STEAM_DECK_LCD ) - { - mode->hdisplay = 800; - mode->hsync_start = mode->hdisplay + JUPITER_HFP; - mode->hsync_end = mode->hsync_start + JUPITER_HSYNC; - mode->htotal = mode->hsync_end + JUPITER_HBP; - - mode->vdisplay = 1280; - mode->vsync_start = mode->vdisplay + JUPITER_VFP; - mode->vsync_end = mode->vsync_start + JUPITER_VSYNC; - mode->vtotal = mode->vsync_end + JUPITER_VBP; - } - mode->clock = ( ( mode->htotal * mode->vtotal * vrefresh ) + 999 ) / 1000; - } + mode->clock = ( ( mode->htotal * mode->vtotal * vrefresh ) + 999 ) / 1000; mode->vrefresh = (1000 * mode->clock) / (mode->htotal * mode->vtotal); snprintf(mode->name, sizeof(mode->name), "%dx%d@%d.00", mode->hdisplay, mode->vdisplay, vrefresh); diff --git a/src/modegen.hpp b/src/modegen.hpp index 010d9cab33..7c2e690890 100644 --- a/src/modegen.hpp +++ b/src/modegen.hpp @@ -10,4 +10,4 @@ void generate_cvt_mode(drmModeModeInfo *mode, int hdisplay, int vdisplay, float vrefresh, bool reduced, bool interlaced); void generate_fixed_mode(drmModeModeInfo *mode, const drmModeModeInfo *base, - int vrefresh, gamescope::GamescopeKnownDisplays eKnownDisplay); + int vrefresh ); diff --git a/src/reshade_effect_manager.cpp b/src/reshade_effect_manager.cpp index 87f886b140..d9f1d0270b 100644 --- a/src/reshade_effect_manager.cpp +++ b/src/reshade_effect_manager.cpp @@ -36,14 +36,22 @@ static std::mutex g_runtimeUniformsMutex; const char *homedir; -static std::string GetLocalUsrDir() +std::string_view GetHomeDir() { - const char *homedir = nullptr; + static std::string s_sHomeDir = []() -> std::string + { + const char *pszHomeDir = getenv( "HOME" ); + if ( pszHomeDir ) + return pszHomeDir; - if ((homedir = getenv("HOME")) == nullptr) - homedir = getpwuid(getuid())->pw_dir; + return getpwuid( getuid() )->pw_dir; + }(); + return s_sHomeDir; +} - return std::string(homedir) + "/.local"; +static std::string GetLocalUsrDir() +{ + return std::string{ GetHomeDir() } + "/.local"; } static std::string GetUsrDir() diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp index 8c9920e315..22a4d60080 100644 --- a/src/steamcompmgr.cpp +++ b/src/steamcompmgr.cpp @@ -7988,6 +7988,11 @@ steamcompmgr_main(int argc, char **argv) hasRepaint = false; hasRepaintNonBasePlane = false; nIgnoredOverlayRepaints = 0; + + { + gamescope::CScriptScopedLock script; + script.Manager().CallHook( "OnPostPaint" ); + } } if ( bIsVBlankFromTimer ) diff --git a/src/wlserver.cpp b/src/wlserver.cpp index 670cf6896d..0a8ee386ca 100644 --- a/src/wlserver.cpp +++ b/src/wlserver.cpp @@ -1155,11 +1155,14 @@ static const struct gamescope_private_interface gamescope_private_impl = { static void gamescope_private_bind( struct wl_client *client, void *data, uint32_t version, uint32_t id ) { struct wl_resource *resource = wl_resource_create( client, &gamescope_private_interface, version, id ); - console_log.m_LoggingListeners[(uintptr_t)resource] = [ resource ]( LogPriority ePriority, std::string_view psvScope, const char *pText ) + console_log.m_LoggingListeners[(uintptr_t)resource] = [ resource ]( LogPriority ePriority, std::string_view psvScope, std::string_view psvText ) { if ( !wlserver_is_lock_held() ) return; - gamescope_private_send_log( resource, pText ); + + // Can't send a length with string on Wayland api currently... :( + std::string sText = std::string{ psvText }; + gamescope_private_send_log( resource, sText.c_str() ); }; wl_resource_set_implementation( resource, &gamescope_private_impl, NULL, [](struct wl_resource *resource) diff --git a/thirdparty/sol/config.hpp b/thirdparty/sol/config.hpp new file mode 100644 index 0000000000..888c336c13 --- /dev/null +++ b/thirdparty/sol/config.hpp @@ -0,0 +1,55 @@ +// The MIT License (MIT) + +// Copyright (c) 2013-2020 Rapptz, ThePhD and contributors + +// 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. + +// This file was generated with a script. +// Generated 2024-09-03 03:46:49.901324 UTC +// This header was generated with sol v3.3.1 (revision 2b0d2fe8) +// https://github.com/ThePhD/sol2 + +#ifndef SOL_SINGLE_SOL_CONFIG_HPP +#define SOL_SINGLE_SOL_CONFIG_HPP + +// beginning of sol/config.hpp + +/* Base, empty configuration file! + + To override, place a file in your include paths of the form: + +. (your include path here) +| sol (directory, or equivalent) + | config.hpp (your config.hpp file) + + So that when sol2 includes the file + +#include + + it gives you the configuration values you desire. Configuration values can be +seen in the safety.rst of the doc/src, or at +https://sol2.readthedocs.io/en/latest/safety.html ! You can also pass them through +the build system, or the command line options of your compiler. + +*/ + +#define SOL_NO_EXCEPTIONS 1 + +// end of sol/config.hpp + +#endif // SOL_SINGLE_SOL_CONFIG_HPP diff --git a/thirdparty/sol/forward.hpp b/thirdparty/sol/forward.hpp new file mode 100644 index 0000000000..453bcdebf1 --- /dev/null +++ b/thirdparty/sol/forward.hpp @@ -0,0 +1,1340 @@ +// The MIT License (MIT) + +// Copyright (c) 2013-2020 Rapptz, ThePhD and contributors + +// 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. + +// This file was generated with a script. +// Generated 2024-09-03 03:46:49.899874 UTC +// This header was generated with sol v3.3.1 (revision 2b0d2fe8) +// https://github.com/ThePhD/sol2 + +#ifndef SOL_SINGLE_INCLUDE_SOL_FORWARD_HPP +#define SOL_SINGLE_INCLUDE_SOL_FORWARD_HPP + +// beginning of sol/forward.hpp + +#ifndef SOL_FORWARD_HPP +#define SOL_FORWARD_HPP + +// beginning of sol/version.hpp + +#include + +#define SOL_VERSION_MAJOR 3 +#define SOL_VERSION_MINOR 2 +#define SOL_VERSION_PATCH 3 +#define SOL_VERSION_STRING "3.2.3" +#define SOL_VERSION ((SOL_VERSION_MAJOR * 100000) + (SOL_VERSION_MINOR * 100) + (SOL_VERSION_PATCH)) + +#define SOL_TOKEN_TO_STRING_POST_EXPANSION_I_(_TOKEN) #_TOKEN +#define SOL_TOKEN_TO_STRING_I_(_TOKEN) SOL_TOKEN_TO_STRING_POST_EXPANSION_I_(_TOKEN) + +#define SOL_CONCAT_TOKENS_POST_EXPANSION_I_(_LEFT, _RIGHT) _LEFT##_RIGHT +#define SOL_CONCAT_TOKENS_I_(_LEFT, _RIGHT) SOL_CONCAT_TOKENS_POST_EXPANSION_I_(_LEFT, _RIGHT) + +#define SOL_RAW_IS_ON(OP_SYMBOL) ((3 OP_SYMBOL 3) != 0) +#define SOL_RAW_IS_OFF(OP_SYMBOL) ((3 OP_SYMBOL 3) == 0) +#define SOL_RAW_IS_DEFAULT_ON(OP_SYMBOL) ((3 OP_SYMBOL 3) > 3) +#define SOL_RAW_IS_DEFAULT_OFF(OP_SYMBOL) ((3 OP_SYMBOL 3 OP_SYMBOL 3) < 0) + +#define SOL_IS_ON(OP_SYMBOL) SOL_RAW_IS_ON(OP_SYMBOL ## _I_) +#define SOL_IS_OFF(OP_SYMBOL) SOL_RAW_IS_OFF(OP_SYMBOL ## _I_) +#define SOL_IS_DEFAULT_ON(OP_SYMBOL) SOL_RAW_IS_DEFAULT_ON(OP_SYMBOL ## _I_) +#define SOL_IS_DEFAULT_OFF(OP_SYMBOL) SOL_RAW_IS_DEFAULT_OFF(OP_SYMBOL ## _I_) + +#define SOL_ON | +#define SOL_OFF ^ +#define SOL_DEFAULT_ON + +#define SOL_DEFAULT_OFF - + +#if defined(SOL_BUILD_CXX_MODE) + #if (SOL_BUILD_CXX_MODE != 0) + #define SOL_BUILD_CXX_MODE_I_ SOL_ON + #else + #define SOL_BUILD_CXX_MODE_I_ SOL_OFF + #endif +#elif defined(__cplusplus) + #define SOL_BUILD_CXX_MODE_I_ SOL_DEFAULT_ON +#else + #define SOL_BUILD_CXX_MODE_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_BUILD_C_MODE) + #if (SOL_BUILD_C_MODE != 0) + #define SOL_BUILD_C_MODE_I_ SOL_ON + #else + #define SOL_BUILD_C_MODE_I_ SOL_OFF + #endif +#elif defined(__STDC__) + #define SOL_BUILD_C_MODE_I_ SOL_DEFAULT_ON +#else + #define SOL_BUILD_C_MODE_I_ SOL_DEFAULT_OFF +#endif + +#if SOL_IS_ON(SOL_BUILD_C_MODE) + #include + #include + #include +#else + #include + #include + #include +#endif + +#if defined(SOL_HAS_BUILTIN) + #define SOL_HAS_BUILTIN_I_(...) SOL_HAS_BUILTIN(__VA_ARGS__) +#elif defined(__has_builtin) + #define SOL_HAS_BUILTIN_I_(...) __has_builtin(__VA_ARGS__) +#else + #define SOL_HAS_BUILTIN_I_(...) 0 +#endif + +#if defined(SOL_COMPILER_VCXX) + #if (SOL_COMPILER_VCXX != 0) + #define SOL_COMPILER_VCXX_I_ SOL_ON + #else + #define SOL_COMPILER_VCXX_I_ SOL_OFF + #endif +#elif defined(_MSC_VER) + #define SOL_COMPILER_VCXX_I_ SOL_DEFAULT_ON +#else + #define SOL_COMPILER_VCXX_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_COMPILER_GCC) + #if (SOL_COMPILER_GCC != 0) + #define SOL_COMPILER_GCC_I_ SOL_ON + #else + #define SOL_COMPILER_GCC_I_ SOL_OFF + #endif +#elif defined(__GNUC__) + #define SOL_COMPILER_GCC_I_ SOL_DEFAULT_ON +#else + #define SOL_COMPILER_GCC_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_COMPILER_CLANG) + #if (SOL_COMPILER_CLANG != 0) + #define SOL_COMPILER_CLANG_I_ SOL_ON + #else + #define SOL_COMPILER_CLANG_I_ SOL_OFF + #endif +#elif defined(__clang__) + #define SOL_COMPILER_CLANG_I_ SOL_DEFAULT_ON +#else + #define SOL_COMPILER_CLANG_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_COMPILER_EDG) + #if (SOL_COMPILER_EDG != 0) + #define SOL_COMPILER_EDG_I_ SOL_ON + #else + #define SOL_COMPILER_EDG_I_ SOL_OFF + #endif +#else + #define SOL_COMPILER_EDG_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_COMPILER_MINGW) + #if (SOL_COMPILER_MINGW != 0) + #define SOL_COMPILER_MINGW_I_ SOL_ON + #else + #define SOL_COMPILER_MINGW_I_ SOL_OFF + #endif +#elif defined(__MINGW32__) + #define SOL_COMPILER_MINGW_I_ SOL_DEFAULT_ON +#else + #define SOL_COMPILER_MINGW_I_ SOL_DEFAULT_OFF +#endif + +#if SIZE_MAX <= 0xFFFFULL + #define SOL_PLATFORM_X16_I_ SOL_ON + #define SOL_PLATFORM_X86_I_ SOL_OFF + #define SOL_PLATFORM_X64_I_ SOL_OFF +#elif SIZE_MAX <= 0xFFFFFFFFULL + #define SOL_PLATFORM_X16_I_ SOL_OFF + #define SOL_PLATFORM_X86_I_ SOL_ON + #define SOL_PLATFORM_X64_I_ SOL_OFF +#else + #define SOL_PLATFORM_X16_I_ SOL_OFF + #define SOL_PLATFORM_X86_I_ SOL_OFF + #define SOL_PLATFORM_X64_I_ SOL_ON +#endif + +#define SOL_PLATFORM_ARM32_I_ SOL_OFF +#define SOL_PLATFORM_ARM64_I_ SOL_OFF + +#if defined(SOL_PLATFORM_WINDOWS) + #if (SOL_PLATFORM_WINDOWS != 0) + #define SOL_PLATFORM_WINDOWS_I_ SOL_ON + #else + #define SOL_PLATFORM_WINDOWS_I_ SOL_OFF + #endif +#elif defined(_WIN32) + #define SOL_PLATFORM_WINDOWS_I_ SOL_DEFAULT_ON +#else + #define SOL_PLATFORM_WINDOWS_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_PLATFORM_CYGWIN) + #if (SOL_PLATFORM_CYGWIN != 0) + #define SOL_PLATFORM_CYGWIN_I_ SOL_ON + #else + #define SOL_PLATFORM_CYGWIN_I_ SOL_ON + #endif +#elif defined(__CYGWIN__) + #define SOL_PLATFORM_CYGWIN_I_ SOL_DEFAULT_ON +#else + #define SOL_PLATFORM_CYGWIN_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_PLATFORM_APPLE) + #if (SOL_PLATFORM_APPLE != 0) + #define SOL_PLATFORM_APPLE_I_ SOL_ON + #else + #define SOL_PLATFORM_APPLE_I_ SOL_OFF + #endif +#elif defined(__APPLE__) + #define SOL_PLATFORM_APPLE_I_ SOL_DEFAULT_ON +#else + #define SOL_PLATFORM_APPLE_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_PLATFORM_UNIX) + #if (SOL_PLATFORM_UNIX != 0) + #define SOL_PLATFORM_UNIXLIKE_I_ SOL_ON + #else + #define SOL_PLATFORM_UNIXLIKE_I_ SOL_OFF + #endif +#elif defined(__unix__) + #define SOL_PLATFORM_UNIXLIKE_I_ SOL_DEFAULT_ON +#else + #define SOL_PLATFORM_UNIXLIKE_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_PLATFORM_LINUX) + #if (SOL_PLATFORM_LINUX != 0) + #define SOL_PLATFORM_LINUXLIKE_I_ SOL_ON + #else + #define SOL_PLATFORM_LINUXLIKE_I_ SOL_OFF + #endif +#elif defined(__LINUX__) + #define SOL_PLATFORM_LINUXLIKE_I_ SOL_DEFAULT_ON +#else + #define SOL_PLATFORM_LINUXLIKE_I_ SOL_DEFAULT_OFF +#endif + +#define SOL_PLATFORM_APPLE_IPHONE_I_ SOL_OFF +#define SOL_PLATFORM_BSDLIKE_I_ SOL_OFF + +#if defined(SOL_IN_DEBUG_DETECTED) + #if (SOL_IN_DEBUG_DETECTED != 0) + #define SOL_DEBUG_BUILD_I_ SOL_ON + #else + #define SOL_DEBUG_BUILD_I_ SOL_OFF + #endif +#elif !defined(NDEBUG) + #if SOL_IS_ON(SOL_COMPILER_VCXX) && defined(_DEBUG) + #define SOL_DEBUG_BUILD_I_ SOL_ON + #elif (SOL_IS_ON(SOL_COMPILER_CLANG) || SOL_IS_ON(SOL_COMPILER_GCC)) && !defined(__OPTIMIZE__) + #define SOL_DEBUG_BUILD_I_ SOL_ON + #else + #define SOL_DEBUG_BUILD_I_ SOL_OFF + #endif +#else + #define SOL_DEBUG_BUILD_I_ SOL_DEFAULT_OFF +#endif // We are in a debug mode of some sort + +#if defined(SOL_NO_EXCEPTIONS) + #if (SOL_NO_EXCEPTIONS != 0) + #define SOL_EXCEPTIONS_I_ SOL_OFF + #else + #define SOL_EXCEPTIONS_I_ SOL_ON + #endif +#elif SOL_IS_ON(SOL_COMPILER_VCXX) + #if !defined(_CPPUNWIND) + #define SOL_EXCEPTIONS_I_ SOL_OFF + #else + #define SOL_EXCEPTIONS_I_ SOL_ON + #endif +#elif SOL_IS_ON(SOL_COMPILER_CLANG) || SOL_IS_ON(SOL_COMPILER_GCC) + #if !defined(__EXCEPTIONS) + #define SOL_EXCEPTIONS_I_ SOL_OFF + #else + #define SOL_EXCEPTIONS_I_ SOL_ON + #endif +#else + #define SOL_EXCEPTIONS_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_NO_RTTI) + #if (SOL_NO_RTTI != 0) + #define SOL_RTTI_I_ SOL_OFF + #else + #define SOL_RTTI_I_ SOL_ON + #endif +#elif SOL_IS_ON(SOL_COMPILER_VCXX) + #if !defined(_CPPRTTI) + #define SOL_RTTI_I_ SOL_OFF + #else + #define SOL_RTTI_I_ SOL_ON + #endif +#elif SOL_IS_ON(SOL_COMPILER_CLANG) || SOL_IS_ON(SOL_COMPILER_GCC) + #if !defined(__GXX_RTTI) + #define SOL_RTTI_I_ SOL_OFF + #else + #define SOL_RTTI_I_ SOL_ON + #endif +#else + #define SOL_RTTI_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_NO_THREAD_LOCAL) + #if (SOL_NO_THREAD_LOCAL != 0) + #define SOL_USE_THREAD_LOCAL_I_ SOL_OFF + #else + #define SOL_USE_THREAD_LOCAL_I_ SOL_ON + #endif +#else + #define SOL_USE_THREAD_LOCAL_I_ SOL_DEFAULT_ON +#endif // thread_local keyword is bjorked on some platforms + +#if defined(SOL_ALL_SAFETIES_ON) + #if (SOL_ALL_SAFETIES_ON != 0) + #define SOL_ALL_SAFETIES_ON_I_ SOL_ON + #else + #define SOL_ALL_SAFETIES_ON_I_ SOL_OFF + #endif +#else + #define SOL_ALL_SAFETIES_ON_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_SAFE_GETTER) + #if (SOL_SAFE_GETTER != 0) + #define SOL_SAFE_GETTER_I_ SOL_ON + #else + #define SOL_SAFE_GETTER_I_ SOL_OFF + #endif +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON) + #define SOL_SAFE_GETTER_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD) + #define SOL_SAFE_GETTER_I_ SOL_DEFAULT_ON + #else + #define SOL_SAFE_GETTER_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_SAFE_USERTYPE) + #if (SOL_SAFE_USERTYPE != 0) + #define SOL_SAFE_USERTYPE_I_ SOL_ON + #else + #define SOL_SAFE_USERTYPE_I_ SOL_OFF + #endif +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON) + #define SOL_SAFE_USERTYPE_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD) + #define SOL_SAFE_USERTYPE_I_ SOL_DEFAULT_ON + #else + #define SOL_SAFE_USERTYPE_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_SAFE_REFERENCES) + #if (SOL_SAFE_REFERENCES != 0) + #define SOL_SAFE_REFERENCES_I_ SOL_ON + #else + #define SOL_SAFE_REFERENCES_I_ SOL_OFF + #endif +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON) + #define SOL_SAFE_REFERENCES_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD) + #define SOL_SAFE_REFERENCES_I_ SOL_DEFAULT_ON + #else + #define SOL_SAFE_REFERENCES_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_SAFE_FUNCTIONS) + #if (SOL_SAFE_FUNCTIONS != 0) + #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_ON + #else + #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_OFF + #endif +#elif defined (SOL_SAFE_FUNCTION_OBJECTS) + #if (SOL_SAFE_FUNCTION_OBJECTS != 0) + #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_ON + #else + #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_OFF + #endif +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON) + #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD) + #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_DEFAULT_ON + #else + #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_SAFE_FUNCTION_CALLS) + #if (SOL_SAFE_FUNCTION_CALLS != 0) + #define SOL_SAFE_FUNCTION_CALLS_I_ SOL_ON + #else + #define SOL_SAFE_FUNCTION_CALLS_I_ SOL_OFF + #endif +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON) + #define SOL_SAFE_FUNCTION_CALLS_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD) + #define SOL_SAFE_FUNCTION_CALLS_I_ SOL_DEFAULT_ON + #else + #define SOL_SAFE_FUNCTION_CALLS_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_SAFE_PROXIES) + #if (SOL_SAFE_PROXIES != 0) + #define SOL_SAFE_PROXIES_I_ SOL_ON + #else + #define SOL_SAFE_PROXIES_I_ SOL_OFF + #endif +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON) + #define SOL_SAFE_PROXIES_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD) + #define SOL_SAFE_PROXIES_I_ SOL_DEFAULT_ON + #else + #define SOL_SAFE_PROXIES_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_SAFE_NUMERICS) + #if (SOL_SAFE_NUMERICS != 0) + #define SOL_SAFE_NUMERICS_I_ SOL_ON + #else + #define SOL_SAFE_NUMERICS_I_ SOL_OFF + #endif +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON) + #define SOL_SAFE_NUMERICS_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD) + #define SOL_SAFE_NUMERICS_I_ SOL_DEFAULT_ON + #else + #define SOL_SAFE_NUMERICS_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_ALL_INTEGER_VALUES_FIT) + #if (SOL_ALL_INTEGER_VALUES_FIT != 0) + #define SOL_ALL_INTEGER_VALUES_FIT_I_ SOL_ON + #else + #define SOL_ALL_INTEGER_VALUES_FIT_I_ SOL_OFF + #endif +#elif !SOL_IS_DEFAULT_OFF(SOL_SAFE_NUMERICS) && SOL_IS_OFF(SOL_SAFE_NUMERICS) + // if numerics is intentionally turned off, flip this on + #define SOL_ALL_INTEGER_VALUES_FIT_I_ SOL_DEFAULT_ON +#else + // default to off + #define SOL_ALL_INTEGER_VALUES_FIT_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_SAFE_STACK_CHECK) + #if (SOL_SAFE_STACK_CHECK != 0) + #define SOL_SAFE_STACK_CHECK_I_ SOL_ON + #else + #define SOL_SAFE_STACK_CHECK_I_ SOL_OFF + #endif +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON) + #define SOL_SAFE_STACK_CHECK_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD) + #define SOL_SAFE_STACK_CHECK_I_ SOL_DEFAULT_ON + #else + #define SOL_SAFE_STACK_CHECK_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_NO_CHECK_NUMBER_PRECISION) + #if (SOL_NO_CHECK_NUMBER_PRECISION != 0) + #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_OFF + #else + #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_ON + #endif +#elif defined(SOL_NO_CHECKING_NUMBER_PRECISION) + #if (SOL_NO_CHECKING_NUMBER_PRECISION != 0) + #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_OFF + #else + #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_ON + #endif +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON) + #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_ON + #elif SOL_IS_ON(SOL_SAFE_NUMERICS) + #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD) + #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_DEFAULT_ON + #else + #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_STRINGS_ARE_NUMBERS) + #if (SOL_STRINGS_ARE_NUMBERS != 0) + #define SOL_STRINGS_ARE_NUMBERS_I_ SOL_ON + #else + #define SOL_STRINGS_ARE_NUMBERS_I_ SOL_OFF + #endif +#else + #define SOL_STRINGS_ARE_NUMBERS_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_ENABLE_INTEROP) + #if (SOL_ENABLE_INTEROP != 0) + #define SOL_USE_INTEROP_I_ SOL_ON + #else + #define SOL_USE_INTEROP_I_ SOL_OFF + #endif +#elif defined(SOL_USE_INTEROP) + #if (SOL_USE_INTEROP != 0) + #define SOL_USE_INTEROP_I_ SOL_ON + #else + #define SOL_USE_INTEROP_I_ SOL_OFF + #endif +#else + #define SOL_USE_INTEROP_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_NO_NIL) + #if (SOL_NO_NIL != 0) + #define SOL_NIL_I_ SOL_OFF + #else + #define SOL_NIL_I_ SOL_ON + #endif +#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED) || defined(__OBJC__) || defined(nil) + #define SOL_NIL_I_ SOL_DEFAULT_OFF +#else + #define SOL_NIL_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_USERTYPE_TYPE_BINDING_INFO) + #if (SOL_USERTYPE_TYPE_BINDING_INFO != 0) + #define SOL_USERTYPE_TYPE_BINDING_INFO_I_ SOL_ON + #else + #define SOL_USERTYPE_TYPE_BINDING_INFO_I_ SOL_OFF + #endif +#else + #define SOL_USERTYPE_TYPE_BINDING_INFO_I_ SOL_DEFAULT_ON +#endif // We should generate a my_type.__type table with lots of class information for usertypes + +#if defined(SOL_AUTOMAGICAL_TYPES_BY_DEFAULT) + #if (SOL_AUTOMAGICAL_TYPES_BY_DEFAULT != 0) + #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_ON + #else + #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_OFF + #endif +#elif defined(SOL_DEFAULT_AUTOMAGICAL_USERTYPES) + #if (SOL_DEFAULT_AUTOMAGICAL_USERTYPES != 0) + #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_ON + #else + #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_OFF + #endif +#else + #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_DEFAULT_ON +#endif // make is_automagical on/off by default + +#if defined(SOL_STD_VARIANT) + #if (SOL_STD_VARIANT != 0) + #define SOL_STD_VARIANT_I_ SOL_ON + #else + #define SOL_STD_VARIANT_I_ SOL_OFF + #endif +#else + #if SOL_IS_ON(SOL_COMPILER_CLANG) && SOL_IS_ON(SOL_PLATFORM_APPLE) + #if defined(__has_include) + #if __has_include() + #define SOL_STD_VARIANT_I_ SOL_DEFAULT_ON + #else + #define SOL_STD_VARIANT_I_ SOL_DEFAULT_OFF + #endif + #else + #define SOL_STD_VARIANT_I_ SOL_DEFAULT_OFF + #endif + #else + #define SOL_STD_VARIANT_I_ SOL_DEFAULT_ON + #endif +#endif // make is_automagical on/off by default + +#if defined(SOL_NOEXCEPT_FUNCTION_TYPE) + #if (SOL_NOEXCEPT_FUNCTION_TYPE != 0) + #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_ON + #else + #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_OFF + #endif +#else + #if defined(__cpp_noexcept_function_type) + #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_ON + #elif SOL_IS_ON(SOL_COMPILER_VCXX) && (defined(_MSVC_LANG) && (_MSVC_LANG < 201403L)) + // There is a bug in the VC++ compiler?? + // on /std:c++latest under x86 conditions (VS 15.5.2), + // compiler errors are tossed for noexcept markings being on function types + // that are identical in every other way to their non-noexcept marked types function types... + // VS 2019: There is absolutely a bug. + #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_OFF + #else + #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_DEFAULT_ON + #endif +#endif // noexcept is part of a function's type + +#if defined(SOL_STACK_STRING_OPTIMIZATION_SIZE) && (SOL_STACK_STRING_OPTIMIZATION_SIZE > 0) + #define SOL_OPTIMIZATION_STRING_CONVERSION_STACK_SIZE_I_ SOL_STACK_STRING_OPTIMIZATION_SIZE +#else + #define SOL_OPTIMIZATION_STRING_CONVERSION_STACK_SIZE_I_ 1024 +#endif + +#if defined(SOL_ID_SIZE) && (SOL_ID_SIZE > 0) + #define SOL_ID_SIZE_I_ SOL_ID_SIZE +#else + #define SOL_ID_SIZE_I_ 512 +#endif + +#if defined(LUA_IDSIZE) && (LUA_IDSIZE > 0) + #define SOL_FILE_ID_SIZE_I_ LUA_IDSIZE +#elif defined(SOL_ID_SIZE) && SOL_ID_SIZE > 0 + #define SOL_FILE_ID_SIZE_I_ SOL_FILE_ID_SIZE +#else + #define SOL_FILE_ID_SIZE_I_ 2048 +#endif + +#if defined(SOL_PRINT_ERRORS) + #if (SOL_PRINT_ERRORS != 0) + #define SOL_PRINT_ERRORS_I_ SOL_ON + #else + #define SOL_PRINT_ERRORS_I_ SOL_OFF + #endif +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON) + #define SOL_PRINT_ERRORS_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD) + #define SOL_PRINT_ERRORS_I_ SOL_DEFAULT_ON + #else + #define SOL_PRINT_ERRORS_I_ SOL_OFF + #endif +#endif + +#if defined(SOL_DEFAULT_PASS_ON_ERROR) + #if (SOL_DEFAULT_PASS_ON_ERROR != 0) + #define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_ON + #else + #define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_OFF + #endif +#else + #define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_USING_CXX_LUA) + #if (SOL_USING_CXX_LUA != 0) + #define SOL_USING_CXX_LUA_I_ SOL_ON + #else + #define SOL_USING_CXX_LUA_I_ SOL_OFF + #endif +#elif defined(SOL_USE_CXX_LUA) + // alternative spelling + #if (SOL_USE_CXX_LUA != 0) + #define SOL_USING_CXX_LUA_I_ SOL_ON + #else + #define SOL_USING_CXX_LUA_I_ SOL_OFF + #endif +#else + #define SOL_USING_CXX_LUA_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_USING_CXX_LUAJIT) + #if (SOL_USING_CXX_LUAJIT != 0) + #define SOL_USING_CXX_LUAJIT_I_ SOL_ON + #else + #define SOL_USING_CXX_LUAJIT_I_ SOL_OFF + #endif +#elif defined(SOL_USE_CXX_LUAJIT) + #if (SOL_USE_CXX_LUAJIT != 0) + #define SOL_USING_CXX_LUAJIT_I_ SOL_ON + #else + #define SOL_USING_CXX_LUAJIT_I_ SOL_OFF + #endif +#else + #define SOL_USING_CXX_LUAJIT_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_NO_LUA_HPP) + #if (SOL_NO_LUA_HPP != 0) + #define SOL_USE_LUA_HPP_I_ SOL_OFF + #else + #define SOL_USE_LUA_HPP_I_ SOL_ON + #endif +#elif SOL_IS_ON(SOL_USING_CXX_LUA) + #define SOL_USE_LUA_HPP_I_ SOL_OFF +#elif defined(__has_include) + #if __has_include() + #define SOL_USE_LUA_HPP_I_ SOL_ON + #else + #define SOL_USE_LUA_HPP_I_ SOL_OFF + #endif +#else + #define SOL_USE_LUA_HPP_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_CONTAINERS_START) + #define SOL_CONTAINER_START_INDEX_I_ SOL_CONTAINERS_START +#elif defined(SOL_CONTAINERS_START_INDEX) + #define SOL_CONTAINER_START_INDEX_I_ SOL_CONTAINERS_START_INDEX +#elif defined(SOL_CONTAINER_START_INDEX) + #define SOL_CONTAINER_START_INDEX_I_ SOL_CONTAINER_START_INDEX +#else + #define SOL_CONTAINER_START_INDEX_I_ 1 +#endif + +#if defined (SOL_NO_MEMORY_ALIGNMENT) + #if (SOL_NO_MEMORY_ALIGNMENT != 0) + #define SOL_ALIGN_MEMORY_I_ SOL_OFF + #else + #define SOL_ALIGN_MEMORY_I_ SOL_ON + #endif +#else + #define SOL_ALIGN_MEMORY_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_USE_BOOST) + #if (SOL_USE_BOOST != 0) + #define SOL_USE_BOOST_I_ SOL_ON + #else + #define SOL_USE_BOOST_I_ SOL_OFF + #endif +#else + #define SOL_USE_BOOST_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_USE_UNSAFE_BASE_LOOKUP) + #if (SOL_USE_UNSAFE_BASE_LOOKUP != 0) + #define SOL_USE_UNSAFE_BASE_LOOKUP_I_ SOL_ON + #else + #define SOL_USE_UNSAFE_BASE_LOOKUP_I_ SOL_OFF + #endif +#else + #define SOL_USE_UNSAFE_BASE_LOOKUP_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_INSIDE_UNREAL) + #if (SOL_INSIDE_UNREAL != 0) + #define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_ON + #else + #define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_OFF + #endif +#else + #if defined(UE_BUILD_DEBUG) || defined(UE_BUILD_DEVELOPMENT) || defined(UE_BUILD_TEST) || defined(UE_BUILD_SHIPPING) || defined(UE_SERVER) + #define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_DEFAULT_ON + #else + #define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_NO_COMPAT) + #if (SOL_NO_COMPAT != 0) + #define SOL_USE_COMPATIBILITY_LAYER_I_ SOL_OFF + #else + #define SOL_USE_COMPATIBILITY_LAYER_I_ SOL_ON + #endif +#else + #define SOL_USE_COMPATIBILITY_LAYER_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_GET_FUNCTION_POINTER_UNSAFE) + #if (SOL_GET_FUNCTION_POINTER_UNSAFE != 0) + #define SOL_GET_FUNCTION_POINTER_UNSAFE_I_ SOL_ON + #else + #define SOL_GET_FUNCTION_POINTER_UNSAFE_I_ SOL_OFF + #endif +#else + #define SOL_GET_FUNCTION_POINTER_UNSAFE_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_CONTAINER_CHECK_IS_EXHAUSTIVE) + #if (SOL_CONTAINER_CHECK_IS_EXHAUSTIVE != 0) + #define SOL_CONTAINER_CHECK_IS_EXHAUSTIVE_I_ SOL_ON + #else + #define SOL_CONTAINER_CHECK_IS_EXHAUSTIVE_I_ SOL_OFF + #endif +#else + #define SOL_CONTAINER_CHECK_IS_EXHAUSTIVE_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_FUNCTION_CALL_VALUE_SEMANTICS) + #if (SOL_FUNCTION_CALL_VALUE_SEMANTICS != 0) + #define SOL_FUNCTION_CALL_VALUE_SEMANTICS_I_ SOL_ON + #else + #define SOL_FUNCTION_CALL_VALUE_SEMANTICS_I_ SOL_OFF + #endif +#else + #define SOL_FUNCTION_CALL_VALUE_SEMANTICS_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_MINGW_CCTYPE_IS_POISONED) + #if (SOL_MINGW_CCTYPE_IS_POISONED != 0) + #define SOL_MINGW_CCTYPE_IS_POISONED_I_ SOL_ON + #else + #define SOL_MINGW_CCTYPE_IS_POISONED_I_ SOL_OFF + #endif +#elif SOL_IS_ON(SOL_COMPILER_MINGW) && defined(__GNUC__) && (__GNUC__ < 6) + // MinGW is off its rocker in some places... + #define SOL_MINGW_CCTYPE_IS_POISONED_I_ SOL_DEFAULT_ON +#else + #define SOL_MINGW_CCTYPE_IS_POISONED_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_CHAR8_T) + #if (SOL_CHAR8_T != 0) + #define SOL_CHAR8_T_I_ SOL_ON + #else + #define SOL_CHAR8_T_I_ SOL_OFF + #endif +#else + #if defined(__cpp_char8_t) + #define SOL_CHAR8_T_I_ SOL_DEFAULT_ON + #else + #define SOL_CHAR8_T_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if SOL_IS_ON(SOL_USE_BOOST) + #include + + #if BOOST_VERSION >= 107500 // Since Boost 1.75.0 boost::none is constexpr + #define SOL_BOOST_NONE_CONSTEXPR_I_ constexpr + #else + #define SOL_BOOST_NONE_CONSTEXPR_I_ const + #endif // BOOST_VERSION +#else + // assume boost isn't using a garbage version + #define SOL_BOOST_NONE_CONSTEXPR_I_ constexpr +#endif + +#if defined(SOL2_CI) + #if (SOL2_CI != 0) + #define SOL2_CI_I_ SOL_ON + #else + #define SOL2_CI_I_ SOL_OFF + #endif +#else + #define SOL2_CI_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_ASSERT) + #define SOL_USER_ASSERT_I_ SOL_ON +#else + #define SOL_USER_ASSERT_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_ASSERT_MSG) + #define SOL_USER_ASSERT_MSG_I_ SOL_ON +#else + #define SOL_USER_ASSERT_MSG_I_ SOL_DEFAULT_OFF +#endif + +// beginning of sol/prologue.hpp + +#if defined(SOL_PROLOGUE_I_) + #error "[sol2] Library Prologue was already included in translation unit and not properly ended with an epilogue." +#endif + +#define SOL_PROLOGUE_I_ 1 + +#if SOL_IS_ON(SOL_BUILD_CXX_MODE) + #define _FWD(...) static_cast( __VA_ARGS__ ) + + #if SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG) + #define _MOVE(...) static_cast<__typeof( __VA_ARGS__ )&&>( __VA_ARGS__ ) + #else + #include + + #define _MOVE(...) static_cast<::std::remove_reference_t<( __VA_ARGS__ )>&&>( __VA_OPT__(,) ) + #endif +#endif + +// end of sol/prologue.hpp + +// beginning of sol/epilogue.hpp + +#if !defined(SOL_PROLOGUE_I_) + #error "[sol2] Library Prologue is missing from this translation unit." +#else + #undef SOL_PROLOGUE_I_ +#endif + +#if SOL_IS_ON(SOL_BUILD_CXX_MODE) + #undef _FWD + #undef _MOVE +#endif + +// end of sol/epilogue.hpp + +// beginning of sol/detail/build_version.hpp + +#if defined(SOL_DLL) + #if (SOL_DLL != 0) + #define SOL_DLL_I_ SOL_ON + #else + #define SOL_DLL_I_ SOL_OFF + #endif +#elif SOL_IS_ON(SOL_COMPILER_VCXX) && (defined(DLL_) || defined(_DLL)) + #define SOL_DLL_I_ SOL_DEFAULT_ON +#else + #define SOL_DLL_I_ SOL_DEFAULT_OFF +#endif // DLL definition + +#if defined(SOL_HEADER_ONLY) + #if (SOL_HEADER_ONLY != 0) + #define SOL_HEADER_ONLY_I_ SOL_ON + #else + #define SOL_HEADER_ONLY_I_ SOL_OFF + #endif +#else + #define SOL_HEADER_ONLY_I_ SOL_DEFAULT_OFF +#endif // Header only library + +#if defined(SOL_BUILD) + #if (SOL_BUILD != 0) + #define SOL_BUILD_I_ SOL_ON + #else + #define SOL_BUILD_I_ SOL_OFF + #endif +#elif SOL_IS_ON(SOL_HEADER_ONLY) + #define SOL_BUILD_I_ SOL_DEFAULT_OFF +#else + #define SOL_BUILD_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_UNITY_BUILD) + #if (SOL_UNITY_BUILD != 0) + #define SOL_UNITY_BUILD_I_ SOL_ON + #else + #define SOL_UNITY_BUILD_I_ SOL_OFF + #endif +#else + #define SOL_UNITY_BUILD_I_ SOL_DEFAULT_OFF +#endif // Header only library + +#if defined(SOL_C_FUNCTION_LINKAGE) + #define SOL_C_FUNCTION_LINKAGE_I_ SOL_C_FUNCTION_LINKAGE +#else + #if SOL_IS_ON(SOL_BUILD_CXX_MODE) + // C++ + #define SOL_C_FUNCTION_LINKAGE_I_ extern "C" + #else + // normal + #define SOL_C_FUNCTION_LINKAGE_I_ + #endif // C++ or not +#endif // Linkage specification for C functions + +#if defined(SOL_API_LINKAGE) + #define SOL_API_LINKAGE_I_ SOL_API_LINKAGE +#else + #if SOL_IS_ON(SOL_DLL) + #if SOL_IS_ON(SOL_COMPILER_VCXX) || SOL_IS_ON(SOL_PLATFORM_WINDOWS) || SOL_IS_ON(SOL_PLATFORM_CYGWIN) + // MSVC Compiler; or, Windows, or Cygwin platforms + #if SOL_IS_ON(SOL_BUILD) + // Building the library + #if SOL_IS_ON(SOL_COMPILER_GCC) + // Using GCC + #define SOL_API_LINKAGE_I_ __attribute__((dllexport)) + #else + // Using Clang, MSVC, etc... + #define SOL_API_LINKAGE_I_ __declspec(dllexport) + #endif + #else + #if SOL_IS_ON(SOL_COMPILER_GCC) + #define SOL_API_LINKAGE_I_ __attribute__((dllimport)) + #else + #define SOL_API_LINKAGE_I_ __declspec(dllimport) + #endif + #endif + #else + // extern if building normally on non-MSVC + #define SOL_API_LINKAGE_I_ extern + #endif + #elif SOL_IS_ON(SOL_UNITY_BUILD) + // Built-in library, like how stb typical works + #if SOL_IS_ON(SOL_HEADER_ONLY) + // Header only, so functions are defined "inline" + #define SOL_API_LINKAGE_I_ inline + #else + // Not header only, so seperately compiled files + #define SOL_API_LINKAGE_I_ extern + #endif + #else + // Normal static library + #if SOL_IS_ON(SOL_BUILD_CXX_MODE) + #define SOL_API_LINKAGE_I_ + #else + #define SOL_API_LINKAGE_I_ extern + #endif + #endif // DLL or not +#endif // Build definitions + +#if defined(SOL_PUBLIC_FUNC_DECL) + #define SOL_PUBLIC_FUNC_DECL_I_ SOL_PUBLIC_FUNC_DECL +#else + #define SOL_PUBLIC_FUNC_DECL_I_ SOL_API_LINKAGE_I_ +#endif + +#if defined(SOL_INTERNAL_FUNC_DECL_) + #define SOL_INTERNAL_FUNC_DECL_I_ SOL_INTERNAL_FUNC_DECL_ +#else + #define SOL_INTERNAL_FUNC_DECL_I_ SOL_API_LINKAGE_I_ +#endif + +#if defined(SOL_PUBLIC_FUNC_DEF) + #define SOL_PUBLIC_FUNC_DEF_I_ SOL_PUBLIC_FUNC_DEF +#else + #define SOL_PUBLIC_FUNC_DEF_I_ SOL_API_LINKAGE_I_ +#endif + +#if defined(SOL_INTERNAL_FUNC_DEF) + #define SOL_INTERNAL_FUNC_DEF_I_ SOL_INTERNAL_FUNC_DEF +#else + #define SOL_INTERNAL_FUNC_DEF_I_ SOL_API_LINKAGE_I_ +#endif + +#if defined(SOL_FUNC_DECL) + #define SOL_FUNC_DECL_I_ SOL_FUNC_DECL +#elif SOL_IS_ON(SOL_HEADER_ONLY) + #define SOL_FUNC_DECL_I_ +#elif SOL_IS_ON(SOL_DLL) + #if SOL_IS_ON(SOL_COMPILER_VCXX) + #if SOL_IS_ON(SOL_BUILD) + #define SOL_FUNC_DECL_I_ extern __declspec(dllexport) + #else + #define SOL_FUNC_DECL_I_ extern __declspec(dllimport) + #endif + #elif SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG) + #define SOL_FUNC_DECL_I_ extern __attribute__((visibility("default"))) + #else + #define SOL_FUNC_DECL_I_ extern + #endif +#endif + +#if defined(SOL_FUNC_DEFN) + #define SOL_FUNC_DEFN_I_ SOL_FUNC_DEFN +#elif SOL_IS_ON(SOL_HEADER_ONLY) + #define SOL_FUNC_DEFN_I_ inline +#elif SOL_IS_ON(SOL_DLL) + #if SOL_IS_ON(SOL_COMPILER_VCXX) + #if SOL_IS_ON(SOL_BUILD) + #define SOL_FUNC_DEFN_I_ __declspec(dllexport) + #else + #define SOL_FUNC_DEFN_I_ __declspec(dllimport) + #endif + #elif SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG) + #define SOL_FUNC_DEFN_I_ __attribute__((visibility("default"))) + #else + #define SOL_FUNC_DEFN_I_ + #endif +#endif + +#if defined(SOL_HIDDEN_FUNC_DECL) + #define SOL_HIDDEN_FUNC_DECL_I_ SOL_HIDDEN_FUNC_DECL +#elif SOL_IS_ON(SOL_HEADER_ONLY) + #define SOL_HIDDEN_FUNC_DECL_I_ +#elif SOL_IS_ON(SOL_DLL) + #if SOL_IS_ON(SOL_COMPILER_VCXX) + #if SOL_IS_ON(SOL_BUILD) + #define SOL_HIDDEN_FUNC_DECL_I_ extern __declspec(dllexport) + #else + #define SOL_HIDDEN_FUNC_DECL_I_ extern __declspec(dllimport) + #endif + #elif SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG) + #define SOL_HIDDEN_FUNC_DECL_I_ extern __attribute__((visibility("default"))) + #else + #define SOL_HIDDEN_FUNC_DECL_I_ extern + #endif +#endif + +#if defined(SOL_HIDDEN_FUNC_DEFN) + #define SOL_HIDDEN_FUNC_DEFN_I_ SOL_HIDDEN_FUNC_DEFN +#elif SOL_IS_ON(SOL_HEADER_ONLY) + #define SOL_HIDDEN_FUNC_DEFN_I_ inline +#elif SOL_IS_ON(SOL_DLL) + #if SOL_IS_ON(SOL_COMPILER_VCXX) + #if SOL_IS_ON(SOL_BUILD) + #define SOL_HIDDEN_FUNC_DEFN_I_ + #else + #define SOL_HIDDEN_FUNC_DEFN_I_ + #endif + #elif SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG) + #define SOL_HIDDEN_FUNC_DEFN_I_ __attribute__((visibility("hidden"))) + #else + #define SOL_HIDDEN_FUNC_DEFN_I_ + #endif +#endif + +// end of sol/detail/build_version.hpp + +// end of sol/version.hpp + +#include +#include +#include + +#if SOL_IS_ON(SOL_USING_CXX_LUA) || SOL_IS_ON(SOL_USING_CXX_LUAJIT) +struct lua_State; +#else +extern "C" { +struct lua_State; +} +#endif // C++ Mangling for Lua vs. Not + +namespace sol { + + enum class type; + + class stateless_reference; + template + class basic_reference; + using reference = basic_reference; + using main_reference = basic_reference; + class stateless_stack_reference; + class stack_reference; + + template + class basic_bytecode; + + struct lua_value; + + struct proxy_base_tag; + template + struct proxy_base; + template + struct table_proxy; + + template + class basic_table_core; + template + using table_core = basic_table_core; + template + using main_table_core = basic_table_core; + template + using stack_table_core = basic_table_core; + template + using basic_table = basic_table_core; + using table = table_core; + using global_table = table_core; + using main_table = main_table_core; + using main_global_table = main_table_core; + using stack_table = stack_table_core; + using stack_global_table = stack_table_core; + + template + struct basic_lua_table; + using lua_table = basic_lua_table; + using stack_lua_table = basic_lua_table; + + template + class basic_usertype; + template + using usertype = basic_usertype; + template + using stack_usertype = basic_usertype; + + template + class basic_metatable; + using metatable = basic_metatable; + using stack_metatable = basic_metatable; + + template + struct basic_environment; + using environment = basic_environment; + using main_environment = basic_environment; + using stack_environment = basic_environment; + + template + class basic_function; + template + class basic_protected_function; + using unsafe_function = basic_function; + using safe_function = basic_protected_function; + using main_unsafe_function = basic_function; + using main_safe_function = basic_protected_function; + using stack_unsafe_function = basic_function; + using stack_safe_function = basic_protected_function; + using stack_aligned_unsafe_function = basic_function; + using stack_aligned_safe_function = basic_protected_function; + using protected_function = safe_function; + using main_protected_function = main_safe_function; + using stack_protected_function = stack_safe_function; + using stack_aligned_protected_function = stack_aligned_safe_function; +#if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS) + using function = protected_function; + using main_function = main_protected_function; + using stack_function = stack_protected_function; + using stack_aligned_function = stack_aligned_safe_function; +#else + using function = unsafe_function; + using main_function = main_unsafe_function; + using stack_function = stack_unsafe_function; + using stack_aligned_function = stack_aligned_unsafe_function; +#endif + using stack_aligned_stack_handler_function = basic_protected_function; + + struct unsafe_function_result; + struct protected_function_result; + using safe_function_result = protected_function_result; +#if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS) + using function_result = safe_function_result; +#else + using function_result = unsafe_function_result; +#endif + + template + class basic_object_base; + template + class basic_object; + template + class basic_userdata; + template + class basic_lightuserdata; + template + class basic_coroutine; + template + class basic_packaged_coroutine; + template + class basic_thread; + + using object = basic_object; + using userdata = basic_userdata; + using lightuserdata = basic_lightuserdata; + using thread = basic_thread; + using coroutine = basic_coroutine; + using packaged_coroutine = basic_packaged_coroutine; + using main_object = basic_object; + using main_userdata = basic_userdata; + using main_lightuserdata = basic_lightuserdata; + using main_coroutine = basic_coroutine; + using stack_object = basic_object; + using stack_userdata = basic_userdata; + using stack_lightuserdata = basic_lightuserdata; + using stack_thread = basic_thread; + using stack_coroutine = basic_coroutine; + + struct stack_proxy_base; + struct stack_proxy; + struct variadic_args; + struct variadic_results; + struct stack_count; + struct this_state; + struct this_main_state; + struct this_environment; + + class state_view; + class state; + + template + struct as_table_t; + template + struct as_container_t; + template + struct nested; + template + struct light; + template + struct user; + template + struct as_args_t; + template + struct protect_t; + template + struct policy_wrapper; + + template + struct usertype_traits; + template + struct unique_usertype_traits; + + template + struct types { + typedef std::make_index_sequence indices; + static constexpr std::size_t size() { + return sizeof...(Args); + } + }; + + template + struct derive : std::false_type { + typedef types<> type; + }; + + template + struct base : std::false_type { + typedef types<> type; + }; + + template + struct weak_derive { + static bool value; + }; + + template + bool weak_derive::value = false; + + namespace stack { + struct record; + } + +#if SOL_IS_OFF(SOL_USE_BOOST) + template + class optional; + + template + class optional; +#endif + + using check_handler_type = int(lua_State*, int, type, type, const char*); + +} // namespace sol + +#define SOL_BASE_CLASSES(T, ...) \ + namespace sol { \ + template <> \ + struct base : std::true_type { \ + typedef ::sol::types<__VA_ARGS__> type; \ + }; \ + } \ + static_assert(true, "") +#define SOL_DERIVED_CLASSES(T, ...) \ + namespace sol { \ + template <> \ + struct derive : std::true_type { \ + typedef ::sol::types<__VA_ARGS__> type; \ + }; \ + } \ + static_assert(true, "") + +#endif // SOL_FORWARD_HPP +// end of sol/forward.hpp + +#endif // SOL_SINGLE_INCLUDE_SOL_FORWARD_HPP diff --git a/thirdparty/sol/sol.hpp b/thirdparty/sol/sol.hpp new file mode 100644 index 0000000000..2197ef5a7c --- /dev/null +++ b/thirdparty/sol/sol.hpp @@ -0,0 +1,29208 @@ +// The MIT License (MIT) + +// Copyright (c) 2013-2020 Rapptz, ThePhD and contributors + +// 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. + +// This file was generated with a script. +// Generated 2024-09-03 03:46:49.867770 UTC +// This header was generated with sol v3.3.1 (revision 2b0d2fe8) +// https://github.com/ThePhD/sol2 + +#ifndef SOL_SINGLE_INCLUDE_SOL_HPP +#define SOL_SINGLE_INCLUDE_SOL_HPP + +// beginning of sol/sol.hpp + +#ifndef SOL_HPP +#define SOL_HPP + +// beginning of sol/version.hpp + +#include + +#define SOL_VERSION_MAJOR 3 +#define SOL_VERSION_MINOR 2 +#define SOL_VERSION_PATCH 3 +#define SOL_VERSION_STRING "3.2.3" +#define SOL_VERSION ((SOL_VERSION_MAJOR * 100000) + (SOL_VERSION_MINOR * 100) + (SOL_VERSION_PATCH)) + +#define SOL_TOKEN_TO_STRING_POST_EXPANSION_I_(_TOKEN) #_TOKEN +#define SOL_TOKEN_TO_STRING_I_(_TOKEN) SOL_TOKEN_TO_STRING_POST_EXPANSION_I_(_TOKEN) + +#define SOL_CONCAT_TOKENS_POST_EXPANSION_I_(_LEFT, _RIGHT) _LEFT##_RIGHT +#define SOL_CONCAT_TOKENS_I_(_LEFT, _RIGHT) SOL_CONCAT_TOKENS_POST_EXPANSION_I_(_LEFT, _RIGHT) + +#define SOL_RAW_IS_ON(OP_SYMBOL) ((3 OP_SYMBOL 3) != 0) +#define SOL_RAW_IS_OFF(OP_SYMBOL) ((3 OP_SYMBOL 3) == 0) +#define SOL_RAW_IS_DEFAULT_ON(OP_SYMBOL) ((3 OP_SYMBOL 3) > 3) +#define SOL_RAW_IS_DEFAULT_OFF(OP_SYMBOL) ((3 OP_SYMBOL 3 OP_SYMBOL 3) < 0) + +#define SOL_IS_ON(OP_SYMBOL) SOL_RAW_IS_ON(OP_SYMBOL ## _I_) +#define SOL_IS_OFF(OP_SYMBOL) SOL_RAW_IS_OFF(OP_SYMBOL ## _I_) +#define SOL_IS_DEFAULT_ON(OP_SYMBOL) SOL_RAW_IS_DEFAULT_ON(OP_SYMBOL ## _I_) +#define SOL_IS_DEFAULT_OFF(OP_SYMBOL) SOL_RAW_IS_DEFAULT_OFF(OP_SYMBOL ## _I_) + +#define SOL_ON | +#define SOL_OFF ^ +#define SOL_DEFAULT_ON + +#define SOL_DEFAULT_OFF - + +#if defined(SOL_BUILD_CXX_MODE) + #if (SOL_BUILD_CXX_MODE != 0) + #define SOL_BUILD_CXX_MODE_I_ SOL_ON + #else + #define SOL_BUILD_CXX_MODE_I_ SOL_OFF + #endif +#elif defined(__cplusplus) + #define SOL_BUILD_CXX_MODE_I_ SOL_DEFAULT_ON +#else + #define SOL_BUILD_CXX_MODE_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_BUILD_C_MODE) + #if (SOL_BUILD_C_MODE != 0) + #define SOL_BUILD_C_MODE_I_ SOL_ON + #else + #define SOL_BUILD_C_MODE_I_ SOL_OFF + #endif +#elif defined(__STDC__) + #define SOL_BUILD_C_MODE_I_ SOL_DEFAULT_ON +#else + #define SOL_BUILD_C_MODE_I_ SOL_DEFAULT_OFF +#endif + +#if SOL_IS_ON(SOL_BUILD_C_MODE) + #include + #include + #include +#else + #include + #include + #include +#endif + +#if defined(SOL_HAS_BUILTIN) + #define SOL_HAS_BUILTIN_I_(...) SOL_HAS_BUILTIN(__VA_ARGS__) +#elif defined(__has_builtin) + #define SOL_HAS_BUILTIN_I_(...) __has_builtin(__VA_ARGS__) +#else + #define SOL_HAS_BUILTIN_I_(...) 0 +#endif + +#if defined(SOL_COMPILER_VCXX) + #if (SOL_COMPILER_VCXX != 0) + #define SOL_COMPILER_VCXX_I_ SOL_ON + #else + #define SOL_COMPILER_VCXX_I_ SOL_OFF + #endif +#elif defined(_MSC_VER) + #define SOL_COMPILER_VCXX_I_ SOL_DEFAULT_ON +#else + #define SOL_COMPILER_VCXX_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_COMPILER_GCC) + #if (SOL_COMPILER_GCC != 0) + #define SOL_COMPILER_GCC_I_ SOL_ON + #else + #define SOL_COMPILER_GCC_I_ SOL_OFF + #endif +#elif defined(__GNUC__) + #define SOL_COMPILER_GCC_I_ SOL_DEFAULT_ON +#else + #define SOL_COMPILER_GCC_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_COMPILER_CLANG) + #if (SOL_COMPILER_CLANG != 0) + #define SOL_COMPILER_CLANG_I_ SOL_ON + #else + #define SOL_COMPILER_CLANG_I_ SOL_OFF + #endif +#elif defined(__clang__) + #define SOL_COMPILER_CLANG_I_ SOL_DEFAULT_ON +#else + #define SOL_COMPILER_CLANG_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_COMPILER_EDG) + #if (SOL_COMPILER_EDG != 0) + #define SOL_COMPILER_EDG_I_ SOL_ON + #else + #define SOL_COMPILER_EDG_I_ SOL_OFF + #endif +#else + #define SOL_COMPILER_EDG_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_COMPILER_MINGW) + #if (SOL_COMPILER_MINGW != 0) + #define SOL_COMPILER_MINGW_I_ SOL_ON + #else + #define SOL_COMPILER_MINGW_I_ SOL_OFF + #endif +#elif defined(__MINGW32__) + #define SOL_COMPILER_MINGW_I_ SOL_DEFAULT_ON +#else + #define SOL_COMPILER_MINGW_I_ SOL_DEFAULT_OFF +#endif + +#if SIZE_MAX <= 0xFFFFULL + #define SOL_PLATFORM_X16_I_ SOL_ON + #define SOL_PLATFORM_X86_I_ SOL_OFF + #define SOL_PLATFORM_X64_I_ SOL_OFF +#elif SIZE_MAX <= 0xFFFFFFFFULL + #define SOL_PLATFORM_X16_I_ SOL_OFF + #define SOL_PLATFORM_X86_I_ SOL_ON + #define SOL_PLATFORM_X64_I_ SOL_OFF +#else + #define SOL_PLATFORM_X16_I_ SOL_OFF + #define SOL_PLATFORM_X86_I_ SOL_OFF + #define SOL_PLATFORM_X64_I_ SOL_ON +#endif + +#define SOL_PLATFORM_ARM32_I_ SOL_OFF +#define SOL_PLATFORM_ARM64_I_ SOL_OFF + +#if defined(SOL_PLATFORM_WINDOWS) + #if (SOL_PLATFORM_WINDOWS != 0) + #define SOL_PLATFORM_WINDOWS_I_ SOL_ON + #else + #define SOL_PLATFORM_WINDOWS_I_ SOL_OFF + #endif +#elif defined(_WIN32) + #define SOL_PLATFORM_WINDOWS_I_ SOL_DEFAULT_ON +#else + #define SOL_PLATFORM_WINDOWS_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_PLATFORM_CYGWIN) + #if (SOL_PLATFORM_CYGWIN != 0) + #define SOL_PLATFORM_CYGWIN_I_ SOL_ON + #else + #define SOL_PLATFORM_CYGWIN_I_ SOL_ON + #endif +#elif defined(__CYGWIN__) + #define SOL_PLATFORM_CYGWIN_I_ SOL_DEFAULT_ON +#else + #define SOL_PLATFORM_CYGWIN_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_PLATFORM_APPLE) + #if (SOL_PLATFORM_APPLE != 0) + #define SOL_PLATFORM_APPLE_I_ SOL_ON + #else + #define SOL_PLATFORM_APPLE_I_ SOL_OFF + #endif +#elif defined(__APPLE__) + #define SOL_PLATFORM_APPLE_I_ SOL_DEFAULT_ON +#else + #define SOL_PLATFORM_APPLE_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_PLATFORM_UNIX) + #if (SOL_PLATFORM_UNIX != 0) + #define SOL_PLATFORM_UNIXLIKE_I_ SOL_ON + #else + #define SOL_PLATFORM_UNIXLIKE_I_ SOL_OFF + #endif +#elif defined(__unix__) + #define SOL_PLATFORM_UNIXLIKE_I_ SOL_DEFAULT_ON +#else + #define SOL_PLATFORM_UNIXLIKE_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_PLATFORM_LINUX) + #if (SOL_PLATFORM_LINUX != 0) + #define SOL_PLATFORM_LINUXLIKE_I_ SOL_ON + #else + #define SOL_PLATFORM_LINUXLIKE_I_ SOL_OFF + #endif +#elif defined(__LINUX__) + #define SOL_PLATFORM_LINUXLIKE_I_ SOL_DEFAULT_ON +#else + #define SOL_PLATFORM_LINUXLIKE_I_ SOL_DEFAULT_OFF +#endif + +#define SOL_PLATFORM_APPLE_IPHONE_I_ SOL_OFF +#define SOL_PLATFORM_BSDLIKE_I_ SOL_OFF + +#if defined(SOL_IN_DEBUG_DETECTED) + #if (SOL_IN_DEBUG_DETECTED != 0) + #define SOL_DEBUG_BUILD_I_ SOL_ON + #else + #define SOL_DEBUG_BUILD_I_ SOL_OFF + #endif +#elif !defined(NDEBUG) + #if SOL_IS_ON(SOL_COMPILER_VCXX) && defined(_DEBUG) + #define SOL_DEBUG_BUILD_I_ SOL_ON + #elif (SOL_IS_ON(SOL_COMPILER_CLANG) || SOL_IS_ON(SOL_COMPILER_GCC)) && !defined(__OPTIMIZE__) + #define SOL_DEBUG_BUILD_I_ SOL_ON + #else + #define SOL_DEBUG_BUILD_I_ SOL_OFF + #endif +#else + #define SOL_DEBUG_BUILD_I_ SOL_DEFAULT_OFF +#endif // We are in a debug mode of some sort + +#if defined(SOL_NO_EXCEPTIONS) + #if (SOL_NO_EXCEPTIONS != 0) + #define SOL_EXCEPTIONS_I_ SOL_OFF + #else + #define SOL_EXCEPTIONS_I_ SOL_ON + #endif +#elif SOL_IS_ON(SOL_COMPILER_VCXX) + #if !defined(_CPPUNWIND) + #define SOL_EXCEPTIONS_I_ SOL_OFF + #else + #define SOL_EXCEPTIONS_I_ SOL_ON + #endif +#elif SOL_IS_ON(SOL_COMPILER_CLANG) || SOL_IS_ON(SOL_COMPILER_GCC) + #if !defined(__EXCEPTIONS) + #define SOL_EXCEPTIONS_I_ SOL_OFF + #else + #define SOL_EXCEPTIONS_I_ SOL_ON + #endif +#else + #define SOL_EXCEPTIONS_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_NO_RTTI) + #if (SOL_NO_RTTI != 0) + #define SOL_RTTI_I_ SOL_OFF + #else + #define SOL_RTTI_I_ SOL_ON + #endif +#elif SOL_IS_ON(SOL_COMPILER_VCXX) + #if !defined(_CPPRTTI) + #define SOL_RTTI_I_ SOL_OFF + #else + #define SOL_RTTI_I_ SOL_ON + #endif +#elif SOL_IS_ON(SOL_COMPILER_CLANG) || SOL_IS_ON(SOL_COMPILER_GCC) + #if !defined(__GXX_RTTI) + #define SOL_RTTI_I_ SOL_OFF + #else + #define SOL_RTTI_I_ SOL_ON + #endif +#else + #define SOL_RTTI_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_NO_THREAD_LOCAL) + #if (SOL_NO_THREAD_LOCAL != 0) + #define SOL_USE_THREAD_LOCAL_I_ SOL_OFF + #else + #define SOL_USE_THREAD_LOCAL_I_ SOL_ON + #endif +#else + #define SOL_USE_THREAD_LOCAL_I_ SOL_DEFAULT_ON +#endif // thread_local keyword is bjorked on some platforms + +#if defined(SOL_ALL_SAFETIES_ON) + #if (SOL_ALL_SAFETIES_ON != 0) + #define SOL_ALL_SAFETIES_ON_I_ SOL_ON + #else + #define SOL_ALL_SAFETIES_ON_I_ SOL_OFF + #endif +#else + #define SOL_ALL_SAFETIES_ON_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_SAFE_GETTER) + #if (SOL_SAFE_GETTER != 0) + #define SOL_SAFE_GETTER_I_ SOL_ON + #else + #define SOL_SAFE_GETTER_I_ SOL_OFF + #endif +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON) + #define SOL_SAFE_GETTER_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD) + #define SOL_SAFE_GETTER_I_ SOL_DEFAULT_ON + #else + #define SOL_SAFE_GETTER_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_SAFE_USERTYPE) + #if (SOL_SAFE_USERTYPE != 0) + #define SOL_SAFE_USERTYPE_I_ SOL_ON + #else + #define SOL_SAFE_USERTYPE_I_ SOL_OFF + #endif +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON) + #define SOL_SAFE_USERTYPE_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD) + #define SOL_SAFE_USERTYPE_I_ SOL_DEFAULT_ON + #else + #define SOL_SAFE_USERTYPE_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_SAFE_REFERENCES) + #if (SOL_SAFE_REFERENCES != 0) + #define SOL_SAFE_REFERENCES_I_ SOL_ON + #else + #define SOL_SAFE_REFERENCES_I_ SOL_OFF + #endif +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON) + #define SOL_SAFE_REFERENCES_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD) + #define SOL_SAFE_REFERENCES_I_ SOL_DEFAULT_ON + #else + #define SOL_SAFE_REFERENCES_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_SAFE_FUNCTIONS) + #if (SOL_SAFE_FUNCTIONS != 0) + #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_ON + #else + #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_OFF + #endif +#elif defined (SOL_SAFE_FUNCTION_OBJECTS) + #if (SOL_SAFE_FUNCTION_OBJECTS != 0) + #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_ON + #else + #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_OFF + #endif +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON) + #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD) + #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_DEFAULT_ON + #else + #define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_SAFE_FUNCTION_CALLS) + #if (SOL_SAFE_FUNCTION_CALLS != 0) + #define SOL_SAFE_FUNCTION_CALLS_I_ SOL_ON + #else + #define SOL_SAFE_FUNCTION_CALLS_I_ SOL_OFF + #endif +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON) + #define SOL_SAFE_FUNCTION_CALLS_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD) + #define SOL_SAFE_FUNCTION_CALLS_I_ SOL_DEFAULT_ON + #else + #define SOL_SAFE_FUNCTION_CALLS_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_SAFE_PROXIES) + #if (SOL_SAFE_PROXIES != 0) + #define SOL_SAFE_PROXIES_I_ SOL_ON + #else + #define SOL_SAFE_PROXIES_I_ SOL_OFF + #endif +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON) + #define SOL_SAFE_PROXIES_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD) + #define SOL_SAFE_PROXIES_I_ SOL_DEFAULT_ON + #else + #define SOL_SAFE_PROXIES_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_SAFE_NUMERICS) + #if (SOL_SAFE_NUMERICS != 0) + #define SOL_SAFE_NUMERICS_I_ SOL_ON + #else + #define SOL_SAFE_NUMERICS_I_ SOL_OFF + #endif +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON) + #define SOL_SAFE_NUMERICS_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD) + #define SOL_SAFE_NUMERICS_I_ SOL_DEFAULT_ON + #else + #define SOL_SAFE_NUMERICS_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_ALL_INTEGER_VALUES_FIT) + #if (SOL_ALL_INTEGER_VALUES_FIT != 0) + #define SOL_ALL_INTEGER_VALUES_FIT_I_ SOL_ON + #else + #define SOL_ALL_INTEGER_VALUES_FIT_I_ SOL_OFF + #endif +#elif !SOL_IS_DEFAULT_OFF(SOL_SAFE_NUMERICS) && SOL_IS_OFF(SOL_SAFE_NUMERICS) + // if numerics is intentionally turned off, flip this on + #define SOL_ALL_INTEGER_VALUES_FIT_I_ SOL_DEFAULT_ON +#else + // default to off + #define SOL_ALL_INTEGER_VALUES_FIT_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_SAFE_STACK_CHECK) + #if (SOL_SAFE_STACK_CHECK != 0) + #define SOL_SAFE_STACK_CHECK_I_ SOL_ON + #else + #define SOL_SAFE_STACK_CHECK_I_ SOL_OFF + #endif +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON) + #define SOL_SAFE_STACK_CHECK_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD) + #define SOL_SAFE_STACK_CHECK_I_ SOL_DEFAULT_ON + #else + #define SOL_SAFE_STACK_CHECK_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_NO_CHECK_NUMBER_PRECISION) + #if (SOL_NO_CHECK_NUMBER_PRECISION != 0) + #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_OFF + #else + #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_ON + #endif +#elif defined(SOL_NO_CHECKING_NUMBER_PRECISION) + #if (SOL_NO_CHECKING_NUMBER_PRECISION != 0) + #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_OFF + #else + #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_ON + #endif +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON) + #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_ON + #elif SOL_IS_ON(SOL_SAFE_NUMERICS) + #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD) + #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_DEFAULT_ON + #else + #define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_STRINGS_ARE_NUMBERS) + #if (SOL_STRINGS_ARE_NUMBERS != 0) + #define SOL_STRINGS_ARE_NUMBERS_I_ SOL_ON + #else + #define SOL_STRINGS_ARE_NUMBERS_I_ SOL_OFF + #endif +#else + #define SOL_STRINGS_ARE_NUMBERS_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_ENABLE_INTEROP) + #if (SOL_ENABLE_INTEROP != 0) + #define SOL_USE_INTEROP_I_ SOL_ON + #else + #define SOL_USE_INTEROP_I_ SOL_OFF + #endif +#elif defined(SOL_USE_INTEROP) + #if (SOL_USE_INTEROP != 0) + #define SOL_USE_INTEROP_I_ SOL_ON + #else + #define SOL_USE_INTEROP_I_ SOL_OFF + #endif +#else + #define SOL_USE_INTEROP_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_NO_NIL) + #if (SOL_NO_NIL != 0) + #define SOL_NIL_I_ SOL_OFF + #else + #define SOL_NIL_I_ SOL_ON + #endif +#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED) || defined(__OBJC__) || defined(nil) + #define SOL_NIL_I_ SOL_DEFAULT_OFF +#else + #define SOL_NIL_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_USERTYPE_TYPE_BINDING_INFO) + #if (SOL_USERTYPE_TYPE_BINDING_INFO != 0) + #define SOL_USERTYPE_TYPE_BINDING_INFO_I_ SOL_ON + #else + #define SOL_USERTYPE_TYPE_BINDING_INFO_I_ SOL_OFF + #endif +#else + #define SOL_USERTYPE_TYPE_BINDING_INFO_I_ SOL_DEFAULT_ON +#endif // We should generate a my_type.__type table with lots of class information for usertypes + +#if defined(SOL_AUTOMAGICAL_TYPES_BY_DEFAULT) + #if (SOL_AUTOMAGICAL_TYPES_BY_DEFAULT != 0) + #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_ON + #else + #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_OFF + #endif +#elif defined(SOL_DEFAULT_AUTOMAGICAL_USERTYPES) + #if (SOL_DEFAULT_AUTOMAGICAL_USERTYPES != 0) + #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_ON + #else + #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_OFF + #endif +#else + #define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_DEFAULT_ON +#endif // make is_automagical on/off by default + +#if defined(SOL_STD_VARIANT) + #if (SOL_STD_VARIANT != 0) + #define SOL_STD_VARIANT_I_ SOL_ON + #else + #define SOL_STD_VARIANT_I_ SOL_OFF + #endif +#else + #if SOL_IS_ON(SOL_COMPILER_CLANG) && SOL_IS_ON(SOL_PLATFORM_APPLE) + #if defined(__has_include) + #if __has_include() + #define SOL_STD_VARIANT_I_ SOL_DEFAULT_ON + #else + #define SOL_STD_VARIANT_I_ SOL_DEFAULT_OFF + #endif + #else + #define SOL_STD_VARIANT_I_ SOL_DEFAULT_OFF + #endif + #else + #define SOL_STD_VARIANT_I_ SOL_DEFAULT_ON + #endif +#endif // make is_automagical on/off by default + +#if defined(SOL_NOEXCEPT_FUNCTION_TYPE) + #if (SOL_NOEXCEPT_FUNCTION_TYPE != 0) + #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_ON + #else + #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_OFF + #endif +#else + #if defined(__cpp_noexcept_function_type) + #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_ON + #elif SOL_IS_ON(SOL_COMPILER_VCXX) && (defined(_MSVC_LANG) && (_MSVC_LANG < 201403L)) + // There is a bug in the VC++ compiler?? + // on /std:c++latest under x86 conditions (VS 15.5.2), + // compiler errors are tossed for noexcept markings being on function types + // that are identical in every other way to their non-noexcept marked types function types... + // VS 2019: There is absolutely a bug. + #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_OFF + #else + #define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_DEFAULT_ON + #endif +#endif // noexcept is part of a function's type + +#if defined(SOL_STACK_STRING_OPTIMIZATION_SIZE) && (SOL_STACK_STRING_OPTIMIZATION_SIZE > 0) + #define SOL_OPTIMIZATION_STRING_CONVERSION_STACK_SIZE_I_ SOL_STACK_STRING_OPTIMIZATION_SIZE +#else + #define SOL_OPTIMIZATION_STRING_CONVERSION_STACK_SIZE_I_ 1024 +#endif + +#if defined(SOL_ID_SIZE) && (SOL_ID_SIZE > 0) + #define SOL_ID_SIZE_I_ SOL_ID_SIZE +#else + #define SOL_ID_SIZE_I_ 512 +#endif + +#if defined(LUA_IDSIZE) && (LUA_IDSIZE > 0) + #define SOL_FILE_ID_SIZE_I_ LUA_IDSIZE +#elif defined(SOL_ID_SIZE) && SOL_ID_SIZE > 0 + #define SOL_FILE_ID_SIZE_I_ SOL_FILE_ID_SIZE +#else + #define SOL_FILE_ID_SIZE_I_ 2048 +#endif + +#if defined(SOL_PRINT_ERRORS) + #if (SOL_PRINT_ERRORS != 0) + #define SOL_PRINT_ERRORS_I_ SOL_ON + #else + #define SOL_PRINT_ERRORS_I_ SOL_OFF + #endif +#else + #if SOL_IS_ON(SOL_ALL_SAFETIES_ON) + #define SOL_PRINT_ERRORS_I_ SOL_ON + #elif SOL_IS_ON(SOL_DEBUG_BUILD) + #define SOL_PRINT_ERRORS_I_ SOL_DEFAULT_ON + #else + #define SOL_PRINT_ERRORS_I_ SOL_OFF + #endif +#endif + +#if defined(SOL_DEFAULT_PASS_ON_ERROR) + #if (SOL_DEFAULT_PASS_ON_ERROR != 0) + #define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_ON + #else + #define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_OFF + #endif +#else + #define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_USING_CXX_LUA) + #if (SOL_USING_CXX_LUA != 0) + #define SOL_USING_CXX_LUA_I_ SOL_ON + #else + #define SOL_USING_CXX_LUA_I_ SOL_OFF + #endif +#elif defined(SOL_USE_CXX_LUA) + // alternative spelling + #if (SOL_USE_CXX_LUA != 0) + #define SOL_USING_CXX_LUA_I_ SOL_ON + #else + #define SOL_USING_CXX_LUA_I_ SOL_OFF + #endif +#else + #define SOL_USING_CXX_LUA_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_USING_CXX_LUAJIT) + #if (SOL_USING_CXX_LUAJIT != 0) + #define SOL_USING_CXX_LUAJIT_I_ SOL_ON + #else + #define SOL_USING_CXX_LUAJIT_I_ SOL_OFF + #endif +#elif defined(SOL_USE_CXX_LUAJIT) + #if (SOL_USE_CXX_LUAJIT != 0) + #define SOL_USING_CXX_LUAJIT_I_ SOL_ON + #else + #define SOL_USING_CXX_LUAJIT_I_ SOL_OFF + #endif +#else + #define SOL_USING_CXX_LUAJIT_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_NO_LUA_HPP) + #if (SOL_NO_LUA_HPP != 0) + #define SOL_USE_LUA_HPP_I_ SOL_OFF + #else + #define SOL_USE_LUA_HPP_I_ SOL_ON + #endif +#elif SOL_IS_ON(SOL_USING_CXX_LUA) + #define SOL_USE_LUA_HPP_I_ SOL_OFF +#elif defined(__has_include) + #if __has_include() + #define SOL_USE_LUA_HPP_I_ SOL_ON + #else + #define SOL_USE_LUA_HPP_I_ SOL_OFF + #endif +#else + #define SOL_USE_LUA_HPP_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_CONTAINERS_START) + #define SOL_CONTAINER_START_INDEX_I_ SOL_CONTAINERS_START +#elif defined(SOL_CONTAINERS_START_INDEX) + #define SOL_CONTAINER_START_INDEX_I_ SOL_CONTAINERS_START_INDEX +#elif defined(SOL_CONTAINER_START_INDEX) + #define SOL_CONTAINER_START_INDEX_I_ SOL_CONTAINER_START_INDEX +#else + #define SOL_CONTAINER_START_INDEX_I_ 1 +#endif + +#if defined (SOL_NO_MEMORY_ALIGNMENT) + #if (SOL_NO_MEMORY_ALIGNMENT != 0) + #define SOL_ALIGN_MEMORY_I_ SOL_OFF + #else + #define SOL_ALIGN_MEMORY_I_ SOL_ON + #endif +#else + #define SOL_ALIGN_MEMORY_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_USE_BOOST) + #if (SOL_USE_BOOST != 0) + #define SOL_USE_BOOST_I_ SOL_ON + #else + #define SOL_USE_BOOST_I_ SOL_OFF + #endif +#else + #define SOL_USE_BOOST_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_USE_UNSAFE_BASE_LOOKUP) + #if (SOL_USE_UNSAFE_BASE_LOOKUP != 0) + #define SOL_USE_UNSAFE_BASE_LOOKUP_I_ SOL_ON + #else + #define SOL_USE_UNSAFE_BASE_LOOKUP_I_ SOL_OFF + #endif +#else + #define SOL_USE_UNSAFE_BASE_LOOKUP_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_INSIDE_UNREAL) + #if (SOL_INSIDE_UNREAL != 0) + #define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_ON + #else + #define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_OFF + #endif +#else + #if defined(UE_BUILD_DEBUG) || defined(UE_BUILD_DEVELOPMENT) || defined(UE_BUILD_TEST) || defined(UE_BUILD_SHIPPING) || defined(UE_SERVER) + #define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_DEFAULT_ON + #else + #define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if defined(SOL_NO_COMPAT) + #if (SOL_NO_COMPAT != 0) + #define SOL_USE_COMPATIBILITY_LAYER_I_ SOL_OFF + #else + #define SOL_USE_COMPATIBILITY_LAYER_I_ SOL_ON + #endif +#else + #define SOL_USE_COMPATIBILITY_LAYER_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_GET_FUNCTION_POINTER_UNSAFE) + #if (SOL_GET_FUNCTION_POINTER_UNSAFE != 0) + #define SOL_GET_FUNCTION_POINTER_UNSAFE_I_ SOL_ON + #else + #define SOL_GET_FUNCTION_POINTER_UNSAFE_I_ SOL_OFF + #endif +#else + #define SOL_GET_FUNCTION_POINTER_UNSAFE_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_CONTAINER_CHECK_IS_EXHAUSTIVE) + #if (SOL_CONTAINER_CHECK_IS_EXHAUSTIVE != 0) + #define SOL_CONTAINER_CHECK_IS_EXHAUSTIVE_I_ SOL_ON + #else + #define SOL_CONTAINER_CHECK_IS_EXHAUSTIVE_I_ SOL_OFF + #endif +#else + #define SOL_CONTAINER_CHECK_IS_EXHAUSTIVE_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_FUNCTION_CALL_VALUE_SEMANTICS) + #if (SOL_FUNCTION_CALL_VALUE_SEMANTICS != 0) + #define SOL_FUNCTION_CALL_VALUE_SEMANTICS_I_ SOL_ON + #else + #define SOL_FUNCTION_CALL_VALUE_SEMANTICS_I_ SOL_OFF + #endif +#else + #define SOL_FUNCTION_CALL_VALUE_SEMANTICS_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_MINGW_CCTYPE_IS_POISONED) + #if (SOL_MINGW_CCTYPE_IS_POISONED != 0) + #define SOL_MINGW_CCTYPE_IS_POISONED_I_ SOL_ON + #else + #define SOL_MINGW_CCTYPE_IS_POISONED_I_ SOL_OFF + #endif +#elif SOL_IS_ON(SOL_COMPILER_MINGW) && defined(__GNUC__) && (__GNUC__ < 6) + // MinGW is off its rocker in some places... + #define SOL_MINGW_CCTYPE_IS_POISONED_I_ SOL_DEFAULT_ON +#else + #define SOL_MINGW_CCTYPE_IS_POISONED_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_CHAR8_T) + #if (SOL_CHAR8_T != 0) + #define SOL_CHAR8_T_I_ SOL_ON + #else + #define SOL_CHAR8_T_I_ SOL_OFF + #endif +#else + #if defined(__cpp_char8_t) + #define SOL_CHAR8_T_I_ SOL_DEFAULT_ON + #else + #define SOL_CHAR8_T_I_ SOL_DEFAULT_OFF + #endif +#endif + +#if SOL_IS_ON(SOL_USE_BOOST) + #include + + #if BOOST_VERSION >= 107500 // Since Boost 1.75.0 boost::none is constexpr + #define SOL_BOOST_NONE_CONSTEXPR_I_ constexpr + #else + #define SOL_BOOST_NONE_CONSTEXPR_I_ const + #endif // BOOST_VERSION +#else + // assume boost isn't using a garbage version + #define SOL_BOOST_NONE_CONSTEXPR_I_ constexpr +#endif + +#if defined(SOL2_CI) + #if (SOL2_CI != 0) + #define SOL2_CI_I_ SOL_ON + #else + #define SOL2_CI_I_ SOL_OFF + #endif +#else + #define SOL2_CI_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_ASSERT) + #define SOL_USER_ASSERT_I_ SOL_ON +#else + #define SOL_USER_ASSERT_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_ASSERT_MSG) + #define SOL_USER_ASSERT_MSG_I_ SOL_ON +#else + #define SOL_USER_ASSERT_MSG_I_ SOL_DEFAULT_OFF +#endif + +// beginning of sol/prologue.hpp + +#if defined(SOL_PROLOGUE_I_) + #error "[sol2] Library Prologue was already included in translation unit and not properly ended with an epilogue." +#endif + +#define SOL_PROLOGUE_I_ 1 + +#if SOL_IS_ON(SOL_BUILD_CXX_MODE) + #define _FWD(...) static_cast( __VA_ARGS__ ) + + #if SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG) + #define _MOVE(...) static_cast<__typeof( __VA_ARGS__ )&&>( __VA_ARGS__ ) + #else + #include + + #define _MOVE(...) static_cast<::std::remove_reference_t<( __VA_ARGS__ )>&&>( __VA_OPT__(,) ) + #endif +#endif + +// end of sol/prologue.hpp + +// beginning of sol/epilogue.hpp + +#if !defined(SOL_PROLOGUE_I_) + #error "[sol2] Library Prologue is missing from this translation unit." +#else + #undef SOL_PROLOGUE_I_ +#endif + +#if SOL_IS_ON(SOL_BUILD_CXX_MODE) + #undef _FWD + #undef _MOVE +#endif + +// end of sol/epilogue.hpp + +// beginning of sol/detail/build_version.hpp + +#if defined(SOL_DLL) + #if (SOL_DLL != 0) + #define SOL_DLL_I_ SOL_ON + #else + #define SOL_DLL_I_ SOL_OFF + #endif +#elif SOL_IS_ON(SOL_COMPILER_VCXX) && (defined(DLL_) || defined(_DLL)) + #define SOL_DLL_I_ SOL_DEFAULT_ON +#else + #define SOL_DLL_I_ SOL_DEFAULT_OFF +#endif // DLL definition + +#if defined(SOL_HEADER_ONLY) + #if (SOL_HEADER_ONLY != 0) + #define SOL_HEADER_ONLY_I_ SOL_ON + #else + #define SOL_HEADER_ONLY_I_ SOL_OFF + #endif +#else + #define SOL_HEADER_ONLY_I_ SOL_DEFAULT_OFF +#endif // Header only library + +#if defined(SOL_BUILD) + #if (SOL_BUILD != 0) + #define SOL_BUILD_I_ SOL_ON + #else + #define SOL_BUILD_I_ SOL_OFF + #endif +#elif SOL_IS_ON(SOL_HEADER_ONLY) + #define SOL_BUILD_I_ SOL_DEFAULT_OFF +#else + #define SOL_BUILD_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_UNITY_BUILD) + #if (SOL_UNITY_BUILD != 0) + #define SOL_UNITY_BUILD_I_ SOL_ON + #else + #define SOL_UNITY_BUILD_I_ SOL_OFF + #endif +#else + #define SOL_UNITY_BUILD_I_ SOL_DEFAULT_OFF +#endif // Header only library + +#if defined(SOL_C_FUNCTION_LINKAGE) + #define SOL_C_FUNCTION_LINKAGE_I_ SOL_C_FUNCTION_LINKAGE +#else + #if SOL_IS_ON(SOL_BUILD_CXX_MODE) + // C++ + #define SOL_C_FUNCTION_LINKAGE_I_ extern "C" + #else + // normal + #define SOL_C_FUNCTION_LINKAGE_I_ + #endif // C++ or not +#endif // Linkage specification for C functions + +#if defined(SOL_API_LINKAGE) + #define SOL_API_LINKAGE_I_ SOL_API_LINKAGE +#else + #if SOL_IS_ON(SOL_DLL) + #if SOL_IS_ON(SOL_COMPILER_VCXX) || SOL_IS_ON(SOL_PLATFORM_WINDOWS) || SOL_IS_ON(SOL_PLATFORM_CYGWIN) + // MSVC Compiler; or, Windows, or Cygwin platforms + #if SOL_IS_ON(SOL_BUILD) + // Building the library + #if SOL_IS_ON(SOL_COMPILER_GCC) + // Using GCC + #define SOL_API_LINKAGE_I_ __attribute__((dllexport)) + #else + // Using Clang, MSVC, etc... + #define SOL_API_LINKAGE_I_ __declspec(dllexport) + #endif + #else + #if SOL_IS_ON(SOL_COMPILER_GCC) + #define SOL_API_LINKAGE_I_ __attribute__((dllimport)) + #else + #define SOL_API_LINKAGE_I_ __declspec(dllimport) + #endif + #endif + #else + // extern if building normally on non-MSVC + #define SOL_API_LINKAGE_I_ extern + #endif + #elif SOL_IS_ON(SOL_UNITY_BUILD) + // Built-in library, like how stb typical works + #if SOL_IS_ON(SOL_HEADER_ONLY) + // Header only, so functions are defined "inline" + #define SOL_API_LINKAGE_I_ inline + #else + // Not header only, so seperately compiled files + #define SOL_API_LINKAGE_I_ extern + #endif + #else + // Normal static library + #if SOL_IS_ON(SOL_BUILD_CXX_MODE) + #define SOL_API_LINKAGE_I_ + #else + #define SOL_API_LINKAGE_I_ extern + #endif + #endif // DLL or not +#endif // Build definitions + +#if defined(SOL_PUBLIC_FUNC_DECL) + #define SOL_PUBLIC_FUNC_DECL_I_ SOL_PUBLIC_FUNC_DECL +#else + #define SOL_PUBLIC_FUNC_DECL_I_ SOL_API_LINKAGE_I_ +#endif + +#if defined(SOL_INTERNAL_FUNC_DECL_) + #define SOL_INTERNAL_FUNC_DECL_I_ SOL_INTERNAL_FUNC_DECL_ +#else + #define SOL_INTERNAL_FUNC_DECL_I_ SOL_API_LINKAGE_I_ +#endif + +#if defined(SOL_PUBLIC_FUNC_DEF) + #define SOL_PUBLIC_FUNC_DEF_I_ SOL_PUBLIC_FUNC_DEF +#else + #define SOL_PUBLIC_FUNC_DEF_I_ SOL_API_LINKAGE_I_ +#endif + +#if defined(SOL_INTERNAL_FUNC_DEF) + #define SOL_INTERNAL_FUNC_DEF_I_ SOL_INTERNAL_FUNC_DEF +#else + #define SOL_INTERNAL_FUNC_DEF_I_ SOL_API_LINKAGE_I_ +#endif + +#if defined(SOL_FUNC_DECL) + #define SOL_FUNC_DECL_I_ SOL_FUNC_DECL +#elif SOL_IS_ON(SOL_HEADER_ONLY) + #define SOL_FUNC_DECL_I_ +#elif SOL_IS_ON(SOL_DLL) + #if SOL_IS_ON(SOL_COMPILER_VCXX) + #if SOL_IS_ON(SOL_BUILD) + #define SOL_FUNC_DECL_I_ extern __declspec(dllexport) + #else + #define SOL_FUNC_DECL_I_ extern __declspec(dllimport) + #endif + #elif SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG) + #define SOL_FUNC_DECL_I_ extern __attribute__((visibility("default"))) + #else + #define SOL_FUNC_DECL_I_ extern + #endif +#endif + +#if defined(SOL_FUNC_DEFN) + #define SOL_FUNC_DEFN_I_ SOL_FUNC_DEFN +#elif SOL_IS_ON(SOL_HEADER_ONLY) + #define SOL_FUNC_DEFN_I_ inline +#elif SOL_IS_ON(SOL_DLL) + #if SOL_IS_ON(SOL_COMPILER_VCXX) + #if SOL_IS_ON(SOL_BUILD) + #define SOL_FUNC_DEFN_I_ __declspec(dllexport) + #else + #define SOL_FUNC_DEFN_I_ __declspec(dllimport) + #endif + #elif SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG) + #define SOL_FUNC_DEFN_I_ __attribute__((visibility("default"))) + #else + #define SOL_FUNC_DEFN_I_ + #endif +#endif + +#if defined(SOL_HIDDEN_FUNC_DECL) + #define SOL_HIDDEN_FUNC_DECL_I_ SOL_HIDDEN_FUNC_DECL +#elif SOL_IS_ON(SOL_HEADER_ONLY) + #define SOL_HIDDEN_FUNC_DECL_I_ +#elif SOL_IS_ON(SOL_DLL) + #if SOL_IS_ON(SOL_COMPILER_VCXX) + #if SOL_IS_ON(SOL_BUILD) + #define SOL_HIDDEN_FUNC_DECL_I_ extern __declspec(dllexport) + #else + #define SOL_HIDDEN_FUNC_DECL_I_ extern __declspec(dllimport) + #endif + #elif SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG) + #define SOL_HIDDEN_FUNC_DECL_I_ extern __attribute__((visibility("default"))) + #else + #define SOL_HIDDEN_FUNC_DECL_I_ extern + #endif +#endif + +#if defined(SOL_HIDDEN_FUNC_DEFN) + #define SOL_HIDDEN_FUNC_DEFN_I_ SOL_HIDDEN_FUNC_DEFN +#elif SOL_IS_ON(SOL_HEADER_ONLY) + #define SOL_HIDDEN_FUNC_DEFN_I_ inline +#elif SOL_IS_ON(SOL_DLL) + #if SOL_IS_ON(SOL_COMPILER_VCXX) + #if SOL_IS_ON(SOL_BUILD) + #define SOL_HIDDEN_FUNC_DEFN_I_ + #else + #define SOL_HIDDEN_FUNC_DEFN_I_ + #endif + #elif SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG) + #define SOL_HIDDEN_FUNC_DEFN_I_ __attribute__((visibility("hidden"))) + #else + #define SOL_HIDDEN_FUNC_DEFN_I_ + #endif +#endif + +// end of sol/detail/build_version.hpp + +// end of sol/version.hpp + +#if SOL_IS_ON(SOL_INSIDE_UNREAL_ENGINE) +#ifdef check +#pragma push_macro("check") +#undef check +#endif +#endif // Unreal Engine 4 Bullshit + +#if SOL_IS_ON(SOL_COMPILER_GCC) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wshadow" +#pragma GCC diagnostic ignored "-Wconversion" +#if __GNUC__ > 6 +#pragma GCC diagnostic ignored "-Wnoexcept-type" +#endif +#elif SOL_IS_ON(SOL_COMPILER_CLANG) +#elif SOL_IS_ON(SOL_COMPILER_VCXX) +#pragma warning(push) +#pragma warning(disable : 4505) // unreferenced local function has been removed GEE THANKS +#endif // clang++ vs. g++ vs. VC++ + +// beginning of sol/forward.hpp + +#ifndef SOL_FORWARD_HPP +#define SOL_FORWARD_HPP + +#include +#include +#include + +#if SOL_IS_ON(SOL_USING_CXX_LUA) || SOL_IS_ON(SOL_USING_CXX_LUAJIT) +struct lua_State; +#else +extern "C" { +struct lua_State; +} +#endif // C++ Mangling for Lua vs. Not + +namespace sol { + + enum class type; + + class stateless_reference; + template + class basic_reference; + using reference = basic_reference; + using main_reference = basic_reference; + class stateless_stack_reference; + class stack_reference; + + template + class basic_bytecode; + + struct lua_value; + + struct proxy_base_tag; + template + struct proxy_base; + template + struct table_proxy; + + template + class basic_table_core; + template + using table_core = basic_table_core; + template + using main_table_core = basic_table_core; + template + using stack_table_core = basic_table_core; + template + using basic_table = basic_table_core; + using table = table_core; + using global_table = table_core; + using main_table = main_table_core; + using main_global_table = main_table_core; + using stack_table = stack_table_core; + using stack_global_table = stack_table_core; + + template + struct basic_lua_table; + using lua_table = basic_lua_table; + using stack_lua_table = basic_lua_table; + + template + class basic_usertype; + template + using usertype = basic_usertype; + template + using stack_usertype = basic_usertype; + + template + class basic_metatable; + using metatable = basic_metatable; + using stack_metatable = basic_metatable; + + template + struct basic_environment; + using environment = basic_environment; + using main_environment = basic_environment; + using stack_environment = basic_environment; + + template + class basic_function; + template + class basic_protected_function; + using unsafe_function = basic_function; + using safe_function = basic_protected_function; + using main_unsafe_function = basic_function; + using main_safe_function = basic_protected_function; + using stack_unsafe_function = basic_function; + using stack_safe_function = basic_protected_function; + using stack_aligned_unsafe_function = basic_function; + using stack_aligned_safe_function = basic_protected_function; + using protected_function = safe_function; + using main_protected_function = main_safe_function; + using stack_protected_function = stack_safe_function; + using stack_aligned_protected_function = stack_aligned_safe_function; +#if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS) + using function = protected_function; + using main_function = main_protected_function; + using stack_function = stack_protected_function; + using stack_aligned_function = stack_aligned_safe_function; +#else + using function = unsafe_function; + using main_function = main_unsafe_function; + using stack_function = stack_unsafe_function; + using stack_aligned_function = stack_aligned_unsafe_function; +#endif + using stack_aligned_stack_handler_function = basic_protected_function; + + struct unsafe_function_result; + struct protected_function_result; + using safe_function_result = protected_function_result; +#if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS) + using function_result = safe_function_result; +#else + using function_result = unsafe_function_result; +#endif + + template + class basic_object_base; + template + class basic_object; + template + class basic_userdata; + template + class basic_lightuserdata; + template + class basic_coroutine; + template + class basic_packaged_coroutine; + template + class basic_thread; + + using object = basic_object; + using userdata = basic_userdata; + using lightuserdata = basic_lightuserdata; + using thread = basic_thread; + using coroutine = basic_coroutine; + using packaged_coroutine = basic_packaged_coroutine; + using main_object = basic_object; + using main_userdata = basic_userdata; + using main_lightuserdata = basic_lightuserdata; + using main_coroutine = basic_coroutine; + using stack_object = basic_object; + using stack_userdata = basic_userdata; + using stack_lightuserdata = basic_lightuserdata; + using stack_thread = basic_thread; + using stack_coroutine = basic_coroutine; + + struct stack_proxy_base; + struct stack_proxy; + struct variadic_args; + struct variadic_results; + struct stack_count; + struct this_state; + struct this_main_state; + struct this_environment; + + class state_view; + class state; + + template + struct as_table_t; + template + struct as_container_t; + template + struct nested; + template + struct light; + template + struct user; + template + struct as_args_t; + template + struct protect_t; + template + struct policy_wrapper; + + template + struct usertype_traits; + template + struct unique_usertype_traits; + + template + struct types { + typedef std::make_index_sequence indices; + static constexpr std::size_t size() { + return sizeof...(Args); + } + }; + + template + struct derive : std::false_type { + typedef types<> type; + }; + + template + struct base : std::false_type { + typedef types<> type; + }; + + template + struct weak_derive { + static bool value; + }; + + template + bool weak_derive::value = false; + + namespace stack { + struct record; + } + +#if SOL_IS_OFF(SOL_USE_BOOST) + template + class optional; + + template + class optional; +#endif + + using check_handler_type = int(lua_State*, int, type, type, const char*); + +} // namespace sol + +#define SOL_BASE_CLASSES(T, ...) \ + namespace sol { \ + template <> \ + struct base : std::true_type { \ + typedef ::sol::types<__VA_ARGS__> type; \ + }; \ + } \ + static_assert(true, "") +#define SOL_DERIVED_CLASSES(T, ...) \ + namespace sol { \ + template <> \ + struct derive : std::true_type { \ + typedef ::sol::types<__VA_ARGS__> type; \ + }; \ + } \ + static_assert(true, "") + +#endif // SOL_FORWARD_HPP +// end of sol/forward.hpp + +// beginning of sol/forward_detail.hpp + +#ifndef SOL_FORWARD_DETAIL_HPP +#define SOL_FORWARD_DETAIL_HPP + +// beginning of sol/traits.hpp + +// beginning of sol/tuple.hpp + +// beginning of sol/base_traits.hpp + +#include + +namespace sol { + namespace detail { + struct unchecked_t { }; + const unchecked_t unchecked = unchecked_t {}; + } // namespace detail + + namespace meta { + using sfinae_yes_t = std::true_type; + using sfinae_no_t = std::false_type; + + template + using void_t = void; + + template + using unqualified = std::remove_cv>; + + template + using unqualified_t = typename unqualified::type; + + namespace meta_detail { + template + struct unqualified_non_alias : unqualified { }; + + template