1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-12-04 11:04:32 +00:00

Merge branch openmw:master into master

This commit is contained in:
Andy Lanzone 2025-07-27 13:21:40 -07:00
commit 31580ffb71
149 changed files with 6962 additions and 5791 deletions

View file

@ -1 +1 @@
VCPKG_DEPS_TAG=2024-11-10
VCPKG_DEPS_TAG=2025-07-23

View file

@ -63,7 +63,7 @@ add_openmw_dir (mwlua
context menuscripts globalscripts localscripts playerscripts luabindings objectbindings cellbindings coremwscriptbindings
mwscriptbindings camerabindings vfsbindings uibindings soundbindings inputbindings nearbybindings dialoguebindings
postprocessingbindings stats recordstore debugbindings corebindings worldbindings worker landbindings magicbindings factionbindings
classbindings itemdata inputprocessor animationbindings birthsignbindings racebindings markupbindings
classbindings itemdata inputprocessor animationbindings birthsignbindings racebindings markupbindings weatherbindings
types/types types/door types/item types/actor types/container types/lockable types/weapon types/npc
types/creature types/player types/activator types/book types/lockpick types/probe types/apparatus
types/potion types/ingredient types/misc types/repair types/armor types/light types/static

View file

@ -781,7 +781,6 @@ void OMW::Engine::prepareEngine()
const auto userdefault = mCfgMgr.getUserConfigPath() / "gamecontrollerdb.txt";
const auto localdefault = mCfgMgr.getLocalPath() / "gamecontrollerdb.txt";
const auto globaldefault = mCfgMgr.getGlobalPath() / "gamecontrollerdb.txt";
std::filesystem::path userGameControllerdb;
if (std::filesystem::exists(userdefault))
@ -790,9 +789,13 @@ void OMW::Engine::prepareEngine()
std::filesystem::path gameControllerdb;
if (std::filesystem::exists(localdefault))
gameControllerdb = localdefault;
else if (std::filesystem::exists(globaldefault))
else if (!mCfgMgr.getGlobalPath().empty())
{
const auto globaldefault = mCfgMgr.getGlobalPath() / "gamecontrollerdb.txt";
if (std::filesystem::exists(globaldefault))
gameControllerdb = globaldefault;
// else if it doesn't exist, pass in an empty string
}
// else if it doesn't exist, pass in an empty path
// gui needs our shaders path before everything else
mResourceSystem->getSceneManager()->setShaderPath(mResDir / "shaders");

View file

@ -22,6 +22,7 @@
namespace osg
{
class Vec3f;
class Vec4f;
class Matrixf;
class Quat;
class Image;
@ -93,6 +94,7 @@ namespace MWWorld
class RefData;
class Cell;
class DateTimeManager;
class Weather;
typedef std::vector<std::pair<MWWorld::Ptr, MWMechanics::Movement>> PtrMovementList;
}
@ -216,9 +218,21 @@ namespace MWBase
virtual void changeWeather(const ESM::RefId& region, const unsigned int id) = 0;
virtual int getCurrentWeather() const = 0;
virtual void changeWeather(const ESM::RefId& region, const ESM::RefId& id) = 0;
virtual int getNextWeather() const = 0;
virtual const std::vector<MWWorld::Weather>& getAllWeather() const = 0;
virtual int getCurrentWeatherScriptId() const = 0;
virtual const MWWorld::Weather& getCurrentWeather() const = 0;
virtual const MWWorld::Weather* getWeather(size_t index) const = 0;
virtual const MWWorld::Weather* getWeather(const ESM::RefId& id) const = 0;
virtual int getNextWeatherScriptId() const = 0;
virtual const MWWorld::Weather* getNextWeather() const = 0;
virtual float getWeatherTransition() const = 0;
@ -478,6 +492,7 @@ namespace MWBase
// Allow NPCs to use torches?
virtual bool useTorches() const = 0;
virtual const osg::Vec4f& getSunLightPosition() const = 0;
virtual float getSunVisibility() const = 0;
virtual float getSunPercentage() const = 0;

View file

@ -501,7 +501,7 @@ int MWDialogue::Filter::getSelectStructInteger(const SelectWrapper& select) cons
case ESM::DialogueCondition::Function_Weather:
return MWBase::Environment::get().getWorld()->getCurrentWeather();
return MWBase::Environment::get().getWorld()->getCurrentWeatherScriptId();
case ESM::DialogueCondition::Function_Reputation:
if (!mActor.getClass().isNpc())

View file

@ -27,6 +27,7 @@
#include "magicbindings.hpp"
#include "soundbindings.hpp"
#include "stats.hpp"
#include "weatherbindings.hpp"
namespace MWLua
{
@ -104,6 +105,9 @@ namespace MWLua
api["land"] = context.cachePackage("openmw_core_land", [context]() { return initCoreLandBindings(context); });
api["weather"]
= context.cachePackage("openmw_core_weather", [context]() { return initCoreWeatherBindings(context); });
api["factions"]
= context.cachePackage("openmw_core_factions", [context]() { return initCoreFactionBindings(context); });
api["dialogue"]

View file

@ -0,0 +1,185 @@
#include "weatherbindings.hpp"
#include <osg/Vec4f>
#include <components/esm3/loadregn.hpp>
#include <components/lua/util.hpp>
#include <components/misc/color.hpp>
#include <components/misc/resourcehelpers.hpp>
#include <components/resource/resourcesystem.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
#include "../mwworld/esmstore.hpp"
#include "../mwworld/weather.hpp"
#include "context.hpp"
namespace
{
class WeatherStore
{
public:
const MWWorld::Weather* get(size_t index) const
{
return MWBase::Environment::get().getWorld()->getWeather(index);
}
const MWWorld::Weather* get(const ESM::RefId& id) const
{
return MWBase::Environment::get().getWorld()->getWeather(id);
}
size_t size() const { return MWBase::Environment::get().getWorld()->getAllWeather().size(); }
};
Misc::Color color(const osg::Vec4f& color)
{
return Misc::Color(color.r(), color.g(), color.b(), color.a());
}
}
namespace MWLua
{
sol::table initCoreWeatherBindings(const Context& context)
{
sol::state_view lua = context.sol();
sol::table api(lua, sol::create);
auto vfs = MWBase::Environment::get().getResourceSystem()->getVFS();
auto weatherT = lua.new_usertype<MWWorld::Weather>("Weather");
weatherT[sol::meta_function::to_string]
= [](const MWWorld::Weather& w) -> std::string { return "Weather[" + w.mName + "]"; };
weatherT["name"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mName; });
weatherT["windSpeed"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mWindSpeed; });
weatherT["cloudSpeed"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mCloudSpeed; });
weatherT["cloudTexture"] = sol::readonly_property([vfs](const MWWorld::Weather& w) {
return Misc::ResourceHelpers::correctTexturePath(w.mCloudTexture, vfs);
});
weatherT["cloudsMaximumPercent"]
= sol::readonly_property([](const MWWorld::Weather& w) { return w.mCloudsMaximumPercent; });
weatherT["isStorm"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mIsStorm; });
weatherT["stormDirection"]
= sol::readonly_property([](const MWWorld::Weather& w) { return w.mStormDirection; });
weatherT["glareView"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mGlareView; });
weatherT["rainSpeed"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mRainSpeed; });
weatherT["rainEntranceSpeed"]
= sol::readonly_property([](const MWWorld::Weather& w) { return w.mRainEntranceSpeed; });
weatherT["rainEffect"] = sol::readonly_property([](const MWWorld::Weather& w) -> sol::optional<std::string> {
if (w.mRainEffect.empty())
return sol::nullopt;
return w.mRainEffect;
});
weatherT["rainMaxRaindrops"]
= sol::readonly_property([](const MWWorld::Weather& w) { return w.mRainMaxRaindrops; });
weatherT["rainDiameter"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mRainDiameter; });
weatherT["rainThreshold"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mRainThreshold; });
weatherT["rainMaxHeight"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mRainMaxHeight; });
weatherT["rainMinHeight"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mRainMinHeight; });
weatherT["rainLoopSoundID"]
= sol::readonly_property([](const MWWorld::Weather& w) { return w.mRainLoopSoundID.serializeText(); });
weatherT["thunderSoundID"] = sol::readonly_property([lua](const MWWorld::Weather& w) {
sol::table result(lua, sol::create);
for (const auto& soundId : w.mThunderSoundID)
result.add(soundId.serializeText());
return result;
});
weatherT["sunDiscSunsetColor"]
= sol::readonly_property([](const MWWorld::Weather& w) { return color(w.mSunDiscSunsetColor); });
weatherT["ambientLoopSoundID"]
= sol::readonly_property([](const MWWorld::Weather& w) { return w.mAmbientLoopSoundID.serializeText(); });
weatherT["ambientColor"] = sol::readonly_property([lua](const MWWorld::Weather& w) {
sol::table result(lua, sol::create);
result["sunrise"] = color(w.mAmbientColor.getSunriseValue());
result["day"] = color(w.mAmbientColor.getDayValue());
result["sunset"] = color(w.mAmbientColor.getSunsetValue());
result["night"] = color(w.mAmbientColor.getNightValue());
return result;
});
weatherT["fogColor"] = sol::readonly_property([lua](const MWWorld::Weather& w) {
sol::table result(lua, sol::create);
result["sunrise"] = color(w.mFogColor.getSunriseValue());
result["day"] = color(w.mFogColor.getDayValue());
result["sunset"] = color(w.mFogColor.getSunsetValue());
result["night"] = color(w.mFogColor.getNightValue());
return result;
});
weatherT["skyColor"] = sol::readonly_property([lua](const MWWorld::Weather& w) {
sol::table result(lua, sol::create);
result["sunrise"] = color(w.mSkyColor.getSunriseValue());
result["day"] = color(w.mSkyColor.getDayValue());
result["sunset"] = color(w.mSkyColor.getSunsetValue());
result["night"] = color(w.mSkyColor.getNightValue());
return result;
});
weatherT["sunColor"] = sol::readonly_property([lua](const MWWorld::Weather& w) {
sol::table result(lua, sol::create);
result["sunrise"] = color(w.mSunColor.getSunriseValue());
result["day"] = color(w.mSunColor.getDayValue());
result["sunset"] = color(w.mSunColor.getSunsetValue());
result["night"] = color(w.mSunColor.getNightValue());
return result;
});
weatherT["landFogDepth"] = sol::readonly_property([lua](const MWWorld::Weather& w) {
sol::table result(lua, sol::create);
result["sunrise"] = w.mLandFogDepth.getSunriseValue();
result["day"] = w.mLandFogDepth.getDayValue();
result["sunset"] = w.mLandFogDepth.getSunsetValue();
result["night"] = w.mLandFogDepth.getNightValue();
return result;
});
weatherT["particleEffect"]
= sol::readonly_property([](const MWWorld::Weather& w) -> sol::optional<std::string> {
if (w.mParticleEffect.empty())
return sol::nullopt;
return w.mParticleEffect;
});
weatherT["distantLandFogFactor"]
= sol::readonly_property([](const MWWorld::Weather& w) { return w.mDL.FogFactor; });
weatherT["distantLandFogOffset"]
= sol::readonly_property([](const MWWorld::Weather& w) { return w.mDL.FogOffset; });
weatherT["scriptId"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mScriptId; });
weatherT["recordId"] = sol::readonly_property([](const MWWorld::Weather& w) { return w.mId.serializeText(); });
api["getCurrent"] = []() { return MWBase::Environment::get().getWorld()->getCurrentWeather(); };
api["getNext"]
= []() -> const MWWorld::Weather* { return MWBase::Environment::get().getWorld()->getNextWeather(); };
api["getTransition"] = []() { return MWBase::Environment::get().getWorld()->getWeatherTransition(); };
api["changeWeather"] = [](std::string_view regionId, const MWWorld::Weather& weather) {
ESM::RefId region = ESM::RefId::deserializeText(regionId);
MWBase::Environment::get().getESMStore()->get<ESM::Region>().find(region);
MWBase::Environment::get().getWorld()->changeWeather(region, weather.mId);
};
sol::usertype<WeatherStore> storeT = lua.new_usertype<WeatherStore>("WeatherWorldStore");
storeT[sol::meta_function::to_string]
= [](const WeatherStore& store) { return "{" + std::to_string(store.size()) + " Weather records}"; };
storeT[sol::meta_function::length] = [](const WeatherStore& store) { return store.size(); };
storeT[sol::meta_function::index] = sol::overload(
[](const WeatherStore& store, size_t index) -> const MWWorld::Weather* {
return store.get(LuaUtil::fromLuaIndex(index));
},
[](const WeatherStore& store, std::string_view id) -> const MWWorld::Weather* {
return store.get(ESM::RefId::deserializeText(id));
});
storeT[sol::meta_function::ipairs] = lua["ipairsForArray"].template get<sol::function>();
storeT[sol::meta_function::pairs] = lua["ipairsForArray"].template get<sol::function>();
// Provide access to the store.
api["records"] = WeatherStore{};
api["getCurrentSunLightDirection"] = []() {
osg::Vec4f sunPos = MWBase::Environment::get().getWorld()->getSunLightPosition();
// normalize to get the direction towards the sun
sunPos.normalize();
// and invert it to get the direction of the sun light
return -sunPos;
};
api["getCurrentSunVisibility"] = []() { return MWBase::Environment::get().getWorld()->getSunVisibility(); };
api["getCurrentSunPercentage"] = []() { return MWBase::Environment::get().getWorld()->getSunPercentage(); };
api["getCurrentWindSpeed"] = []() { return MWBase::Environment::get().getWorld()->getWindSpeed(); };
api["getCurrentStormDirection"] = []() { return MWBase::Environment::get().getWorld()->getStormDirection(); };
return LuaUtil::makeReadOnly(api);
}
}

View file

@ -0,0 +1,14 @@
#ifndef MWLUA_WEATHERBINDINGS_H
#define MWLUA_WEATHERBINDINGS_H
#include <sol/forward.hpp>
namespace MWLua
{
struct Context;
sol::table initCoreWeatherBindings(const Context&);
}
#endif // MWLUA_WEATHERBINDINGS_H

View file

@ -73,6 +73,21 @@ namespace
namespace MWMechanics
{
struct ActiveSpells::UpdateContext
{
bool mUpdatedEnemy = false;
bool mUpdatedHitOverlay = false;
bool mUpdateSpellWindow = false;
bool mPlayNonLooping = false;
bool mEraseRemoved = false;
bool mUpdate;
UpdateContext(bool update)
: mUpdate(update)
{
}
};
ActiveSpells::IterationGuard::IterationGuard(ActiveSpells& spells)
: mActiveSpells(spells)
{
@ -256,8 +271,9 @@ namespace MWMechanics
++spellIt;
}
UpdateContext context(duration > 0.f);
for (const auto& spell : mQueue)
addToSpells(ptr, spell);
addToSpells(ptr, spell, context);
mQueue.clear();
// Vanilla only does this on cell change I think
@ -267,20 +283,17 @@ namespace MWMechanics
if (spell->mData.mType != ESM::Spell::ST_Spell && spell->mData.mType != ESM::Spell::ST_Power
&& !isSpellActive(spell->mId))
{
mSpells.emplace_back(ActiveSpellParams{ spell, ptr, true });
mSpells.back().setActiveSpellId(MWBase::Environment::get().getESMStore()->generateId());
initParams(ptr, ActiveSpellParams{ spell, ptr, true }, context);
}
}
bool updateSpellWindow = false;
bool playNonLooping = false;
if (ptr.getClass().hasInventoryStore(ptr)
&& !(creatureStats.isDead() && !creatureStats.isDeathAnimationFinished()))
{
auto& store = ptr.getClass().getInventoryStore(ptr);
if (store.getInvListener() != nullptr)
{
playNonLooping = !store.isFirstEquip();
context.mPlayNonLooping = !store.isFirstEquip();
const auto world = MWBase::Environment::get().getWorld();
for (int slotIndex = 0; slotIndex < MWWorld::InventoryStore::Slots; slotIndex++)
{
@ -306,18 +319,40 @@ namespace MWMechanics
// invisibility manually
purgeEffect(ptr, ESM::MagicEffect::Invisibility);
applyPurges(ptr);
ActiveSpellParams& params = mSpells.emplace_back(ActiveSpellParams{ *slot, enchantment, ptr });
params.setActiveSpellId(MWBase::Environment::get().getESMStore()->generateId());
updateSpellWindow = true;
ActiveSpellParams* params = initParams(ptr, ActiveSpellParams{ *slot, enchantment, ptr }, context);
if (params)
context.mUpdateSpellWindow = true;
}
}
}
const MWWorld::Ptr player = MWMechanics::getPlayer();
bool updatedHitOverlay = false;
bool updatedEnemy = false;
// Update effects
context.mEraseRemoved = true;
for (auto spellIt = mSpells.begin(); spellIt != mSpells.end();)
{
updateActiveSpell(ptr, duration, spellIt, context);
}
if (Settings::game().mClassicCalmSpellsBehavior)
{
ESM::MagicEffect::Effects effect
= ptr.getClass().isNpc() ? ESM::MagicEffect::CalmHumanoid : ESM::MagicEffect::CalmCreature;
if (creatureStats.getMagicEffects().getOrDefault(effect).getMagnitude() > 0.f)
creatureStats.getAiSequence().stopCombat();
}
if (ptr == player && context.mUpdateSpellWindow)
{
// Something happened with the spell list -- possibly while the game is paused,
// so we want to make the spell window get the memo.
// We don't normally want to do this, so this targets constant enchantments.
MWBase::Environment::get().getWindowManager()->updateSpellWindow();
}
}
bool ActiveSpells::updateActiveSpell(
const MWWorld::Ptr& ptr, float duration, Collection::iterator& spellIt, UpdateContext& context)
{
const auto caster = MWBase::Environment::get().getWorld()->searchPtrViaActorId(
spellIt->mCasterActorId); // Maybe make this search outside active grid?
@ -325,7 +360,7 @@ namespace MWMechanics
std::optional<ActiveSpellParams> reflected;
for (auto it = spellIt->mEffects.begin(); it != spellIt->mEffects.end();)
{
auto result = applyMagicEffect(ptr, caster, *spellIt, *it, duration, playNonLooping);
auto result = applyMagicEffect(ptr, caster, *spellIt, *it, duration, context.mPlayNonLooping);
if (result.mType == MagicApplicationResult::Type::REFLECTED)
{
if (!reflected)
@ -344,16 +379,17 @@ namespace MWMechanics
it = spellIt->mEffects.erase(it);
else
{
const MWWorld::Ptr player = MWMechanics::getPlayer();
++it;
if (!updatedEnemy && result.mShowHealth && caster == player && ptr != player)
if (!context.mUpdatedEnemy && result.mShowHealth && caster == player && ptr != player)
{
MWBase::Environment::get().getWindowManager()->setEnemy(ptr);
updatedEnemy = true;
context.mUpdatedEnemy = true;
}
if (!updatedHitOverlay && result.mShowHit && ptr == player)
if (!context.mUpdatedHitOverlay && result.mShowHit && ptr == player)
{
MWBase::Environment::get().getWindowManager()->activateHitOverlay(false);
updatedHitOverlay = true;
context.mUpdatedHitOverlay = true;
}
}
removedSpell = applyPurges(ptr, &spellIt, &it);
@ -375,13 +411,16 @@ namespace MWMechanics
caster.getClass().getCreatureStats(caster).getActiveSpells().addSpell(*reflected);
}
if (removedSpell)
continue;
return true;
if (context.mEraseRemoved)
{
bool remove = false;
if (spellIt->hasFlag(ESM::ActiveSpells::Flag_SpellStore))
{
try
{
auto& spells = ptr.getClass().getCreatureStats(ptr).getSpells();
remove = !spells.hasSpell(spellIt->mSourceSpellId);
}
catch (const std::runtime_error& e)
@ -413,30 +452,27 @@ namespace MWMechanics
for (const auto& effect : params.mEffects)
onMagicEffectRemoved(ptr, params, effect);
applyPurges(ptr, &spellIt);
updateSpellWindow = true;
continue;
context.mUpdateSpellWindow = true;
return true;
}
}
++spellIt;
return false;
}
if (Settings::game().mClassicCalmSpellsBehavior)
ActiveSpells::ActiveSpellParams* ActiveSpells::initParams(
const MWWorld::Ptr& ptr, const ActiveSpellParams& params, UpdateContext& context)
{
ESM::MagicEffect::Effects effect
= ptr.getClass().isNpc() ? ESM::MagicEffect::CalmHumanoid : ESM::MagicEffect::CalmCreature;
if (creatureStats.getMagicEffects().getOrDefault(effect).getMagnitude() > 0.f)
creatureStats.getAiSequence().stopCombat();
mSpells.emplace_back(params).setActiveSpellId(MWBase::Environment::get().getESMStore()->generateId());
auto it = mSpells.end();
--it;
// We instantly apply the effect with a duration of 0 so continuous effects can be purged before truly applying
if (context.mUpdate && updateActiveSpell(ptr, 0.f, it, context))
return nullptr;
return &*it;
}
if (ptr == player && updateSpellWindow)
{
// Something happened with the spell list -- possibly while the game is paused,
// so we want to make the spell window get the memo.
// We don't normally want to do this, so this targets constant enchantments.
MWBase::Environment::get().getWindowManager()->updateSpellWindow();
}
}
void ActiveSpells::addToSpells(const MWWorld::Ptr& ptr, const ActiveSpellParams& spell)
void ActiveSpells::addToSpells(const MWWorld::Ptr& ptr, const ActiveSpellParams& spell, UpdateContext& context)
{
if (!spell.hasFlag(ESM::ActiveSpells::Flag_Stackable))
{
@ -454,8 +490,7 @@ namespace MWMechanics
onMagicEffectRemoved(ptr, params, effect);
}
}
mSpells.emplace_back(spell);
mSpells.back().setActiveSpellId(MWBase::Environment::get().getESMStore()->generateId());
initParams(ptr, spell, context);
}
ActiveSpells::ActiveSpells()
@ -608,6 +643,8 @@ namespace MWMechanics
{
purge(
[=](const ActiveSpellParams&, const ESM::ActiveEffect& effect) {
if (!(effect.mFlags & ESM::ActiveEffect::Flag_Applied))
return false;
if (effectArg.empty())
return effect.mEffectId == effectId;
return effect.mEffectId == effectId && effect.getSkillOrAttribute() == effectArg;

View file

@ -116,17 +116,23 @@ namespace MWMechanics
IterationGuard(ActiveSpells& spells);
~IterationGuard();
};
struct UpdateContext;
std::list<ActiveSpellParams> mSpells;
std::vector<ActiveSpellParams> mQueue;
std::queue<Predicate> mPurges;
bool mIterating;
void addToSpells(const MWWorld::Ptr& ptr, const ActiveSpellParams& spell);
void addToSpells(const MWWorld::Ptr& ptr, const ActiveSpellParams& spell, UpdateContext& context);
bool applyPurges(const MWWorld::Ptr& ptr, std::list<ActiveSpellParams>::iterator* currentSpell = nullptr,
std::vector<ActiveEffect>::iterator* currentEffect = nullptr);
bool updateActiveSpell(
const MWWorld::Ptr& ptr, float duration, Collection::iterator& spellIt, UpdateContext& context);
ActiveSpellParams* initParams(const MWWorld::Ptr& ptr, const ActiveSpellParams& params, UpdateContext& context);
public:
ActiveSpells();

View file

@ -1326,19 +1326,37 @@ namespace MWMechanics
const MWWorld::Ptr player = getPlayer();
const MWBase::World* const world = MWBase::Environment::get().getWorld();
struct CacheEntry
{
MWWorld::Ptr mPtr;
float mMaxSpeed;
osg::Vec3f mHalfExtents;
Movement& mMovement;
};
std::vector<CacheEntry> cache;
cache.reserve(mActors.size());
for (const Actor& actor : mActors)
{
if (actor.isInvalid())
continue;
const MWWorld::Ptr& ptr = actor.getPtr();
const MWWorld::Class& cls = ptr.getClass();
cache.push_back({ ptr, cls.getMaxSpeed(ptr), world->getHalfExtents(ptr), cls.getMovementSettings(ptr) });
}
for (const CacheEntry& cached : cache)
{
const MWWorld::Ptr& ptr = cached.mPtr;
if (ptr == player)
continue; // Don't interfere with player controls.
const float maxSpeed = ptr.getClass().getMaxSpeed(ptr);
const float maxSpeed = cached.mMaxSpeed;
if (maxSpeed == 0.0)
continue; // Can't move, so there is no sense to predict collisions.
Movement& movement = ptr.getClass().getMovementSettings(ptr);
Movement& movement = cached.mMovement;
const osg::Vec2f origMovement(movement.mPosition[0], movement.mPosition[1]);
const bool isMoving = origMovement.length2() > 0.01;
if (movement.mPosition[1] < 0)
@ -1379,7 +1397,7 @@ namespace MWMechanics
const osg::Vec2f baseSpeed = origMovement * maxSpeed;
const osg::Vec3f basePos = ptr.getRefData().getPosition().asVec3();
const float baseRotZ = ptr.getRefData().getPosition().rot[2];
const osg::Vec3f halfExtents = world->getHalfExtents(ptr);
const osg::Vec3f& halfExtents = cached.mHalfExtents;
const float maxDistToCheck = isMoving ? maxDistForPartialAvoiding : maxDistForStrictAvoiding;
float timeToCheck = maxTimeToCheck;
@ -1392,15 +1410,13 @@ namespace MWMechanics
float angleToApproachingActor = 0;
// Iterate through all other actors and predict collisions.
for (const Actor& otherActor : mActors)
for (const CacheEntry& otherCached : cache)
{
if (otherActor.isInvalid())
continue;
const MWWorld::Ptr& otherPtr = otherActor.getPtr();
const MWWorld::Ptr& otherPtr = otherCached.mPtr;
if (otherPtr == ptr || otherPtr == currentTarget)
continue;
const osg::Vec3f otherHalfExtents = world->getHalfExtents(otherPtr);
const osg::Vec3f& otherHalfExtents = otherCached.mHalfExtents;
const osg::Vec3f deltaPos = otherPtr.getRefData().getPosition().asVec3() - basePos;
const osg::Vec2f relPos = Misc::rotateVec2f(osg::Vec2f(deltaPos.x(), deltaPos.y()), baseRotZ);
const float dist = deltaPos.length();
@ -1413,8 +1429,7 @@ namespace MWMechanics
if (deltaPos.z() > halfExtents.z() * 2 || deltaPos.z() < -otherHalfExtents.z() * 2)
continue;
const osg::Vec3f speed = otherPtr.getClass().getMovementSettings(otherPtr).asVec3()
* otherPtr.getClass().getMaxSpeed(otherPtr);
const osg::Vec3f speed = otherCached.mMovement.asVec3() * otherCached.mMaxSpeed;
const float rotZ = otherPtr.getRefData().getPosition().rot[2];
const osg::Vec2f relSpeed
= Misc::rotateVec2f(osg::Vec2f(speed.x(), speed.y()), baseRotZ - rotZ) - baseSpeed;

View file

@ -178,11 +178,16 @@ namespace MWMechanics
currentCell = actor.getCell();
}
const MWWorld::Class& actorClass = actor.getClass();
MWMechanics::CreatureStats& stats = actorClass.getCreatureStats(actor);
if (stats.isParalyzed() || stats.getKnockedDown())
return false;
bool forceFlee = false;
if (!canFight(actor, target))
{
storage.stopAttack();
actor.getClass().getCreatureStats(actor).setAttackingOrSpell(false);
stats.setAttackingOrSpell(false);
storage.mActionCooldown = 0.f;
// Continue combat if target is player or player follower/escorter and an attack has been attempted
const auto& playerFollowersAndEscorters
@ -191,18 +196,14 @@ namespace MWMechanics
= (std::find(playerFollowersAndEscorters.begin(), playerFollowersAndEscorters.end(), target)
!= playerFollowersAndEscorters.end());
if ((target == MWMechanics::getPlayer() || targetSidesWithPlayer)
&& ((actor.getClass().getCreatureStats(actor).getHitAttemptActorId()
== target.getClass().getCreatureStats(target).getActorId())
|| (target.getClass().getCreatureStats(target).getHitAttemptActorId()
== actor.getClass().getCreatureStats(actor).getActorId())))
&& ((stats.getHitAttemptActorId() == target.getClass().getCreatureStats(target).getActorId())
|| (target.getClass().getCreatureStats(target).getHitAttemptActorId() == stats.getActorId())))
forceFlee = true;
else // Otherwise end combat
return true;
}
const MWWorld::Class& actorClass = actor.getClass();
actorClass.getCreatureStats(actor).setMovementFlag(CreatureStats::Flag_Run, true);
stats.setMovementFlag(CreatureStats::Flag_Run, true);
float& actionCooldown = storage.mActionCooldown;
std::unique_ptr<Action>& currentAction = storage.mCurrentAction;
@ -330,7 +331,7 @@ namespace MWMechanics
{
storage.mUseCustomDestination = false;
storage.stopAttack();
actor.getClass().getCreatureStats(actor).setAttackingOrSpell(false);
stats.setAttackingOrSpell(false);
currentAction = std::make_unique<ActionFlee>();
actionCooldown = currentAction->getActionCooldown();
storage.startFleeing();

View file

@ -2310,17 +2310,13 @@ namespace MWMechanics
}
else
{
// Do not play turning animation for player if rotation speed is very slow.
// Actual threshold should take framerate in account.
float rotationThreshold = (isPlayer ? 0.015f : 0.001f) * 60 * duration;
// It seems only bipedal actors use turning animations.
// Also do not use turning animations in the first-person view and when sneaking.
if (!sneak && !isFirstPersonPlayer && isBiped)
{
if (effectiveRotation > rotationThreshold)
if (effectiveRotation > 0.f)
movestate = inwater ? CharState_SwimTurnRight : CharState_TurnRight;
else if (effectiveRotation < -rotationThreshold)
else if (effectiveRotation < 0.f)
movestate = inwater ? CharState_SwimTurnLeft : CharState_TurnLeft;
}
}
@ -2346,20 +2342,6 @@ namespace MWMechanics
vec.y() *= std::sqrt(1.0f - swimUpwardCoef * swimUpwardCoef);
}
// Player can not use smooth turning as NPCs, so we play turning animation a bit to avoid jittering
if (isPlayer)
{
float threshold = mCurrentMovement.find("swim") == std::string::npos ? 0.4f : 0.8f;
float complete;
bool animPlaying = mAnimation->getInfo(mCurrentMovement, &complete);
if (movestate == CharState_None && jumpstate == JumpState_None && isTurning())
{
if (animPlaying && complete < threshold)
movestate = mMovementState;
}
}
else
{
if (isBiped)
{
if (mTurnAnimationThreshold > 0)
@ -2375,7 +2357,6 @@ namespace MWMechanics
movestate = mMovementState;
}
}
}
if (movestate != CharState_None)
{
@ -2402,11 +2383,10 @@ namespace MWMechanics
if (isTurning())
{
// Adjust animation speed from 1.0 to 1.5 multiplier
if (duration > 0)
{
float turnSpeed = std::min(1.5f, std::abs(rot.z()) / duration / static_cast<float>(osg::PI));
mAnimation->adjustSpeedMult(mCurrentMovement, std::max(turnSpeed, 1.0f));
mAnimation->adjustSpeedMult(mCurrentMovement, turnSpeed);
}
}
else if (mMovementState != CharState_None && mAdjustMovementAnimSpeed)

View file

@ -215,10 +215,6 @@ namespace MWMechanics
bool hasDuration = !(magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration);
effect.mDuration = hasDuration ? static_cast<float>(enam.mData.mDuration) : 1.f;
bool appliedOnce = magicEffect->mData.mFlags & ESM::MagicEffect::AppliedOnce;
if (!appliedOnce)
effect.mDuration = std::max(1.f, effect.mDuration);
effect.mTimeLeft = effect.mDuration;
// add to list of active effects, to apply in next frame

View file

@ -1011,11 +1011,13 @@ namespace MWMechanics
else
{
// Morrowind.exe doesn't apply magic effects while the menu is open, we do because we like to see stats
// updated instantly. We don't want to teleport instantly though
// updated instantly. We don't want to teleport instantly though. Nor do we want to force players to drink
// invisibility potions in the "right" order
if (!dt
&& (effect.mEffectId == ESM::MagicEffect::Recall
|| effect.mEffectId == ESM::MagicEffect::DivineIntervention
|| effect.mEffectId == ESM::MagicEffect::AlmsiviIntervention))
|| effect.mEffectId == ESM::MagicEffect::AlmsiviIntervention
|| effect.mEffectId == ESM::MagicEffect::Invisibility))
return { MagicApplicationResult::Type::APPLIED, receivedMagicDamage, affectedHealth };
auto& stats = target.getClass().getCreatureStats(target);
auto& magnitudes = stats.getMagicEffects();

View file

@ -943,8 +943,8 @@ namespace MWRender
stateUpdater->setIsUnderwater(isUnderwater);
stateUpdater->setFogColor(fogColor);
stateUpdater->setGameHour(world->getTimeStamp().getHour());
stateUpdater->setWeatherId(world->getCurrentWeather());
stateUpdater->setNextWeatherId(world->getNextWeather());
stateUpdater->setWeatherId(world->getCurrentWeatherScriptId());
stateUpdater->setNextWeatherId(world->getNextWeatherScriptId());
stateUpdater->setWeatherTransition(world->getWeatherTransition());
stateUpdater->setWindSpeed(world->getWindSpeed());
stateUpdater->setSkyColor(mSky->getSkyColor());

View file

@ -139,6 +139,7 @@ namespace MWRender
int skyGetSecundaPhase() const;
void skySetMoonColour(bool red);
const osg::Vec4f& getSunLightPosition() const { return mSunLight->getPosition(); }
void setSunDirection(const osg::Vec3f& direction);
void setSunColour(const osg::Vec4f& diffuse, const osg::Vec4f& specular, float sunVis);
void setNight(bool isNight) { mNight = isNight; }

View file

@ -71,7 +71,7 @@ namespace MWScript
public:
void execute(Interpreter::Runtime& runtime) override
{
runtime.push(MWBase::Environment::get().getWorld()->getCurrentWeather());
runtime.push(MWBase::Environment::get().getWorld()->getCurrentWeatherScriptId());
}
};

View file

@ -1,5 +1,6 @@
#include "weather.hpp"
#include <components/esm/stringrefid.hpp>
#include <components/settings/values.hpp>
#include <components/misc/rng.hpp>
@ -141,9 +142,12 @@ namespace MWWorld
return direction;
}
Weather::Weather(const std::string& name, float stormWindSpeed, float rainSpeed, float dlFactor, float dlOffset,
const std::string& particleEffect)
: mCloudTexture(Fallback::Map::getString("Weather_" + name + "_Cloud_Texture"))
Weather::Weather(ESM::RefId id, int scriptId, const std::string& name, float stormWindSpeed, float rainSpeed,
float dlFactor, float dlOffset, const std::string& particleEffect)
: mId(id)
, mScriptId(scriptId)
, mName(name)
, mCloudTexture(Fallback::Map::getString("Weather_" + name + "_Cloud_Texture"))
, mSkyColor(Fallback::Map::getColour("Weather_" + name + "_Sky_Sunrise_Color"),
Fallback::Map::getColour("Weather_" + name + "_Sky_Day_Color"),
Fallback::Map::getColour("Weather_" + name + "_Sky_Sunset_Color"),
@ -676,6 +680,41 @@ namespace MWWorld
stopSounds();
}
const Weather* WeatherManager::getWeather(size_t index) const
{
if (index < mWeatherSettings.size())
return &mWeatherSettings[index];
return nullptr;
}
const Weather* WeatherManager::getWeather(const ESM::RefId& id) const
{
auto it = std::find_if(
mWeatherSettings.begin(), mWeatherSettings.end(), [id](const auto& weather) { return weather.mId == id; });
if (it != mWeatherSettings.end())
return &*it;
return nullptr;
}
void WeatherManager::changeWeather(const ESM::RefId& regionID, const ESM::RefId& weatherID)
{
auto wIt = std::find_if(mWeatherSettings.begin(), mWeatherSettings.end(),
[weatherID](const auto& weather) { return weather.mId == weatherID; });
if (wIt != mWeatherSettings.end())
{
auto rIt = mRegions.find(regionID);
if (rIt != mRegions.end())
{
rIt->second.setWeather(std::distance(mWeatherSettings.begin(), wIt));
regionalWeatherChanged(rIt->first, rIt->second);
}
}
}
void WeatherManager::changeWeather(const ESM::RefId& regionID, const unsigned int weatherID)
{
// In Morrowind, this seems to have the following behavior, when applied to the current region:
@ -1053,8 +1092,9 @@ namespace MWWorld
const std::string& name, float dlFactor, float dlOffset, const std::string& particleEffect)
{
static const float fStromWindSpeed = mStore.get<ESM::GameSetting>().find("fStromWindSpeed")->mValue.getFloat();
Weather weather(name, fStromWindSpeed, mRainSpeed, dlFactor, dlOffset, particleEffect);
ESM::StringRefId id(name);
Weather weather(
id, mWeatherSettings.size(), name, fStromWindSpeed, mRainSpeed, dlFactor, dlOffset, particleEffect);
mWeatherSettings.push_back(weather);
}

View file

@ -109,6 +109,11 @@ namespace MWWorld
T getValue(const float gameHour, const TimeOfDaySettings& timeSettings, const std::string& prefix) const;
const T& getSunriseValue() const { return mSunriseValue; }
const T& getDayValue() const { return mDayValue; }
const T& getSunsetValue() const { return mSunsetValue; }
const T& getNightValue() const { return mNightValue; }
private:
T mSunriseValue, mDayValue, mSunsetValue, mNightValue;
};
@ -119,9 +124,12 @@ namespace MWWorld
public:
static osg::Vec3f defaultDirection();
Weather(const std::string& name, float stormWindSpeed, float rainSpeed, float dlFactor, float dlOffset,
const std::string& particleEffect);
Weather(const ESM::RefId id, const int scriptId, const std::string& name, float stormWindSpeed, float rainSpeed,
float dlFactor, float dlOffset, const std::string& particleEffect);
ESM::RefId mId;
int mScriptId;
std::string mName;
std::string mCloudTexture;
// Sky (atmosphere) color
@ -289,11 +297,12 @@ namespace MWWorld
~WeatherManager();
/**
* Change the weather in the specified region
* Change the weather in the specified region by id of the weather
* @param region that should be changed
* @param ID of the weather setting to shift to
*/
void changeWeather(const ESM::RefId& regionID, const unsigned int weatherID);
void changeWeather(const ESM::RefId& regionID, const ESM::RefId& weatherID);
void modRegion(const ESM::RefId& regionID, const std::vector<uint8_t>& chances);
void playerTeleported(const ESM::RefId& playerRegion, bool isExterior);
@ -316,8 +325,23 @@ namespace MWWorld
void advanceTime(double hours, bool incremental);
const std::vector<Weather>& getAllWeather() { return mWeatherSettings; }
const Weather& getWeather() { return mWeatherSettings[mCurrentWeather]; }
const Weather* getWeather(size_t index) const;
const Weather* getWeather(const ESM::RefId& id) const;
int getWeatherID() const { return mCurrentWeather; }
const Weather* getNextWeather()
{
if (mNextWeather > -1)
return &mWeatherSettings[mNextWeather];
return nullptr;
}
int getNextWeatherID() const { return mNextWeather; }
float getTransitionFactor() const { return mTransitionFactor; }

View file

@ -1868,14 +1868,43 @@ namespace MWWorld
return ESM::Cell::sDefaultWorldspaceId;
}
int World::getCurrentWeather() const
const std::vector<MWWorld::Weather>& World::getAllWeather() const
{
return mWeatherManager->getWeatherID();
return mWeatherManager->getAllWeather();
}
int World::getNextWeather() const
int World::getCurrentWeatherScriptId() const
{
return mWeatherManager->getNextWeatherID();
return mWeatherManager->getWeather().mScriptId;
}
const MWWorld::Weather& World::getCurrentWeather() const
{
return mWeatherManager->getWeather();
}
const MWWorld::Weather* World::getWeather(size_t index) const
{
return mWeatherManager->getWeather(index);
}
const MWWorld::Weather* World::getWeather(const ESM::RefId& id) const
{
return mWeatherManager->getWeather(id);
}
int World::getNextWeatherScriptId() const
{
auto next = mWeatherManager->getNextWeather();
if (next == nullptr)
return -1;
return next->mScriptId;
}
const MWWorld::Weather* World::getNextWeather() const
{
return mWeatherManager->getNextWeather();
}
float World::getWeatherTransition() const
@ -1893,6 +1922,11 @@ namespace MWWorld
mWeatherManager->changeWeather(region, id);
}
void World::changeWeather(const ESM::RefId& region, const ESM::RefId& id)
{
mWeatherManager->changeWeather(region, id);
}
void World::modRegion(const ESM::RefId& regionid, const std::vector<uint8_t>& chances)
{
mWeatherManager->modRegion(regionid, chances);
@ -3133,6 +3167,11 @@ namespace MWWorld
}
}
const osg::Vec4f& World::getSunLightPosition() const
{
return mRendering->getSunLightPosition();
}
float World::getSunVisibility() const
{
return mWeatherManager->getSunVisibility();

View file

@ -317,9 +317,16 @@ namespace MWWorld
void changeWeather(const ESM::RefId& region, const unsigned int id) override;
int getCurrentWeather() const override;
void changeWeather(const ESM::RefId& region, const ESM::RefId& id) override;
int getNextWeather() const override;
const std::vector<MWWorld::Weather>& getAllWeather() const override;
int getCurrentWeatherScriptId() const override;
const MWWorld::Weather& getCurrentWeather() const override;
const MWWorld::Weather* getWeather(size_t index) const override;
const MWWorld::Weather* getWeather(const ESM::RefId& id) const override;
int getNextWeatherScriptId() const override;
const MWWorld::Weather* getNextWeather() const override;
float getWeatherTransition() const override;
@ -573,6 +580,7 @@ namespace MWWorld
// Allow NPCs to use torches?
bool useTorches() const override;
const osg::Vec4f& getSunLightPosition() const override;
float getSunVisibility() const override;
float getSunPercentage() const override;

View file

@ -7,6 +7,7 @@
#include <components/esm3/loadnpc.hpp>
#include <components/esm3/readerscache.hpp>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
namespace MWWorld
@ -36,7 +37,7 @@ namespace MWWorld
LiveCellRef<ESM::NPC> liveCellRef(cellRef, &npc);
liveCellRef.mData.setDeletedByContentFile(true);
Ptr ptr(&liveCellRef);
EXPECT_EQ(ptr.toString(), "deleted object0xd00002a (NPC, \"player\")");
EXPECT_THAT(ptr.toString(), StrCaseEq("deleted object0xd00002a (NPC, \"player\")"));
}
TEST(MWWorldPtrTest, toStringShouldReturnHumanReadableTextRepresentationOfPtr)
@ -53,7 +54,7 @@ namespace MWWorld
cellRef.mRefNum = ESM::RefNum{ .mIndex = 0x2a, .mContentFile = 0xd };
LiveCellRef<ESM::NPC> liveCellRef(cellRef, &npc);
Ptr ptr(&liveCellRef);
EXPECT_EQ(ptr.toString(), "object0xd00002a (NPC, \"player\")");
EXPECT_THAT(ptr.toString(), StrCaseEq("object0xd00002a (NPC, \"player\")"));
}
TEST(MWWorldPtrTest, underlyingLiveCellRefShouldBeDeregisteredOnDestruction)

View file

@ -18,37 +18,33 @@ namespace Files
namespace bpo = boost::program_options;
namespace
{
#if defined(_WIN32) || defined(__WINDOWS__)
static const char* const applicationName = "OpenMW";
constexpr auto applicationName = "OpenMW";
#else
static const char* const applicationName = "openmw";
constexpr auto applicationName = "openmw";
#endif
static constexpr auto localToken = u8"?local?";
static constexpr auto userConfigToken = u8"?userconfig?";
static constexpr auto userDataToken = u8"?userdata?";
static constexpr auto globalToken = u8"?global?";
using GetPath = const std::filesystem::path& (Files::FixedPath<>::*)() const;
constexpr std::array<std::pair<std::u8string_view, GetPath>, 4> sTokenMappings = {
std::make_pair(u8"?local?", &FixedPath<>::getLocalPath),
std::make_pair(u8"?userconfig?", &FixedPath<>::getUserConfigPath),
std::make_pair(u8"?userdata?", &FixedPath<>::getUserDataPath),
std::make_pair(u8"?global?", &FixedPath<>::getGlobalDataPath),
};
}
ConfigurationManager::ConfigurationManager(bool silent)
: mFixedPath(applicationName)
, mSilent(silent)
{
setupTokensMapping();
// Initialize with fixed paths, will be overridden in `readConfiguration`.
mUserDataPath = mFixedPath.getUserDataPath();
mScreenshotPath = mFixedPath.getUserDataPath() / "screenshots";
}
ConfigurationManager::~ConfigurationManager() {}
void ConfigurationManager::setupTokensMapping()
{
mTokensMapping.insert(std::make_pair(localToken, &FixedPath<>::getLocalPath));
mTokensMapping.insert(std::make_pair(userConfigToken, &FixedPath<>::getUserConfigPath));
mTokensMapping.insert(std::make_pair(userDataToken, &FixedPath<>::getUserDataPath));
mTokensMapping.insert(std::make_pair(globalToken, &FixedPath<>::getGlobalDataPath));
}
ConfigurationManager::~ConfigurationManager() = default;
static bool hasReplaceConfig(const bpo::variables_map& variables)
{
@ -74,7 +70,7 @@ namespace Files
std::optional<bpo::variables_map> config = loadConfig(mFixedPath.getLocalPath(), description);
if (config)
mActiveConfigPaths.push_back(mFixedPath.getLocalPath());
else
else if (!mFixedPath.getGlobalConfigPath().empty())
{
mActiveConfigPaths.push_back(mFixedPath.getGlobalConfigPath());
config = loadConfig(mFixedPath.getGlobalConfigPath(), description);
@ -305,15 +301,18 @@ namespace Files
const auto pos = str.find('?', 1);
if (pos != std::u8string::npos && pos != 0)
{
auto tokenIt = mTokensMapping.find(str.substr(0, pos + 1));
if (tokenIt != mTokensMapping.end())
std::u8string_view view(str);
auto token = view.substr(0, pos + 1);
auto found = std::find_if(
sTokenMappings.begin(), sTokenMappings.end(), [&](const auto& item) { return item.first == token; });
if (found != sTokenMappings.end())
{
auto tempPath(((mFixedPath).*(tokenIt->second))());
if (pos < str.length() - 1)
auto tempPath(((mFixedPath).*(found->second))());
if (!tempPath.empty() && pos < view.length() - 1)
{
// There is something after the token, so we should
// append it to the path
tempPath /= str.substr(pos + 1, str.length() - pos);
tempPath /= view.substr(pos + 1, view.length() - pos);
}
path = std::move(tempPath);

View file

@ -62,17 +62,12 @@ namespace Files
private:
typedef Files::FixedPath<> FixedPathType;
typedef const std::filesystem::path& (FixedPathType::*path_type_f)() const;
typedef std::map<std::u8string, path_type_f> TokensMappingContainer;
std::optional<boost::program_options::variables_map> loadConfig(
const std::filesystem::path& path, const boost::program_options::options_description& description) const;
void addExtraConfigDirs(
std::stack<std::filesystem::path>& dirs, const boost::program_options::variables_map& variables) const;
void setupTokensMapping();
std::vector<std::filesystem::path> mActiveConfigPaths;
FixedPathType mFixedPath;
@ -80,8 +75,6 @@ namespace Files
std::filesystem::path mUserDataPath;
std::filesystem::path mScreenshotPath;
TokensMappingContainer mTokensMapping;
bool mSilent;
};

View file

@ -8,21 +8,11 @@
namespace Files
{
inline QString getLocalConfigPathQString(const Files::ConfigurationManager& cfgMgr)
{
return Files::pathToQString(cfgMgr.getLocalPath() / openmwCfgFile);
}
inline QString getUserConfigPathQString(const Files::ConfigurationManager& cfgMgr)
{
return Files::pathToQString(cfgMgr.getUserConfigPath() / openmwCfgFile);
}
inline QString getGlobalConfigPathQString(const Files::ConfigurationManager& cfgMgr)
{
return Files::pathToQString(cfgMgr.getGlobalPath() / openmwCfgFile);
}
inline QStringList getActiveConfigPathsQString(const Files::ConfigurationManager& cfgMgr)
{
const auto& activePaths = cfgMgr.getActiveConfigPaths();

View file

@ -54,19 +54,7 @@ namespace Files
{
// The concept of a global config path is absurd on Windows.
// Always use local config instead.
// The virtual base class requires that we provide this, though.
std::filesystem::path globalPath = std::filesystem::current_path();
PWSTR cString;
HRESULT result = SHGetKnownFolderPath(FOLDERID_ProgramFiles, 0, nullptr, &cString);
if (SUCCEEDED(result))
globalPath = std::filesystem::path(cString);
else
Log(Debug::Error) << "Error " << result << " when getting Program Files path";
CoTaskMemFree(cString);
return globalPath / mName;
return {};
}
std::filesystem::path WindowsPath::getLocalPath() const

View file

@ -34,7 +34,7 @@ namespace Files
std::filesystem::path getUserDataPath() const;
/**
* \brief Returns "X:\Program Files\"
* \brief Returns an empty path
*
* \return std::filesystem::path
*/

View file

@ -1,5 +1,8 @@
The code in this directory is copied from https://github.com/ThePhD/sol2.git (64096348465b980e2f1d0e5ba9cbeea8782e8f27)
The code in this directory is copied from https://github.com/ThePhD/sol2.git (c1f95a773c6f8f4fde8ca3efe872e7286afe4444) and has been patched to include
Additional changes include cherry-picking upstream commit d805d027e0a0a7222e936926139f06e23828ce9f to fix compilation under Clang 19.
https://github.com/ThePhD/sol2/pull/1674 (71d85143ad69164f5f52c3bdab91fb503c676eb4)
https://github.com/ThePhD/sol2/pull/1676 (a6872ef46b08704b9069ebf83161f4637459ce63)
https://github.com/ThePhD/sol2/pull/1716 (5b6881ed94c795298eae72b6848308e9a37e42c5)
https://github.com/ThePhD/sol2/pull/1722 (ab874eb0e8ef8aea4c10074a89efa25f62a29d9a)
License: MIT

47
extern/sol3/sol/abort.hpp vendored Normal file
View file

@ -0,0 +1,47 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 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.
#ifndef SOL_ABORT_HPP
#define SOL_ABORT_HPP
#include <sol/version.hpp>
#include <sol/base_traits.hpp>
#include <cstdlib>
// clang-format off
#if SOL_IS_ON(SOL_DEBUG_BUILD)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
#define SOL_DEBUG_ABORT() \
if (true) { ::std::abort(); } \
static_assert(true, "")
#else
#define SOL_DEBUG_ABORT() ::std::abort()
#endif
#else
#define SOL_DEBUG_ABORT() static_assert(true, "")
#endif
// clang-format on
#endif // SOL_ABORT_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -28,7 +28,7 @@
#include <sol/forward.hpp>
#if SOL_IS_ON(SOL2_CI_I_)
#if SOL_IS_ON(SOL2_CI)
struct pre_main {
pre_main() {
@ -43,15 +43,15 @@ struct pre_main {
// clang-format off
#if SOL_IS_ON(SOL_USER_C_ASSERT_I_)
#define sol_c_assert(...) SOL_C_ASSERT(__VA_ARGS__)
#if SOL_IS_ON(SOL_USER_ASSERT)
#define SOL_ASSERT(...) SOL_C_ASSERT(__VA_ARGS__)
#else
#if SOL_IS_ON(SOL_DEBUG_BUILD_I_)
#if SOL_IS_ON(SOL_DEBUG_BUILD)
#include <exception>
#include <iostream>
#include <cstdlib>
#define sol_c_assert(...) \
#define SOL_ASSERT(...) \
do { \
if (!(__VA_ARGS__)) { \
std::cerr << "Assertion `" #__VA_ARGS__ "` failed in " << __FILE__ << " line " << __LINE__ << std::endl; \
@ -59,7 +59,7 @@ struct pre_main {
} \
} while (false)
#else
#define sol_c_assert(...) \
#define SOL_ASSERT(...) \
do { \
if (false) { \
(void)(__VA_ARGS__); \
@ -68,15 +68,15 @@ struct pre_main {
#endif
#endif
#if SOL_IS_ON(SOL_USER_M_ASSERT_I_)
#define sol_m_assert(message, ...) SOL_M_ASSERT(message, __VA_ARGS__)
#if SOL_IS_ON(SOL_USER_ASSERT_MSG)
#define SOL_ASSERT_MSG(message, ...) SOL_ASSERT_MSG(message, __VA_ARGS__)
#else
#if SOL_IS_ON(SOL_DEBUG_BUILD_I_)
#if SOL_IS_ON(SOL_DEBUG_BUILD)
#include <exception>
#include <iostream>
#include <cstdlib>
#define sol_m_assert(message, ...) \
#define SOL_ASSERT_MSG(message, ...) \
do { \
if (!(__VA_ARGS__)) { \
std::cerr << "Assertion `" #__VA_ARGS__ "` failed in " << __FILE__ << " line " << __LINE__ << ": " << message << std::endl; \
@ -84,7 +84,7 @@ struct pre_main {
} \
} while (false)
#else
#define sol_m_assert(message, ...) \
#define SOL_ASSERT_MSG(message, ...) \
do { \
if (false) { \
(void)(__VA_ARGS__); \

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -62,6 +62,39 @@ namespace sol {
template <template <class...> class Trait, class... Args>
constexpr inline bool is_detected_v = is_detected<Trait, Args...>::value;
template <typename _Default, typename _Void, template <typename...> typename _Op, typename... _Args>
class detector {
public:
using value_t = ::std::false_type;
using type = _Default;
};
template <typename _Default, template <typename...> typename _Op, typename... _Args>
class detector<_Default, void_t<_Op<_Args...>>, _Op, _Args...> {
public:
using value_t = ::std::true_type;
using type = _Op<_Args...>;
};
class nonesuch {
public:
~nonesuch() = delete;
nonesuch(nonesuch const&) = delete;
nonesuch& operator=(nonesuch const&) = delete;
};
template <template <typename...> typename _Op, typename... _Args>
using detected_t = typename detector<nonesuch, void, _Op, _Args...>::type;
template <typename _Default, template <typename...> typename _Op, typename... _Args>
using detected_or = detector<_Default, void, _Op, _Args...>;
template <typename _Default, template <typename...> typename _Op, typename... _Args>
using detected_or_t = typename detector<_Default, void, _Op, _Args...>::type;
template <typename _Default, template <typename...> typename _Op, typename... _Args>
constexpr inline bool detected_or_v = detector<_Default, void, _Op, _Args...>::value;
template <std::size_t I>
using index_value = std::integral_constant<std::size_t, I>;

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -31,7 +31,7 @@
namespace sol { namespace meta {
namespace meta_detail {
template <typename F>
using detect_deducible_signature = decltype(&F::operator(), void());
using detect_deducible_signature = decltype(&F::operator());
} // namespace meta_detail
template <typename F>
@ -196,7 +196,7 @@ namespace sol { namespace meta {
typedef R (T::*function_pointer_type)(Args..., ...) const volatile&&;
};
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_)
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
template <typename R, typename... Args>
struct fx_traits<R(Args...) noexcept, false> : public basic_traits<true, false, void, R, Args...> {
@ -311,7 +311,7 @@ namespace sol { namespace meta {
#endif // noexcept is part of a function's type
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_) && SOL_IS_ON(SOL_PLATFORM_X86_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX) && SOL_IS_ON(SOL_PLATFORM_X86)
template <typename R, typename... Args>
struct fx_traits<R __stdcall(Args...), false> : public basic_traits<false, false, void, R, Args...> {
typedef R(__stdcall* function_pointer_type)(Args...);
@ -369,7 +369,7 @@ namespace sol { namespace meta {
typedef R (__stdcall T::*function_pointer_type)(Args...) const volatile&&;
};
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_)
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
template <typename R, typename... Args>
struct fx_traits<R __stdcall(Args...) noexcept, false> : public basic_traits<true, false, void, R, Args...> {

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -99,7 +99,7 @@ namespace sol {
using storage_t = Container;
const std::byte* p_code = static_cast<const std::byte*>(memory);
storage_t& bc = *static_cast<storage_t*>(userdata_pointer);
#if SOL_IS_OFF(SOL_EXCEPTIONS_I_)
#if SOL_IS_OFF(SOL_EXCEPTIONS)
bc.insert(bc.cend(), p_code, p_code + memory_size);
#else
try {

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -54,7 +54,7 @@ namespace sol {
lua_createtable(L, static_cast<int>(sizeof...(In)), 0);
stack_reference deps(L, -1);
auto per_dep = [&L, &deps](int i) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow
lua_pushvalue(L, i);
@ -79,7 +79,7 @@ namespace sol {
}
lua_createtable(L, static_cast<int>(sdeps.size()), 0);
stack_reference deps(L, -1);
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, static_cast<int>(sdeps.size()), detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow
for (std::size_t i = 0; i < sdeps.size(); ++i) {
@ -429,7 +429,7 @@ namespace sol {
}
};
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_)
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
template <bool is_index, bool is_variable, bool checked, int boost, bool clean_stack, typename C>
struct agnostic_lua_call_wrapper<detail::lua_CFunction_noexcept, is_index, is_variable, checked, boost, clean_stack, C> {
static int call(lua_State* L, detail::lua_CFunction_noexcept f) {
@ -478,12 +478,13 @@ namespace sol {
using object_type = typename wrap::object_type;
if constexpr (sizeof...(Args) < 1) {
using Ta = meta::conditional_t<std::is_void_v<T>, object_type, T>;
static_assert(std::is_base_of_v<object_type, Ta>,
static_assert(std::is_same_v<object_type, Ta> || std::is_base_of_v<object_type, Ta>,
"It seems like you might have accidentally bound a class type with a member function method that does not correspond to the "
"class. For example, there could be a small type in your new_usertype<T>(...) binding, where you specify one class \"T\" "
"but then bind member methods from a complete unrelated class. Check things over!");
#if SOL_IS_ON(SOL_SAFE_USERTYPE_I_)
auto maybeo = stack::check_get<Ta*>(L, 1);
#if SOL_IS_ON(SOL_SAFE_USERTYPE)
stack::record tracking {};
auto maybeo = stack::stack_detail::check_get_arg<Ta*>(L, 1, &no_panic, tracking);
if (!maybeo || maybeo.value() == nullptr) {
return luaL_error(L,
"sol: received nil for 'self' argument (use ':' for accessing member functions, make sure member variables are "
@ -511,12 +512,13 @@ namespace sol {
if constexpr (is_index) {
if constexpr (sizeof...(Args) < 1) {
using Ta = meta::conditional_t<std::is_void_v<T>, object_type, T>;
static_assert(std::is_base_of_v<object_type, Ta>,
static_assert(std::is_same_v<object_type, Ta> || std::is_base_of_v<object_type, Ta>,
"It seems like you might have accidentally bound a class type with a member function method that does not correspond "
"to the class. For example, there could be a small type in your new_usertype<T>(...) binding, where you specify one "
"class \"T\" but then bind member methods from a complete unrelated class. Check things over!");
#if SOL_IS_ON(SOL_SAFE_USERTYPE_I_)
auto maybeo = stack::check_get<Ta*>(L, 1);
#if SOL_IS_ON(SOL_SAFE_USERTYPE)
stack::record tracking {};
auto maybeo = stack::stack_detail::check_get_arg<Ta*>(L, 1, &no_panic, tracking);
if (!maybeo || maybeo.value() == nullptr) {
if (is_variable) {
return luaL_error(L, "sol: 'self' argument is lua_nil (bad '.' access?)");
@ -573,8 +575,9 @@ namespace sol {
}
else {
using Ta = meta::conditional_t<std::is_void_v<T>, object_type, T>;
#if SOL_IS_ON(SOL_SAFE_USERTYPE_I_)
auto maybeo = stack::check_get<Ta*>(L, 1);
#if SOL_IS_ON(SOL_SAFE_USERTYPE)
stack::record tracking {};
auto maybeo = stack::stack_detail::check_get_arg<Ta*>(L, 1, &no_panic, tracking);
if (!maybeo || maybeo.value() == nullptr) {
if (is_variable) {
return luaL_error(L, "sol: received nil for 'self' argument (bad '.' access?)");
@ -811,8 +814,9 @@ namespace sol {
using args_list = meta::pop_front_type_t<typename traits_type::free_args_list>;
using Ta = T;
using Oa = std::remove_pointer_t<object_type>;
#if SOL_IS_ON(SOL_SAFE_USERTYPE_I_)
auto maybeo = stack::check_get<Ta*>(L, 1);
#if SOL_IS_ON(SOL_SAFE_USERTYPE)
stack::record tracking {};
auto maybeo = stack::stack_detail::check_get_arg<Ta*>(L, 1, &no_panic, tracking);
if (!maybeo || maybeo.value() == nullptr) {
if (is_variable) {
return luaL_error(L, "sol: 'self' argument is lua_nil (bad '.' access?)");

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -32,9 +32,10 @@
#include <sol/version.hpp>
#include <sol/compatibility/lua_version.hpp>
#if SOL_IS_ON(SOL_USE_COMPATIBILITY_LAYER_I_)
#if SOL_IS_ON(SOL_USE_COMPATIBILITY_LAYER)
#if SOL_IS_ON(SOL_USE_CXX_LUA_I_) || SOL_IS_ON(SOL_USE_CXX_LUAJIT_I_)
// clang-format off
#if SOL_IS_ON(SOL_USING_CXX_LUA) || SOL_IS_ON(SOL_USING_CXX_LUAJIT)
#ifndef COMPAT53_LUA_CPP
#define COMPAT53_LUA_CPP 1
#endif // Build Lua Compat layer as C++
@ -42,10 +43,9 @@
#ifndef COMPAT53_INCLUDE_SOURCE
#define COMPAT53_INCLUDE_SOURCE 1
#endif // Build Compat Layer Inline
#include <sol/compatibility/compat-5.3.h>
#include <sol/compatibility/compat-5.4.h>
#endif
// clang-format on
#endif // SOL_COMPATIBILITY_HPP

View file

@ -7,9 +7,15 @@
#if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
extern "C" {
#endif
#if __has_include(<lua/lua.h>)
#include <lua/lua.h>
#include <lua/lauxlib.h>
#include <lua/lualib.h>
#else
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#endif
#if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
}
#endif

View file

@ -4,9 +4,15 @@
#if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
extern "C" {
#endif
#if __has_include(<lua/lua.h>)
#include <lua/lua.h>
#include <lua/lauxlib.h>
#include <lua/lualib.h>
#else
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#endif
#if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP)
}
#endif

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -21,24 +21,40 @@
// 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.
#ifndef SOL_COMPATIBILITY_VERSION_HPP
#define SOL_COMPATIBILITY_VERSION_HPP
#ifndef SOL_COMPATIBILITY_LUA_VERSION_HPP
#define SOL_COMPATIBILITY_LUA_VERSION_HPP
#include <sol/version.hpp>
// clang-format off
#if SOL_IS_ON(SOL_USE_CXX_LUA_I_)
#if SOL_IS_ON(SOL_USING_CXX_LUA)
#if __has_include(<lua/lua.h>)
#include <lua/lua.h>
#include <lua/lauxlib.h>
#include <lua/lualib.h>
#else
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
#elif SOL_IS_ON(SOL_USE_LUA_HPP_I_)
#include <lualib.h>
#endif
#elif SOL_IS_ON(SOL_USE_LUA_HPP)
#if __has_include(<lua/lua.hpp>)
#include <lua/lua.hpp>
#else
#include <lua.hpp>
#endif
#else
extern "C" {
#if __has_include(<lua/lua.h>)
#include <lua/lua.h>
#include <lua/lauxlib.h>
#include <lua/lualib.h>
#else
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#endif
}
#endif // C++ Mangling for Lua vs. Not
@ -50,13 +66,15 @@
#endif
#elif defined(LUAJIT_VERSION)
#define SOL_USE_LUAJIT_I_ SOL_ON
#elif SOL_IS_ON(SOL_USING_CXX_LUAJIT)
#define SOL_USE_LUAJIT_I_ SOL_ON
#else
#define SOL_USE_LUAJIT_I_ SOL_DEFAULT_OFF
#endif // luajit
#if SOL_IS_ON(SOL_USE_CXX_LUAJIT_I_)
#if SOL_IS_ON(SOL_USING_CXX_LUAJIT)
#include <luajit.h>
#elif SOL_IS_ON(SOL_USE_LUAJIT_I_)
#elif SOL_IS_ON(SOL_USE_LUAJIT)
extern "C" {
#include <luajit.h>
}
@ -64,7 +82,7 @@
#if defined(SOL_LUAJIT_VERSION)
#define SOL_LUAJIT_VERSION_I_ SOL_LUAJIT_VERSION
#elif SOL_IS_ON(SOL_USE_LUAJIT_I_)
#elif SOL_IS_ON(SOL_USE_LUAJIT)
#define SOL_LUAJIT_VERSION_I_ LUAJIT_VERSION_NUM
#else
#define SOL_LUAJIT_VERSION_I_ 0
@ -118,15 +136,18 @@
#else
#define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_OFF
#endif
#elif SOL_LUAJIT_VERSION_I_ >= 20100
#else
#if SOL_IS_ON(SOL_USE_LUAJIT)
#if SOL_USE(SOL_LUAJIT_VERSION) >= 20100
// LuaJIT 2.1.0-beta3 and better have exception support locked in for all platforms (mostly)
#define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_DEFAULT_ON
#elif SOL_LUAJIT_VERSION_I_ >= 20000
#elif SOL_USE(SOL_LUAJIT_VERSION) >= 20000
// LuaJIT 2.0.x have exception support only on x64 builds
#if SOL_IS_ON(SOL_PLATFORM_X64_I_)
#if SOL_IS_ON(SOL_PLATFORM_X64)
#define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_DEFAULT_ON
#else
#define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_OFF
#define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_DEFAULT_OFF
#endif
#endif
#else
// otherwise, there is no exception safety for
@ -134,6 +155,7 @@
// always be serialized
#define SOL_PROPAGATE_EXCEPTIONS_I_ SOL_DEFAULT_OFF
#endif
#endif
// Some configurations work with exceptions,
// but cannot catch-all everything...
@ -144,13 +166,14 @@
#define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_OFF
#endif
#else
#if SOL_IS_ON(SOL_USE_LUAJIT_I_)
#if SOL_IS_ON(SOL_USE_LUAJIT) || SOL_IS_ON(SOL_USING_CXX_LUAJIT)
#define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_DEFAULT_OFF
#elif SOL_IS_ON(SOL_USE_CXX_LUAJIT_I_)
#define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_DEFAULT_OFF
#elif SOL_IS_ON(SOL_USE_CXX_LUA_I_)
#elif SOL_IS_ON(SOL_USING_CXX_LUA)
// C++ builds of Lua will throw an exception to implement its `yield` behavior;
// it is irresponsible to "catch all" on this setting.
#define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_DEFAULT_OFF
#else
// Otherwise, by default, everyhting should be caught.
#define SOL_EXCEPTIONS_CATCH_ALL_I_ SOL_DEFAULT_ON
#endif
#endif
@ -162,7 +185,7 @@
#define SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE_I_ SOL_OFF
#endif
#else
#if SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS_I_) && SOL_IS_ON(SOL_USE_LUAJIT_I_)
#if SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS) && SOL_IS_ON(SOL_USE_LUAJIT)
#define SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE_I_ SOL_ON
#else
#define SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE_I_ SOL_DEFAULT_OFF
@ -176,7 +199,7 @@
#define SOL_LUAL_STREAM_USE_CLOSE_FUNCTION_I_ SOL_OFF
#endif
#else
#if SOL_IS_OFF(SOL_USE_LUAJIT_I_) && (SOL_LUA_VERSION > 501)
#if SOL_IS_OFF(SOL_USE_LUAJIT) && (SOL_LUA_VERSION > 501)
#define SOL_LUAL_STREAM_USE_CLOSE_FUNCTION_I_ SOL_ON
#else
#define SOL_LUAL_STREAM_USE_CLOSE_FUNCTION_I_ SOL_DEFAULT_OFF
@ -192,7 +215,11 @@
#else
// Lua 5.2 only (deprecated in 5.3 (503)) (Can be turned on with Compat flags)
// Lua 5.2, or other versions of Lua with the compat flag, or Lua that is not 5.2 with the specific define (5.4.1 either removed it entirely or broke it)
#if (SOL_LUA_VERSION_I_ == 502) || (defined(LUA_COMPAT_BITLIB) && (LUA_COMPAT_BITLIB != 0)) || (SOL_LUA_VERSION_I_ < 504 && (defined(LUA_COMPAT_5_2) && (LUA_COMPAT_5_2 != 0)))
#if (SOL_LUA_VERSION_I_ == 502)
#define SOL_LUA_BIT32_LIB_I_ SOL_ON
#elif defined(LUA_COMPAT_BITLIB)
#define SOL_LUA_BIT32_LIB_I_ SOL_ON
#elif (SOL_LUA_VERSION_I_ < 504 && defined(LUA_COMPAT_5_2))
#define SOL_LUA_BIT32_LIB_I_ SOL_ON
#else
#define SOL_LUA_BIT32_LIB_I_ SOL_DEFAULT_OFF
@ -215,4 +242,4 @@
// clang-format on
#endif // SOL_COMPATIBILITY_VERSION_HPP
#endif // SOL_COMPATIBILITY_LUA_VERSION_HPP

50
extern/sol3/sol/config.hpp vendored Normal file
View file

@ -0,0 +1,50 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 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.
#ifndef SOL_CONFIG_HPP
#define 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 <sol/config.hpp>
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.
*/
#endif // SOL_CONFIG_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -94,7 +94,7 @@ namespace sol {
meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_coroutine(T&& r) noexcept
: base_t(std::forward<T>(r)), m_error_handler(detail::get_default_handler<reference, is_main_threaded<base_t>::value>(r.lua_state())) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
if (!is_function<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this);
constructor_handler handler {};
@ -157,7 +157,7 @@ namespace sol {
}
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_coroutine(lua_State* L, T&& r, handler_t eh) : base_t(L, std::forward<T>(r)), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this);
constructor_handler handler {};
stack::check<basic_coroutine>(lua_state(), -1, handler);
@ -180,7 +180,7 @@ namespace sol {
: basic_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
}
basic_coroutine(lua_State* L, absolute_index index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {};
stack::check<basic_coroutine>(L, index, handler);
#endif // Safety
@ -189,7 +189,7 @@ namespace sol {
: basic_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
}
basic_coroutine(lua_State* L, raw_index index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {};
stack::check<basic_coroutine>(L, index, handler);
#endif // Safety
@ -198,7 +198,7 @@ namespace sol {
: basic_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
}
basic_coroutine(lua_State* L, ref_index index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this);
constructor_handler handler {};
stack::check<basic_coroutine>(lua_state(), -1, handler);

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -47,6 +47,17 @@ namespace sol { namespace detail { namespace debug {
inline void print_section(const std::string& message, lua_State* L) {
std::cout << "-- " << message << " -- [ " << dump_types(L) << " ]" << std::endl;
}
inline void print_lua_information(lua_State* L) {
std::cout << "Lua Version: " << SOL_USE(SOL_LUA_VERSION) << std::endl;
std::cout << "Lua (C++): " << SOL_IS_ON(SOL_USING_CXX_LUA) << std::endl;
std::cout << "Trampoline Propagate Exceptions?: " << SOL_IS_ON(SOL_PROPAGATE_EXCEPTIONS) << std::endl;
std::cout << "Catch-all Exceptions?: " << SOL_IS_ON(SOL_EXCEPTIONS_CATCH_ALL) << std::endl;
std::cout << "LuaJIT: " << SOL_IS_ON(SOL_USE_LUAJIT) << std::endl;
std::cout << "LuaJIT Version: " << SOL_USE(SOL_LUAJIT_VERSION) << std::endl;
std::cout << "LuaJIT (C++): " << SOL_IS_ON(SOL_USING_CXX_LUAJIT) << std::endl;
std::cout << "LuaJIT Exception Trampoline: " << SOL_IS_ON(SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE) << std::endl;
}
}}} // namespace sol::detail::debug
#endif // SOL_DEBUG_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -28,7 +28,7 @@
#include <string>
#include <array>
#include <cctype>
#if SOL_IS_ON(SOL_MINGW_CCTYPE_IS_POISONED_I_)
#if SOL_IS_ON(SOL_MINGW_CCTYPE_IS_POISONED)
extern "C" {
#include <ctype.h>
}
@ -47,7 +47,7 @@ namespace sol { namespace detail {
"`anonymous namespace'" } };
#if SOL_IS_ON(SOL_COMPILER_GCC_I_) || SOL_IS_ON(SOL_COMPILER_CLANG_I_)
#if SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG)
inline std::string ctti_get_type_name_from_sig(std::string name) {
// cardinal sins from MINGW
using namespace std;
@ -85,7 +85,7 @@ namespace sol { namespace detail {
inline std::string ctti_get_type_name() {
return ctti_get_type_name_from_sig(__PRETTY_FUNCTION__);
}
#elif SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#elif SOL_IS_ON(SOL_COMPILER_VCXX)
inline std::string ctti_get_type_name_from_sig(std::string name) {
std::size_t start = name.find("get_type_name");
if (start == std::string::npos)

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -36,7 +36,7 @@
#else
#define SOL_DLL_I_ SOL_OFF
#endif
#elif SOL_IS_ON(SOL_COMPILER_VCXX_I_) && (defined(DLL_) || defined(_DLL))
#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
@ -58,7 +58,7 @@
#else
#define SOL_BUILD_I_ SOL_OFF
#endif
#elif SOL_IS_ON(SOL_HEADER_ONLY_I_)
#elif SOL_IS_ON(SOL_HEADER_ONLY)
#define SOL_BUILD_I_ SOL_DEFAULT_OFF
#else
#define SOL_BUILD_I_ SOL_DEFAULT_ON
@ -77,7 +77,7 @@
#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_I_)
#if SOL_IS_ON(SOL_BUILD_CXX_MODE)
// C++
#define SOL_C_FUNCTION_LINKAGE_I_ extern "C"
#else
@ -89,12 +89,12 @@
#if defined(SOL_API_LINKAGE)
#define SOL_API_LINKAGE_I_ SOL_API_LINKAGE
#else
#if SOL_IS_ON(SOL_DLL_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_) || SOL_IS_ON(SOL_PLATFORM_WINDOWS_I_) || SOL_IS_ON(SOL_PLATFORM_CYGWIN_I_)
#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_I_)
#if SOL_IS_ON(SOL_BUILD)
// Building the library
#if SOL_IS_ON(SOL_COMPILER_GCC_I_)
#if SOL_IS_ON(SOL_COMPILER_GCC)
// Using GCC
#define SOL_API_LINKAGE_I_ __attribute__((dllexport))
#else
@ -102,7 +102,7 @@
#define SOL_API_LINKAGE_I_ __declspec(dllexport)
#endif
#else
#if SOL_IS_ON(SOL_COMPILER_GCC_I_)
#if SOL_IS_ON(SOL_COMPILER_GCC)
#define SOL_API_LINKAGE_I_ __attribute__((dllimport))
#else
#define SOL_API_LINKAGE_I_ __declspec(dllimport)
@ -112,9 +112,9 @@
// extern if building normally on non-MSVC
#define SOL_API_LINKAGE_I_ extern
#endif
#elif SOL_IS_ON(SOL_UNITY_BUILD_I_)
#elif SOL_IS_ON(SOL_UNITY_BUILD)
// Built-in library, like how stb typical works
#if SOL_IS_ON(SOL_HEADER_ONLY_I_)
#if SOL_IS_ON(SOL_HEADER_ONLY)
// Header only, so functions are defined "inline"
#define SOL_API_LINKAGE_I_ inline
#else
@ -123,7 +123,7 @@
#endif
#else
// Normal static library
#if SOL_IS_ON(SOL_BUILD_CXX_MODE_I_)
#if SOL_IS_ON(SOL_BUILD_CXX_MODE)
#define SOL_API_LINKAGE_I_
#else
#define SOL_API_LINKAGE_I_ extern
@ -157,16 +157,16 @@
#if defined(SOL_FUNC_DECL)
#define SOL_FUNC_DECL_I_ SOL_FUNC_DECL
#elif SOL_IS_ON(SOL_HEADER_ONLY_I_)
#elif SOL_IS_ON(SOL_HEADER_ONLY)
#define SOL_FUNC_DECL_I_
#elif SOL_IS_ON(SOL_DLL_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_BUILD_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_I_) || SOL_IS_ON(SOL_COMPILER_CLANG_I_)
#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
@ -175,16 +175,16 @@
#if defined(SOL_FUNC_DEFN)
#define SOL_FUNC_DEFN_I_ SOL_FUNC_DEFN
#elif SOL_IS_ON(SOL_HEADER_ONLY_I_)
#elif SOL_IS_ON(SOL_HEADER_ONLY)
#define SOL_FUNC_DEFN_I_ inline
#elif SOL_IS_ON(SOL_DLL_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_BUILD_I_)
#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_I_) || SOL_IS_ON(SOL_COMPILER_CLANG_I_)
#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_
@ -193,16 +193,16 @@
#if defined(SOL_HIDDEN_FUNC_DECL)
#define SOL_HIDDEN_FUNC_DECL_I_ SOL_HIDDEN_FUNC_DECL
#elif SOL_IS_ON(SOL_HEADER_ONLY_I_)
#elif SOL_IS_ON(SOL_HEADER_ONLY)
#define SOL_HIDDEN_FUNC_DECL_I_
#elif SOL_IS_ON(SOL_DLL_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_BUILD_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_I_) || SOL_IS_ON(SOL_COMPILER_CLANG_I_)
#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
@ -211,16 +211,16 @@
#if defined(SOL_HIDDEN_FUNC_DEFN)
#define SOL_HIDDEN_FUNC_DEFN_I_ SOL_HIDDEN_FUNC_DEFN
#elif SOL_IS_ON(SOL_HEADER_ONLY_I_)
#elif SOL_IS_ON(SOL_HEADER_ONLY)
#define SOL_HIDDEN_FUNC_DEFN_I_ inline
#elif SOL_IS_ON(SOL_DLL_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_BUILD_I_)
#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_I_) || SOL_IS_ON(SOL_COMPILER_CLANG_I_)
#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_

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -61,7 +61,7 @@ namespace sol {
}
inline int dump_throw_on_error(lua_State* L_, int result_code, lua_Writer writer_function, void* userdata_pointer_, bool strip) {
#if SOL_IS_OFF(SOL_EXCEPTIONS_I_)
#if SOL_IS_OFF(SOL_EXCEPTIONS)
return dump_panic_on_error(L_, result_code, writer_function, userdata_pointer_, strip);
#else
(void)L_;

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -26,6 +26,7 @@
#include <type_traits>
#include <utility>
#include <memory>
namespace sol { namespace detail {

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -58,29 +58,29 @@ namespace sol {
basic_environment(env_key_t, const stack_reference& extraction_target)
: base_t(detail::no_safety, extraction_target.lua_state(), (stack::push_environment_of(extraction_target), -1)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {};
stack::check<env_key_t>(this->lua_state(), -1, handler);
#endif // Safety
lua_pop(this->lua_state(), 2);
lua_pop(this->lua_state(), 1);
}
template <bool b>
basic_environment(env_key_t, const basic_reference<b>& extraction_target)
: base_t(detail::no_safety, extraction_target.lua_state(), (stack::push_environment_of(extraction_target), -1)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {};
stack::check<env_key_t>(this->lua_state(), -1, handler);
#endif // Safety
lua_pop(this->lua_state(), 2);
lua_pop(this->lua_state(), 1);
}
basic_environment(lua_State* L, int index = -1) : base_t(detail::no_safety, L, index) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {};
stack::check<basic_environment>(L, index, handler);
#endif // Safety
}
basic_environment(lua_State* L, ref_index index) : base_t(detail::no_safety, L, index) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this);
constructor_handler handler {};
stack::check<basic_environment>(L, -1, handler);
@ -90,7 +90,7 @@ namespace sol {
meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_environment>>, meta::neg<std::is_same<base_type, stack_reference>>,
meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_environment(T&& r) noexcept : base_t(detail::no_safety, std::forward<T>(r)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
if (!is_environment<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this);
constructor_handler handler {};
@ -103,7 +103,7 @@ namespace sol {
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_environment(lua_State* L, T&& r) noexcept : base_t(detail::no_safety, L, std::forward<T>(r)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
if (!is_environment<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this);
constructor_handler handler {};
@ -136,11 +136,13 @@ namespace sol {
const char* success = lua_setupvalue(L, target_index, 1);
if (success == nullptr) {
// left things alone on the stack, pop them off
lua_pop(L, 1);
lua_pop(L, 2);
return false;
}
lua_pop(L, 1);
return true;
}
lua_pop(L, 1);
return false;
}
else {
@ -152,6 +154,7 @@ namespace sol {
}
string_view upvalue_name(maybe_upvalue_name);
if (upvalue_name == "_ENV") {
lua_pop(L, 1);
this->push();
const char* success = lua_setupvalue(L, target_index, upvalue_index);
if (success == nullptr) {

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -31,7 +31,7 @@
#undef SOL_PROLOGUE_I_
#endif
#if SOL_IS_ON(SOL_BUILD_CXX_MODE_I_)
#if SOL_IS_ON(SOL_BUILD_CXX_MODE)
#undef _FWD
#undef _MOVE
#endif

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -57,6 +57,23 @@ namespace sol {
}
return luaL_error(L, er.format_string, er.argument_strings[0], er.argument_strings[1], er.argument_strings[2], er.argument_strings[3]);
}
class error_exception : public std::runtime_error {
public:
error_exception(const std::string& str) : error_exception(detail::direct_error, "lua: error: " + str) {
}
error_exception(std::string&& str) : error_exception(detail::direct_error, "lua: error: " + std::move(str)) {
}
error_exception(detail::direct_error_tag, const std::string& str) : std::runtime_error(str) {
}
error_exception(detail::direct_error_tag, std::string&& str) : std::runtime_error(str) {
}
error_exception(const error_exception& e) = default;
error_exception(error_exception&& e) = default;
error_exception& operator=(const error_exception& e) = default;
error_exception& operator=(error_exception&& e) = default;
};
} // namespace detail
class error : public std::runtime_error {
@ -69,19 +86,15 @@ namespace sol {
}
error(std::string&& str) : error(detail::direct_error, "lua: error: " + std::move(str)) {
}
error(detail::direct_error_tag, const std::string& str) : std::runtime_error(""), what_reason(str) {
error(detail::direct_error_tag, const std::string& str) : std::runtime_error(str) {
}
error(detail::direct_error_tag, std::string&& str) : std::runtime_error(""), what_reason(std::move(str)) {
error(detail::direct_error_tag, std::string&& str) : std::runtime_error(str) {
}
error(const error& e) = default;
error(error&& e) = default;
error& operator=(const error& e) = default;
error& operator=(error&& e) = default;
virtual const char* what() const noexcept override {
return what_reason.c_str();
}
};
} // namespace sol

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -24,6 +24,7 @@
#ifndef SOL_ERROR_HANDLER_HPP
#define SOL_ERROR_HANDLER_HPP
#include <sol/config.hpp>
#include <sol/types.hpp>
#include <sol/demangle.hpp>
@ -62,7 +63,7 @@ namespace sol {
case type::poly:
return "anything";
case type::userdata: {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 2, "not enough space to push get the type name");
#endif // make sure stack doesn't overflow
if (lua_getmetatable(L, index) == 0) {
@ -84,7 +85,7 @@ namespace sol {
inline int push_type_panic_string(lua_State* L, int index, type expected, type actual, string_view message, string_view aux_message) noexcept {
const char* err = message.size() == 0
? (aux_message.size() == 0 ? "stack index %d, expected %s, received %s" : "stack index %d, expected %s, received %s: %s")
? (aux_message.size() == 0 ? "stack index %d, expected %s, received %s" : "stack index %d, expected %s, received %s: %s%s")
: "stack index %d, expected %s, received %s: %s %s";
const char* type_name = expected == type::poly ? "anything" : lua_typename(L, static_cast<int>(expected));
{
@ -96,12 +97,16 @@ namespace sol {
inline int type_panic_string(lua_State* L, int index, type expected, type actual, string_view message = "") noexcept(false) {
push_type_panic_string(L, index, expected, actual, message, "");
return lua_error(L);
size_t str_size = 0;
const char* str = lua_tolstring(L, -1, &str_size);
return luaL_error(L, str);
}
inline int type_panic_c_str(lua_State* L, int index, type expected, type actual, const char* message = nullptr) noexcept(false) {
push_type_panic_string(L, index, expected, actual, message == nullptr ? "" : message, "");
return lua_error(L);
size_t str_size = 0;
const char* str = lua_tolstring(L, -1, &str_size);
return luaL_error(L, str);
}
struct type_panic_t {
@ -118,7 +123,9 @@ namespace sol {
struct constructor_handler {
int operator()(lua_State* L, int index, type expected, type actual, string_view message) const noexcept(false) {
push_type_panic_string(L, index, expected, actual, message, "(type check failed in constructor)");
return lua_error(L);
size_t str_size = 0;
const char* str = lua_tolstring(L, -1, &str_size);
return luaL_error(L, str);
}
};
@ -126,7 +133,9 @@ namespace sol {
struct argument_handler {
int operator()(lua_State* L, int index, type expected, type actual, string_view message) const noexcept(false) {
push_type_panic_string(L, index, expected, actual, message, "(bad argument to variable or function call)");
return lua_error(L);
size_t str_size = 0;
const char* str = lua_tolstring(L, -1, &str_size);
return luaL_error(L, str);
}
};
@ -142,7 +151,9 @@ namespace sol {
aux_message += ")')";
push_type_panic_string(L, index, expected, actual, message, aux_message);
}
return lua_error(L);
size_t str_size = 0;
const char* str = lua_tolstring(L, -1, &str_size);
return luaL_error(L, str);
}
};

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -30,7 +30,7 @@
#include <type_traits>
#include <string_view>
#if SOL_IS_ON(SOL_USE_CXX_LUA_I_) || SOL_IS_ON(SOL_USE_CXX_LUAJIT_I_)
#if SOL_IS_ON(SOL_USING_CXX_LUA) || SOL_IS_ON(SOL_USING_CXX_LUAJIT)
struct lua_State;
#else
extern "C" {
@ -117,7 +117,7 @@ namespace sol {
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_I_)
#if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS)
using function = protected_function;
using main_function = main_protected_function;
using stack_function = stack_protected_function;
@ -133,7 +133,7 @@ namespace sol {
struct unsafe_function_result;
struct protected_function_result;
using safe_function_result = protected_function_result;
#if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS_I_)
#if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS)
using function_result = safe_function_result;
#else
using function_result = unsafe_function_result;
@ -234,7 +234,7 @@ namespace sol {
struct record;
}
#if SOL_IS_OFF(SOL_USE_BOOST_I_)
#if SOL_IS_OFF(SOL_USE_BOOST)
template <class T>
class optional;
@ -253,7 +253,7 @@ namespace sol {
typedef ::sol::types<__VA_ARGS__> type; \
}; \
} \
void a_sol3_detail_function_decl_please_no_collide()
static_assert(true, "")
#define SOL_DERIVED_CLASSES(T, ...) \
namespace sol { \
template <> \
@ -261,6 +261,6 @@ namespace sol {
typedef ::sol::types<__VA_ARGS__> type; \
}; \
} \
void a_sol3_detail_function_decl_please_no_collide()
static_assert(true, "")
#endif // SOL_FORWARD_HPP

44
extern/sol3/sol/forward_as.hpp vendored Normal file
View file

@ -0,0 +1,44 @@
// sol2
// The MIT License (MIT)
// Copyright (c) 2013-2022 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.
#ifndef SOL_FORWARD_AS_HPP
#define SOL_FORWARD_AS_HPP
#include <sol/version.hpp>
#include <utility>
#include <type_traits>
namespace sol {
template <typename T, typename U>
constexpr decltype(auto) forward_as(U&& value) noexcept {
if constexpr (::std::is_lvalue_reference_v<T>) {
return value;
}
else {
return ::std::move(value);
}
}
}
#endif // SOL_FORWARD_AS_HPP

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -32,7 +32,7 @@
namespace sol {
namespace detail {
const bool default_safe_function_calls =
#if SOL_IS_ON(SOL_SAFE_FUNCTION_CALLS_I_)
#if SOL_IS_ON(SOL_SAFE_FUNCTION_CALLS)
true;
#else
false;

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -217,7 +217,7 @@ namespace sol {
int upvalues = 0;
upvalues += stack::push(L, nullptr);
upvalues += stack::push(L, std::forward<Fx>(fx));
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_)
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
if constexpr (std::is_nothrow_invocable_r_v<int, uFx, lua_State*>) {
detail::lua_CFunction_noexcept cf = &lua_c_noexcept_wrapper<true>;
lua_pushcclosure(L, reinterpret_cast<lua_CFunction>(cf), upvalues);
@ -237,7 +237,7 @@ namespace sol {
int upvalues = 0;
upvalues += stack::push(L, nullptr);
upvalues += stack::push(L, std::forward<Fx>(fx));
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_)
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
if constexpr (std::is_nothrow_invocable_r_v<int, uFx, lua_State*>) {
detail::lua_CFunction_noexcept cf = &lua_c_noexcept_wrapper<is_yielding>;
lua_pushcclosure(L, reinterpret_cast<lua_CFunction>(cf), upvalues);
@ -398,7 +398,7 @@ namespace sol {
struct unqualified_pusher<Signature,
std::enable_if_t<meta::all<std::is_function<std::remove_pointer_t<Signature>>, meta::neg<std::is_same<Signature, lua_CFunction>>,
meta::neg<std::is_same<Signature, std::remove_pointer_t<lua_CFunction>>>
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_)
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
,
meta::neg<std::is_same<Signature, detail::lua_CFunction_noexcept>>,
meta::neg<std::is_same<Signature, std::remove_pointer_t<detail::lua_CFunction_noexcept>>>
@ -711,7 +711,7 @@ namespace sol {
namespace stack_detail {
template <typename Function, typename Handler>
bool check_function_pointer(lua_State* L, int index, Handler&& handler, record& tracking) noexcept {
#if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE_I_)
#if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE)
tracking.use(1);
bool success = lua_iscfunction(L, index) == 1;
if (success) {
@ -737,7 +737,7 @@ namespace sol {
template <typename Function>
Function* get_function_pointer(lua_State* L, int index, record& tracking) noexcept {
#if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE_I_)
#if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE)
tracking.use(1);
auto udata = stack::stack_detail::get_as_upvalues_using_function<Function*>(L, index);
Function* fx = udata.first;
@ -747,7 +747,7 @@ namespace sol {
(void)index;
(void)tracking;
static_assert(meta::meta_detail::always_true<Function>::value,
#if SOL_IS_DEFAULT_OFF(SOL_GET_FUNCTION_POINTER_UNSAFE_I_)
#if SOL_IS_DEFAULT_OFF(SOL_GET_FUNCTION_POINTER_UNSAFE)
"You are attempting to retrieve a function pointer type. "
"This is inherently unsafe in sol2. In order to do this, you must turn on the "
"SOL_GET_FUNCTION_POINTER_UNSAFE configuration macro, as detailed in the documentation. "

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -74,7 +74,7 @@ namespace sol { namespace function_detail {
}
static int call(lua_State* L, member_function& self)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
@ -90,7 +90,7 @@ namespace sol { namespace function_detail {
}
int operator()(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -35,7 +35,7 @@ namespace sol { namespace function_detail {
using traits_type = meta::bind_traits<function_type>;
static int real_call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
@ -70,7 +70,7 @@ namespace sol { namespace function_detail {
typedef lua_bind_traits<function_type> traits_type;
static int real_call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
@ -88,7 +88,7 @@ namespace sol { namespace function_detail {
template <bool is_yielding, bool no_trampoline>
static int call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
@ -110,7 +110,7 @@ namespace sol { namespace function_detail {
}
int operator()(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
@ -126,7 +126,7 @@ namespace sol { namespace function_detail {
typedef lua_bind_traits<function_type> traits_type;
static int real_call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
@ -153,7 +153,7 @@ namespace sol { namespace function_detail {
template <bool is_yielding, bool no_trampoline>
static int call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
@ -175,7 +175,7 @@ namespace sol { namespace function_detail {
}
int operator()(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
@ -191,7 +191,7 @@ namespace sol { namespace function_detail {
typedef lua_bind_traits<function_type> traits_type;
static int real_call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
@ -216,7 +216,7 @@ namespace sol { namespace function_detail {
template <bool is_yielding, bool no_trampoline>
static int call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
@ -238,7 +238,7 @@ namespace sol { namespace function_detail {
}
int operator()(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
@ -254,7 +254,7 @@ namespace sol { namespace function_detail {
typedef lua_bind_traits<function_type> traits_type;
static int real_call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
@ -268,7 +268,7 @@ namespace sol { namespace function_detail {
template <bool is_yielding, bool no_trampoline>
static int call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
@ -290,7 +290,7 @@ namespace sol { namespace function_detail {
}
int operator()(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#if SOL_IS_ON(SOL_COMPILER_VCXX)
// MSVC is broken, what a surprise...
#else
noexcept(traits_type::is_noexcept)
@ -320,7 +320,13 @@ namespace sol { namespace function_detail {
}
template <bool is_yielding, bool no_trampoline>
static int call(lua_State* L) noexcept(std::is_nothrow_copy_assignable_v<T>) {
static int call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_CLANG)
// apparent regression in clang 18 - llvm/llvm-project#91362
#else
noexcept(std::is_nothrow_copy_assignable_v<T>)
#endif
{
int nr;
if constexpr (no_trampoline) {
nr = real_call(L);
@ -360,7 +366,13 @@ namespace sol { namespace function_detail {
}
template <bool is_yielding, bool no_trampoline>
static int call(lua_State* L) noexcept(std::is_nothrow_copy_assignable_v<T>) {
static int call(lua_State* L)
#if SOL_IS_ON(SOL_COMPILER_CLANG)
// apparent regression in clang 18 - llvm/llvm-project#91362
#else
noexcept(std::is_nothrow_copy_assignable_v<T>)
#endif
{
int nr;
if constexpr (no_trampoline) {
nr = real_call(L);

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -121,7 +121,7 @@ namespace sol {
typedef meta::unqualified_t<F> Fu;
typedef std::integral_constant<bool,
std::is_same<Fu, lua_CFunction>::value
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_)
#if SOL_IS_ON(SOL_USE_NOEXCEPT_FUNCTION_TYPE)
|| std::is_same<Fu, detail::lua_CFunction_noexcept>::value
#endif
>

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -39,7 +39,7 @@ namespace sol {
load_status err;
public:
load_result() noexcept = default;
load_result() noexcept : load_result(nullptr) {}
load_result(lua_State* Ls, int stackindex = -1, int retnum = 0, int popnum = 0, load_status lerr = load_status::ok) noexcept
: L(Ls), index(stackindex), returncount(retnum), popcount(popnum), err(lerr) {
}
@ -95,7 +95,7 @@ namespace sol {
if (valid()) {
return UT(nullopt);
}
return error(detail::direct_error, stack::get<std::string>(L, index));
return stack::stack_detail::get_error(L, index);
}
else {
if (!valid()) {
@ -106,15 +106,15 @@ namespace sol {
}
else {
if constexpr (std::is_same_v<T, error>) {
#if SOL_IS_ON(SOL_SAFE_PROXIES_I_)
#if SOL_IS_ON(SOL_SAFE_PROXIES)
if (valid()) {
type_panic_c_str(L, index, type_of(L, index), type::none, "expecting an error type (a string, from Lua)");
}
#endif // Check proxy type's safety
return error(detail::direct_error, stack::get<std::string>(L, index));
return stack::stack_detail::get_error(L, index);
}
else {
#if SOL_IS_ON(SOL_SAFE_PROXIES_I_)
#if SOL_IS_ON(SOL_SAFE_PROXIES)
if (!valid()) {
type_panic_c_str(L, index, type_of(L, index), type::none);
}
@ -142,8 +142,10 @@ namespace sol {
};
~load_result() {
if (L != nullptr) {
stack::remove(L, index, popcount);
}
}
};
} // namespace sol

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -50,7 +50,7 @@ namespace sol {
}
template <typename T, meta::enable_any<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_lua_table(lua_State* L, T&& r) : base_t(L, std::forward<T>(r)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this);
constructor_handler handler {};
stack::check<basic_lua_table>(lua_state(), -1, handler);
@ -62,13 +62,13 @@ namespace sol {
}
}
basic_lua_table(lua_State* L, int index = -1) : base_t(detail::no_safety, L, index) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {};
stack::check<basic_lua_table>(L, index, handler);
#endif // Safety
}
basic_lua_table(lua_State* L, ref_index index) : base_t(detail::no_safety, L, index) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this);
constructor_handler handler {};
stack::check<basic_lua_table>(lua_state(), -1, handler);
@ -78,7 +78,7 @@ namespace sol {
meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_lua_table>>, meta::neg<std::is_same<ref_t, stack_reference>>,
meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_lua_table(T&& r) noexcept : basic_lua_table(detail::no_safety, std::forward<T>(r)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
if (!is_table<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this);
constructor_handler handler {};

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -48,7 +48,7 @@ namespace sol {
using is_lua_value_single_constructible = meta::any<std::is_same<T, lua_value>, is_reference_or_lua_value_init_list<T>>;
static lua_State*& thread_local_lua_state() {
#if SOL_IS_ON(SOL_USE_THREAD_LOCAL_I_)
#if SOL_IS_ON(SOL_USE_THREAD_LOCAL)
static thread_local lua_State* L = nullptr;
#else
static lua_State* L = nullptr;

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -86,20 +86,20 @@ namespace sol {
}
template <typename T, meta::enable_any<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_metatable(lua_State* L, T&& r) : base_t(L, std::forward<T>(r)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this);
constructor_handler handler {};
stack::check<basic_metatable>(lua_state(), -1, handler);
#endif // Safety
}
basic_metatable(lua_State* L, int index = -1) : basic_metatable(detail::no_safety, L, index) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {};
stack::check<basic_metatable>(L, index, handler);
#endif // Safety
}
basic_metatable(lua_State* L, ref_index index) : basic_metatable(detail::no_safety, L, index) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this);
constructor_handler handler {};
stack::check<basic_metatable>(lua_state(), -1, handler);
@ -109,7 +109,7 @@ namespace sol {
meta::enable<meta::neg<meta::any_same<meta::unqualified_t<T>, basic_metatable>>, meta::neg<std::is_same<base_type, stack_reference>>,
meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_metatable(T&& r) noexcept : basic_metatable(detail::no_safety, std::forward<T>(r)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
if (!is_table<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this);
constructor_handler handler {};

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -27,7 +27,7 @@
#include <sol/forward.hpp>
#include <sol/in_place.hpp>
#include <sol/traits.hpp>
#if SOL_IS_ON(SOL_USE_BOOST_I_)
#if SOL_IS_ON(SOL_USE_BOOST)
#include <boost/optional.hpp>
#else
#include <sol/optional_implementation.hpp>
@ -38,7 +38,7 @@
namespace sol {
#if SOL_IS_ON(SOL_USE_BOOST_I_)
#if SOL_IS_ON(SOL_USE_BOOST)
template <typename T>
using optional = boost::optional<T>;
using nullopt_t = boost::none_t;
@ -59,14 +59,14 @@ namespace sol {
inline static constexpr std::nullopt_t value = std::nullopt;
};
#if SOL_IS_ON(SOL_USE_BOOST_I_)
#if SOL_IS_ON(SOL_USE_BOOST)
template <typename T>
struct associated_nullopt<boost::optional<T>> {
inline static SOL_BOOST_NONE_CONSTEXPR_I_ boost::none_t value = boost::none;
};
#endif // Boost nullopt
#if SOL_IS_ON(SOL_USE_BOOST_I_)
#if SOL_IS_ON(SOL_USE_BOOST)
template <typename T>
inline SOL_BOOST_NONE_CONSTEXPR_I_ auto associated_nullopt_v = associated_nullopt<T>::value;
#else
@ -76,7 +76,7 @@ namespace sol {
} // namespace detail
} // namespace sol
#if SOL_IS_ON(SOL_USE_BOOST_I_)
#if SOL_IS_ON(SOL_USE_BOOST)
#undef SOL_BOOST_NONE_CONSTEXPR_I_
#endif

View file

@ -1,6 +1,6 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -1375,7 +1375,7 @@ namespace sol {
SOL_TL_OPTIONAL_11_CONSTEXPR T& value() & {
if (has_value())
return this->m_value;
#if SOL_IS_OFF(SOL_EXCEPTIONS_I_)
#if SOL_IS_OFF(SOL_EXCEPTIONS)
std::abort();
#else
throw bad_optional_access();
@ -1386,7 +1386,7 @@ namespace sol {
SOL_TL_OPTIONAL_11_CONSTEXPR const T& value() const& {
if (has_value())
return this->m_value;
#if SOL_IS_OFF(SOL_EXCEPTIONS_I_)
#if SOL_IS_OFF(SOL_EXCEPTIONS)
std::abort();
#else
throw bad_optional_access();
@ -1396,7 +1396,7 @@ namespace sol {
SOL_TL_OPTIONAL_11_CONSTEXPR T&& value() && {
if (has_value())
return std::move(this->m_value);
#if SOL_IS_OFF(SOL_EXCEPTIONS_I_)
#if SOL_IS_OFF(SOL_EXCEPTIONS)
std::abort();
#else
throw bad_optional_access();
@ -1408,7 +1408,7 @@ namespace sol {
SOL_TL_OPTIONAL_11_CONSTEXPR const T&& value() const&& {
if (has_value())
return std::move(this->m_value);
#if SOL_IS_OFF(SOL_EXCEPTIONS_I_)
#if SOL_IS_OFF(SOL_EXCEPTIONS)
std::abort();
#else
throw bad_optional_access();
@ -2186,12 +2186,9 @@ namespace sol {
/// one.
///
/// \group emplace
template <class... Args>
T& emplace(Args&&... args) noexcept {
static_assert(std::is_constructible<T, Args&&...>::value, "T must be constructible with Args");
T& emplace(T& arg) noexcept {
*this = nullopt;
new (static_cast<void*>(this)) optional(std::in_place, std::forward<Args>(args)...);
m_value = &arg;
return **this;
}
@ -2251,7 +2248,7 @@ namespace sol {
SOL_TL_OPTIONAL_11_CONSTEXPR T& value() {
if (has_value())
return *m_value;
#if SOL_IS_OFF(SOL_EXCEPTIONS_I_)
#if SOL_IS_OFF(SOL_EXCEPTIONS)
std::abort();
#else
throw bad_optional_access();
@ -2262,7 +2259,7 @@ namespace sol {
SOL_TL_OPTIONAL_11_CONSTEXPR const T& value() const {
if (has_value())
return *m_value;
#if SOL_IS_OFF(SOL_EXCEPTIONS_I_)
#if SOL_IS_OFF(SOL_EXCEPTIONS)
std::abort();
#else
throw bad_optional_access();

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -96,7 +96,7 @@ namespace sol {
meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_packaged_coroutine(T&& r) noexcept
: base_t(std::forward<T>(r)), m_error_handler(detail::get_default_handler<reference, is_main_threaded<base_t>::value>(r.lua_state())) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
if (!is_function<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this);
constructor_handler handler {};
@ -160,7 +160,7 @@ namespace sol {
}
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_packaged_coroutine(lua_State* L, T&& r, handler_t eh) : base_t(L, std::forward<T>(r)), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this);
constructor_handler handler {};
stack::check<basic_packaged_coroutine>(lua_state(), -1, handler);
@ -183,7 +183,7 @@ namespace sol {
: basic_packaged_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
}
basic_packaged_coroutine(lua_State* L, absolute_index index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {};
stack::check<basic_packaged_coroutine>(L, index, handler);
#endif // Safety
@ -192,7 +192,7 @@ namespace sol {
: basic_packaged_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
}
basic_packaged_coroutine(lua_State* L, raw_index index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {};
stack::check<basic_packaged_coroutine>(L, index, handler);
#endif // Safety
@ -201,7 +201,7 @@ namespace sol {
: basic_packaged_coroutine(L, index, detail::get_default_handler<reference, is_main_threaded<base_t>::value>(L)) {
}
basic_packaged_coroutine(lua_State* L, ref_index index, handler_t eh) : base_t(L, index), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this);
constructor_handler handler {};
stack::check<basic_packaged_coroutine>(lua_state(), -1, handler);

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -28,6 +28,7 @@
#include <utility>
#include <type_traits>
#include <memory>
namespace sol {

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -32,10 +32,10 @@
#define SOL_PROLOGUE_I_ 1
#if SOL_IS_ON(SOL_BUILD_CXX_MODE_I_)
#if SOL_IS_ON(SOL_BUILD_CXX_MODE)
#define _FWD(...) static_cast<decltype( __VA_ARGS__ )&&>( __VA_ARGS__ )
#if SOL_IS_ON(SOL_COMPILER_GCC_I_) || SOL_IS_ON(SOL_COMPILER_CLANG_I_)
#if SOL_IS_ON(SOL_COMPILER_GCC) || SOL_IS_ON(SOL_COMPILER_CLANG)
#define _MOVE(...) static_cast<__typeof( __VA_ARGS__ )&&>( __VA_ARGS__ )
#else
#include <type_traits>

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -75,7 +75,7 @@ namespace sol {
meta::neg<std::is_base_of<proxy_base_tag, meta::unqualified_t<T>>>, meta::neg<std::is_same<base_t, stack_reference>>,
meta::neg<std::is_same<lua_nil_t, meta::unqualified_t<T>>>, is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_protected_function(T&& r) noexcept : base_t(std::forward<T>(r)), m_error_handler(get_default_handler(r.lua_state())) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
if (!is_function<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this);
constructor_handler handler {};
@ -133,7 +133,7 @@ namespace sol {
}
template <typename T, meta::enable<is_lua_reference<meta::unqualified_t<T>>> = meta::enabler>
basic_protected_function(lua_State* L_, T&& r, handler_t eh) : base_t(L_, std::forward<T>(r)), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this);
constructor_handler handler {};
stack::check<basic_protected_function>(lua_state(), -1, handler);
@ -146,7 +146,7 @@ namespace sol {
basic_protected_function(lua_State* L_, int index_ = -1) : basic_protected_function(L_, index_, get_default_handler(L_)) {
}
basic_protected_function(lua_State* L_, int index_, handler_t eh) : base_t(L_, index_), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {};
stack::check<basic_protected_function>(L_, index_, handler);
#endif // Safety
@ -154,7 +154,7 @@ namespace sol {
basic_protected_function(lua_State* L_, absolute_index index_) : basic_protected_function(L_, index_, get_default_handler(L_)) {
}
basic_protected_function(lua_State* L_, absolute_index index_, handler_t eh) : base_t(L_, index_), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {};
stack::check<basic_protected_function>(L_, index_, handler);
#endif // Safety
@ -162,7 +162,7 @@ namespace sol {
basic_protected_function(lua_State* L_, raw_index index_) : basic_protected_function(L_, index_, get_default_handler(L_)) {
}
basic_protected_function(lua_State* L_, raw_index index_, handler_t eh) : base_t(L_, index_), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
constructor_handler handler {};
stack::check<basic_protected_function>(L_, index_, handler);
#endif // Safety
@ -170,7 +170,7 @@ namespace sol {
basic_protected_function(lua_State* L_, ref_index index_) : basic_protected_function(L_, index_, get_default_handler(L_)) {
}
basic_protected_function(lua_State* L_, ref_index index_, handler_t eh) : base_t(L_, index_), m_error_handler(std::move(eh)) {
#if SOL_IS_ON(SOL_SAFE_REFERENCES_I_)
#if SOL_IS_ON(SOL_SAFE_REFERENCES)
auto pp = stack::push_pop(*this);
constructor_handler handler {};
stack::check<basic_protected_function>(lua_state(), -1, handler);
@ -339,14 +339,14 @@ namespace sol {
int firstreturn = 1;
int returncount = 0;
call_status code = call_status::ok;
#if SOL_IS_ON(SOL_EXCEPTIONS_I_) && SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS_I_)
#if SOL_IS_ON(SOL_EXCEPTIONS) && SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS)
try {
#endif // No Exceptions
firstreturn = (std::max)(1, static_cast<int>(stacksize - n - static_cast<int>(h.valid() && !is_stack_handler_v)));
code = luacall(n, LUA_MULTRET, h);
poststacksize = lua_gettop(lua_state()) - static_cast<int>(h.valid() && !is_stack_handler_v);
returncount = poststacksize - (firstreturn - 1);
#if SOL_IS_ON(SOL_EXCEPTIONS_I_) && SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS_I_)
#if SOL_IS_ON(SOL_EXCEPTIONS) && SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS)
}
// Handle C++ errors thrown from C++ functions bound inside of lua
catch (const char* error) {
@ -364,7 +364,7 @@ namespace sol {
firstreturn = lua_gettop(lua_state());
return protected_function_result(lua_state(), firstreturn, 0, 1, call_status::runtime);
}
#if SOL_IS_ON(SOL_EXCEPTIONS_CATCH_ALL_I_)
#if SOL_IS_ON(SOL_EXCEPTIONS_CATCH_ALL)
// LuaJIT cannot have the catchall when the safe propagation is on
// but LuaJIT will swallow all C++ errors
// if we don't at least catch std::exception ones

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -54,7 +54,7 @@ namespace sol {
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
protected_function_result() noexcept = default;
protected_function_result() noexcept : protected_function_result(nullptr) {}
protected_function_result(lua_State* Ls, int idx = -1, int retnum = 0, int popped = 0, call_status pferr = call_status::ok) noexcept
: L( Ls), index(idx), returncount(retnum), popcount(popped), err(pferr) {
}
@ -99,6 +99,13 @@ namespace sol {
return status() == call_status::ok || status() == call_status::yielded;
}
#if SOL_IS_ON(SOL_COMPILER_GCC)
#pragma GCC diagnostic push
#if !SOL_IS_ON(SOL_COMPILER_CLANG)
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
#endif
template <typename T>
decltype(auto) get(int index_offset = 0) const {
using UT = meta::unqualified_t<T>;
@ -109,7 +116,7 @@ namespace sol {
if (valid()) {
return UT();
}
return UT(error(detail::direct_error, stack::get<std::string>(L, target)));
return UT(stack::stack_detail::get_error(L, target));
}
else {
if (!valid()) {
@ -120,16 +127,16 @@ namespace sol {
}
else {
if constexpr (std::is_same_v<T, error>) {
#if SOL_IS_ON(SOL_SAFE_PROXIES_I_)
#if SOL_IS_ON(SOL_SAFE_PROXIES)
if (valid()) {
type t = type_of(L, target);
type_panic_c_str(L, target, t, type::none, "bad get from protected_function_result (is an error)");
}
#endif // Check Argument Safety
return error(detail::direct_error, stack::get<std::string>(L, target));
return stack::stack_detail::get_error(L, target);
}
else {
#if SOL_IS_ON(SOL_SAFE_PROXIES_I_)
#if SOL_IS_ON(SOL_SAFE_PROXIES)
if (!valid()) {
type t = type_of(L, target);
type_panic_c_str(L, target, t, type::none, "bad get from protected_function_result (is not an error)");
@ -140,6 +147,10 @@ namespace sol {
}
}
#if SOL_IS_ON(SOL_COMPILER_GCC)
#pragma GCC diagnostic pop
#endif
type get_type(int index_offset = 0) const noexcept {
return type_of(L, index + static_cast<int>(index_offset));
}
@ -216,7 +227,7 @@ namespace sol {
template <>
struct unqualified_pusher<protected_function_result> {
static int push(lua_State* L, const protected_function_result& pfr) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, static_cast<int>(pfr.pop_count()), detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow
int p = 0;

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -92,7 +92,7 @@ namespace sol { namespace detail {
return;
}
if (!ref.valid()) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow
lua_pushnil(L);

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -289,7 +289,7 @@ namespace sol {
}
stateless_reference(lua_State* L_, global_tag_t) noexcept {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L_, 1, "not enough Lua stack space to push this reference value");
#endif // make sure stack doesn't overflow
lua_pushglobaltable(L_);
@ -352,7 +352,7 @@ namespace sol {
}
stateless_reference(lua_State* L_, int index = -1) noexcept {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L_, 1, "not enough Lua stack space to push this reference value");
#endif // make sure stack doesn't overflow
lua_pushvalue(L_, index);
@ -383,7 +383,7 @@ namespace sol {
}
int push(lua_State* L_) const noexcept {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L_, 1, "not enough Lua stack space to push this reference value");
#endif // make sure stack doesn't overflow
lua_rawgeti(L_, LUA_REGISTRYINDEX, ref);
@ -407,7 +407,7 @@ namespace sol {
void reset(lua_State* L_, int index_) noexcept {
reset(L_);
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L_, 1, "not enough Lua stack space to push this reference value");
#endif // make sure stack doesn't overflow
lua_pushvalue(L_, index_);
@ -616,7 +616,7 @@ namespace sol {
}
basic_reference(lua_State* L_, int index = -1) noexcept : luastate(detail::pick_main_thread<main_only>(L_, L_)) {
// use L_ to stick with that state's execution stack
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L_, 1, "not enough Lua stack space to push this reference value");
#endif // make sure stack doesn't overflow
lua_pushvalue(L_, index);
@ -693,7 +693,7 @@ namespace sol {
}
int push(lua_State* L_) const noexcept {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L_, 1, "not enough Lua stack space to push this reference value");
#endif // make sure stack doesn't overflow
if (lua_state() == nullptr) {
@ -828,6 +828,8 @@ namespace sol {
stateless_reference_equals(lua_State* L_) noexcept : stateless_stack_reference_equals(L_) {
}
using stateless_stack_reference_equals::operator();
bool operator()(const lua_nil_t& lhs, const stateless_reference& rhs) const noexcept {
return rhs.equals(lua_state(), lhs);
}
@ -839,6 +841,14 @@ namespace sol {
bool operator()(const stateless_reference& lhs, const stateless_reference& rhs) const noexcept {
return lhs.equals(lua_state(), rhs);
}
bool operator()(const stateless_stack_reference& lhs, const stateless_reference& rhs) const noexcept {
return rhs.equals(lua_state(), lhs);
}
bool operator()(const stateless_reference& lhs, const stateless_stack_reference& rhs) const noexcept {
return lhs.equals(lua_state(), rhs);
}
};
struct reference_equals : public stack_reference_equals {
@ -878,6 +888,8 @@ namespace sol {
stateless_reference_hash(lua_State* L_) noexcept : stateless_stack_reference_hash(L_) {
}
using stateless_stack_reference_hash::operator();
result_type operator()(const stateless_reference& lhs) const noexcept {
std::hash<const void*> h;
return h(lhs.pointer(lua_state()));

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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

View file

@ -1,6 +1,6 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -24,23 +24,23 @@
#include <sol/version.hpp>
#if SOL_IS_ON(SOL_INSIDE_UNREAL_ENGINE_I_)
#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_I_)
#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_I_)
#elif SOL_IS_ON(SOL_COMPILER_CLANG)
// we'll just let this alone for now
#elif SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#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++
@ -65,13 +65,15 @@
#include <sol/variadic_results.hpp>
#include <sol/lua_value.hpp>
#if SOL_IS_ON(SOL_COMPILER_GCC_I_)
#if SOL_IS_ON(SOL_COMPILER_GCC)
#pragma GCC diagnostic pop
#elif SOL_IS_ON(SOL_COMPILER_VCXX_I_)
#elif SOL_IS_ON(SOL_COMPILER_CLANG)
// we'll just let this alone for now
#elif SOL_IS_ON(SOL_COMPILER_VCXX)
#pragma warning(pop)
#endif // g++
#if SOL_IS_ON(SOL_INSIDE_UNREAL_ENGINE_I_)
#if SOL_IS_ON(SOL_INSIDE_UNREAL_ENGINE)
#undef check
#pragma pop_macro("check")
#endif // Unreal Engine 4 Bullshit

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -34,6 +34,8 @@
#include <sol/stack_pop.hpp>
#include <sol/stack_field.hpp>
#include <sol/stack_probe.hpp>
#include <sol/error.hpp>
#include <sol/assert.hpp>
#include <cstring>
#include <array>
@ -149,7 +151,10 @@ namespace sol {
template <bool checked, typename Arg, typename... Args, std::size_t I, std::size_t... Is, typename Handler, typename Fx, typename... FxArgs>
static decltype(auto) eval(types<Arg, Args...>, std::index_sequence<I, Is...>, lua_State* L_, int start_index_, Handler&& handler_,
record& tracking_, Fx&& fx_, FxArgs&&... fxargs_) {
#if SOL_IS_ON(SOL_PROPAGATE_EXCEPTIONS_I_)
#if 0 && SOL_IS_ON(SOL_PROPAGATE_EXCEPTIONS)
// NOTE: THIS IS TERMPORARILY TURNED OFF BECAUSE IT IMPACTS ACTUAL SEMANTICS W.R.T. THINGS LIKE LUAJIT,
// SO IT MUST REMAIN OFF UNTIL WE CAN ESTABLISH SIMILAR BEHAVIOR IN MODES WHERE `checked == false`!
// We can save performance/time by letting errors unwind produced arguments
// rather than checking everything once, and then potentially re-doing work
if constexpr (checked) {
@ -186,7 +191,7 @@ namespace sol {
"a reference and std::move it manually if this was your intention.");
argument_handler<types<R, Args...>> handler {};
record tracking {};
#if SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS_I_)
#if SOL_IS_OFF(SOL_PROPAGATE_EXCEPTIONS)
if constexpr (checkargs) {
multi_check<Args...>(L_, start_index_, handler);
}
@ -200,11 +205,21 @@ namespace sol {
argument_types_, argument_indices_, L_, start_index_, handler, tracking, std::forward<Fx>(fx_), std::forward<FxArgs>(args_)...);
}
}
template <typename T>
void raw_table_set(lua_State* L, T&& arg, int tableindex = -2) {
int push_count = push(L, std::forward<T>(arg));
SOL_ASSERT(push_count == 1);
std::size_t unique_index = static_cast<std::size_t>(luaL_len(L, tableindex) + 1u);
lua_rawseti(L, tableindex, static_cast<int>(unique_index));
}
} // namespace stack_detail
template <typename T>
int set_ref(lua_State* L, T&& arg, int tableindex = -2) {
push(L, std::forward<T>(arg));
int push_count = push(L, std::forward<T>(arg));
SOL_ASSERT(push_count == 1);
return luaL_ref(L, tableindex);
}
@ -319,11 +334,11 @@ namespace sol {
}
inline void luajit_exception_handler(lua_State* L, int (*handler)(lua_State*, lua_CFunction) = detail::c_trampoline) {
#if SOL_IS_ON(SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE_I_)
#if SOL_IS_ON(SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE)
if (L == nullptr) {
return;
}
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L, 1, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow
lua_pushlightuserdata(L, (void*)handler);
@ -336,7 +351,7 @@ namespace sol {
}
inline void luajit_exception_off(lua_State* L) {
#if SOL_IS_ON(SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE_I_)
#if SOL_IS_ON(SOL_USE_LUAJIT_EXCEPTION_TRAMPOLINE)
if (L == nullptr) {
return;
}
@ -345,6 +360,24 @@ namespace sol {
(void)L;
#endif
}
namespace stack_detail {
inline error get_error(lua_State* L, int target) {
auto maybe_exc = stack::check_get<error&>(L, target);
if (maybe_exc.has_value()) {
return maybe_exc.value();
}
return error(detail::direct_error, stack::get<std::string>(L, target));
}
inline detail::error_exception get_error_exception(lua_State* L, int target) {
auto maybe_exc = stack::check_get<detail::error_exception&>(L, target);
if (maybe_exc.has_value()) {
return maybe_exc.value();
}
return detail::error_exception(detail::direct_error, stack::get<std::string>(L, target));
}
}
} // namespace stack
} // namespace sol

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -84,7 +84,7 @@ namespace sol { namespace stack { namespace stack_detail {
pushed += 1;
}
int metatable_exists = lua_getmetatable(L_, 1);
sol_c_assert(metatable_exists == 1);
SOL_ASSERT(metatable_exists == 1);
const auto& index_key = to_string(sol::meta_function::index);
lua_getfield(L_, lua_gettop(L_), index_key.c_str());
lua_remove(L_, -2);

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -30,6 +30,13 @@
namespace sol { namespace stack {
#if SOL_IS_ON(SOL_COMPILER_GCC)
#pragma GCC diagnostic push
#if !SOL_IS_ON(SOL_COMPILER_CLANG)
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
#endif
namespace stack_detail {
template <typename OptionalType, typename T, typename Handler>
OptionalType get_optional(lua_State* L, int index, Handler&& handler, record& tracking) {
@ -70,9 +77,8 @@ namespace sol { namespace stack {
actual* mem = static_cast<actual*>(memory);
return static_cast<actual>(*mem);
}
actual r {};
if constexpr (!derive<element>::value) {
return {};
return OptionalType();
}
else {
memory = detail::align_usertype_unique_tag<true, false>(memory);
@ -80,6 +86,7 @@ namespace sol { namespace stack {
memory = detail::align_usertype_unique<actual, true, false>(memory);
string_view ti = usertype_traits<element>::qualified_name();
int cast_operation;
actual r {};
if constexpr (is_actual_type_rebindable_for_v<Tu>) {
using rebound_actual_type = unique_usertype_rebind_actual_t<Tu, void>;
string_view rebind_ti = usertype_traits<rebound_actual_type>::qualified_name();
@ -103,19 +110,23 @@ namespace sol { namespace stack {
default:
break;
}
return {};
return OptionalType();
}
}
else {
if (!check<T>(L, index, std::forward<Handler>(handler))) {
tracking.use(static_cast<int>(!lua_isnone(L, index)));
return {};
return OptionalType();
}
return OptionalType(stack_detail::unchecked_get<T>(L, index, tracking));
}
}
} // namespace stack_detail
#if SOL_IS_ON(SOL_COMPILER_GCC)
#pragma GCC diagnostic pop
#endif
template <typename T, typename>
struct qualified_check_getter {
typedef decltype(stack_detail::unchecked_get<T>(nullptr, -1, std::declval<record&>())) R;

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -32,7 +32,7 @@
#include <cstdlib>
#include <cmath>
#include <optional>
#if SOL_IS_ON(SOL_STD_VARIANT_I_)
#if SOL_IS_ON(SOL_STD_VARIANT)
#include <variant>
#endif // variant shenanigans (thanks, Mac OSX)
@ -76,7 +76,7 @@ namespace sol { namespace stack {
int isnum = 0;
const lua_Number value = lua_tonumberx(L, index, &isnum);
if (isnum != 0) {
#if SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS_I_)
#if SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS)
const auto integer_value = llround(value);
if (static_cast<lua_Number>(integer_value) == value) {
tracking.use(1);
@ -139,7 +139,7 @@ namespace sol { namespace stack {
}
};
#if SOL_IS_ON(SOL_STD_VARIANT_I_)
#if SOL_IS_ON(SOL_STD_VARIANT)
template <typename... Tn, typename C>
struct unqualified_check_getter<std::variant<Tn...>, C> {
typedef std::variant<Tn...> V;

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -28,7 +28,7 @@
namespace sol { namespace stack {
template <typename X, type expected, typename>
template <typename X, typename>
struct qualified_checker {
template <typename Handler>
static bool check(lua_State* L, int index, Handler&& handler, record& tracking) {

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -32,7 +32,7 @@
#include <utility>
#include <cmath>
#include <optional>
#if SOL_IS_ON(SOL_STD_VARIANT_I_)
#if SOL_IS_ON(SOL_STD_VARIANT)
#include <variant>
#endif // variant shenanigans
@ -116,7 +116,7 @@ namespace sol { namespace stack {
}
else if constexpr (meta::any_same_v<T,
char
#if SOL_IS_ON(SOL_CHAR8_T_I_)
#if SOL_IS_ON(SOL_CHAR8_T)
,
char8_t
#endif
@ -129,7 +129,7 @@ namespace sol { namespace stack {
tracking.use(1);
#if SOL_LUA_VERSION_I_ >= 503
// Lua 5.3 and greater checks for numeric precision
#if SOL_IS_ON(SOL_STRINGS_ARE_NUMBERS_I_)
#if SOL_IS_ON(SOL_STRINGS_ARE_NUMBERS)
// imprecise, sloppy conversions
int isnum = 0;
lua_tointegerx(L_, index, &isnum);
@ -138,7 +138,7 @@ namespace sol { namespace stack {
// expected type, actual type
handler(L_, index, type::number, type_of(L_, index), detail::not_a_number_or_number_string_integral);
}
#elif SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS_I_)
#elif SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS)
// this check is precise, do not convert
if (lua_isinteger(L_, index) == 1) {
return true;
@ -160,7 +160,7 @@ namespace sol { namespace stack {
return success;
#else
// Lua 5.2 and below checks
#if SOL_IS_OFF(SOL_STRINGS_ARE_NUMBERS_I_)
#if SOL_IS_OFF(SOL_STRINGS_ARE_NUMBERS)
// must pre-check, because it will convert
type t = type_of(L_, index);
if (t != type::number) {
@ -170,7 +170,7 @@ namespace sol { namespace stack {
}
#endif // Do not allow strings to be numbers
#if SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS_I_)
#if SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS)
int isnum = 0;
const lua_Number v = lua_tonumberx(L_, index, &isnum);
const bool success = isnum != 0 && static_cast<lua_Number>(llround(v)) == v;
@ -179,9 +179,9 @@ namespace sol { namespace stack {
#endif // Safe numerics and number precision checking
if (!success) {
// Use defines to provide a better error message!
#if SOL_IS_ON(SOL_STRINGS_ARE_NUMBERS_I_)
#if SOL_IS_ON(SOL_STRINGS_ARE_NUMBERS)
handler(L_, index, type::number, type_of(L_, index), detail::not_a_number_or_number_string);
#elif SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS_I_)
#elif SOL_IS_ON(SOL_NUMBER_PRECISION_CHECKS)
handler(L_, index, type::number, t, detail::not_a_number_or_number_string);
#else
handler(L_, index, type::number, t, detail::not_a_number);
@ -192,7 +192,7 @@ namespace sol { namespace stack {
}
else if constexpr (std::is_floating_point_v<T> || std::is_same_v<T, lua_Number>) {
tracking.use(1);
#if SOL_IS_ON(SOL_STRINGS_ARE_NUMBERS_I_)
#if SOL_IS_ON(SOL_STRINGS_ARE_NUMBERS)
bool success = lua_isnumber(L_, index) == 1;
if (!success) {
// expected type, actual type
@ -218,6 +218,7 @@ namespace sol { namespace stack {
}
else if constexpr (is_unique_usertype_v<T>) {
using element = unique_usertype_element_t<T>;
using element_no_cv = meta::unqualified_t<element>;
using actual = unique_usertype_actual_t<T>;
const type indextype = type_of(L_, index);
tracking.use(1);
@ -229,7 +230,7 @@ namespace sol { namespace stack {
return true;
}
int metatableindex = lua_gettop(L_);
if (stack_detail::check_metatable<d::u<element>>(L_, metatableindex)) {
if (stack_detail::check_metatable<d::u<element_no_cv>>(L_, metatableindex)) {
void* memory = lua_touserdata(L_, index);
memory = detail::align_usertype_unique_destructor(memory);
detail::unique_destructor& pdx = *static_cast<detail::unique_destructor*>(memory);
@ -371,7 +372,7 @@ namespace sol { namespace stack {
}
return stack::unqualified_check<ValueType>(L_, index, &no_panic, tracking);
}
#if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE_I_)
#if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE)
else if constexpr (std::is_function_v<T> || (std::is_pointer_v<T> && std::is_function_v<std::remove_pointer_t<T>>)) {
return stack_detail::check_function_pointer<std::remove_pointer_t<T>>(L_, index, std::forward<Handler>(handler), tracking);
}
@ -388,9 +389,7 @@ namespace sol { namespace stack {
return success;
}
else if constexpr (meta::is_specialization_of_v<T, user>) {
unqualified_checker<lightuserdata_value, type::userdata> c;
(void)c;
return c.check(L_, index, std::forward<Handler>(handler), tracking);
return stack::unqualified_check<detail::as_value_tag<lightuserdata_value>>(L_, index, std::forward<Handler>(handler), tracking);
}
else {
if constexpr (std::is_pointer_v<T>) {
@ -508,13 +507,13 @@ namespace sol { namespace stack {
return true;
}
else {
#if SOL_IS_ON(SOL_USE_INTEROP_I_)
#if SOL_IS_ON(SOL_USE_INTEROP)
if (stack_detail::interop_check<U>(L_, index, indextype, handler, tracking)) {
return true;
}
#endif // interop extensibility
tracking.use(1);
#if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE_I_)
#if SOL_IS_ON(SOL_GET_FUNCTION_POINTER_UNSAFE)
if (lua_iscfunction(L_, index) != 0) {
// a potential match...
return true;
@ -539,7 +538,7 @@ namespace sol { namespace stack {
bool success = false;
bool has_derived = derive<T>::value || weak_derive<T>::value;
if (has_derived) {
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK_I_)
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(L_, 1, detail::not_enough_stack_space_string);
#endif // make sure stack doesn't overflow
auto pn = stack::pop_n(L_, 1);
@ -579,6 +578,104 @@ namespace sol { namespace stack {
}
};
template <typename T, std::size_t N, type expect>
struct unqualified_checker<exhaustive_until<T, N>, expect> {
template <typename K, typename V, typename Handler>
static bool check_two(types<K, V>, lua_State* arg_L, int relindex, type, Handler&& handler, record& tracking) {
tracking.use(1);
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(arg_L, 3, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow
int index = lua_absindex(arg_L, relindex);
lua_pushnil(arg_L);
while (lua_next(arg_L, index) != 0) {
const bool is_key_okay = stack::check<K>(arg_L, -2, std::forward<Handler>(handler), tracking);
if (!is_key_okay) {
lua_pop(arg_L, 2);
return false;
}
const bool is_value_okay = stack::check<V>(arg_L, -1, std::forward<Handler>(handler), tracking);
if (!is_value_okay) {
lua_pop(arg_L, 2);
return false;
}
lua_pop(arg_L, 1);
}
return true;
}
template <typename V, typename Handler>
static bool check_one(types<V>, lua_State* arg_L, int relindex, type, Handler&& handler, record& tracking) {
tracking.use(1);
size_t index = lua_absindex(arg_L, relindex);
// Zzzz slower but necessary thanks to the lower version API and missing functions qq
std::size_t idx = 0;
int vi = 0;
for (lua_Integer i = 0;; (void)(i += lua_size<V>::value), lua_pop(arg_L, static_cast<int>(vi))) {
vi = 0;
if (idx >= N) {
return true;
}
#if SOL_IS_ON(SOL_SAFE_STACK_CHECK)
luaL_checkstack(arg_L, 2, detail::not_enough_stack_space_generic);
#endif // make sure stack doesn't overflow
bool isnil = false;
for (; vi < static_cast<int>(lua_size<V>::value); ++vi) {
lua_pushinteger(arg_L, i);
lua_gettable(arg_L, static_cast<int>(index));
type vt = type_of(arg_L, -1);
isnil = vt == type::lua_nil;
if (isnil) {
if (i == 0) {
vi += 1;
goto loop_continue;
}
lua_pop(arg_L, static_cast<int>(vi + 1));
return true;
}
}
if (!stack::check<V>(arg_L, -lua_size<V>::value, std::forward<Handler>(handler), tracking)) {
lua_pop(arg_L, lua_size<V>::value);
return false;
}
++idx;
loop_continue:;
}
}
template <typename Handler>
static bool check(lua_State* arg_L, int index, Handler&& handler, record& tracking) {
using Tu = meta::unqualified_t<T>;
if constexpr (is_container_v<Tu>) {
if constexpr (meta::is_associative<Tu>::value) {
typedef typename Tu::value_type P;
typedef typename P::first_type K;
typedef typename P::second_type V;
return check_two(types<K, V>(), arg_L, index, expect, std::forward<Handler>(handler), tracking);
}
else {
typedef typename Tu::value_type V;
return check_one(types<V>(), arg_L, index, expect, std::forward<Handler>(handler), tracking);
}
}
else {
unqualified_checker<Tu, expect> c {};
return c.check(arg_L, index, std::forward<Handler>(handler), tracking);
}
}
};
template <typename T, type expect>
struct unqualified_checker<non_exhaustive<T>, expect> {
template <typename Handler>
static bool check(lua_State* arg_L, int index, Handler&& handler, record& tracking) {
return stack::check<T>(arg_L, index, std::forward<Handler>(handler), tracking);
}
};
template <typename... Args>
struct unqualified_checker<std::tuple<Args...>, type::poly> {
template <typename Handler>
@ -595,7 +692,7 @@ namespace sol { namespace stack {
}
};
#if SOL_IS_ON(SOL_STD_VARIANT_I_)
#if SOL_IS_ON(SOL_STD_VARIANT)
template <typename... Tn>
struct unqualified_checker<std::variant<Tn...>, type::poly> {

View file

@ -2,7 +2,7 @@
// The MIT License (MIT)
// Copyright (c) 2013-2021 Rapptz, ThePhD and contributors
// Copyright (c) 2013-2022 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
@ -127,7 +127,7 @@ namespace sol {
inline void* align_usertype_pointer(void* ptr) {
using use_align = std::integral_constant<bool,
#if SOL_IS_OFF(SOL_ALIGN_MEMORY_I_)
#if SOL_IS_OFF(SOL_ALIGN_MEMORY)
false
#else
(std::alignment_of<void*>::value > 1)
@ -143,7 +143,7 @@ namespace sol {
template <bool pre_aligned = false, bool pre_shifted = false>
void* align_usertype_unique_destructor(void* ptr) {
using use_align = std::integral_constant<bool,
#if SOL_IS_OFF(SOL_ALIGN_MEMORY_I_)
#if SOL_IS_OFF(SOL_ALIGN_MEMORY)
false
#else
(std::alignment_of<unique_destructor>::value > 1)
@ -165,7 +165,7 @@ namespace sol {
template <bool pre_aligned = false, bool pre_shifted = false>
void* align_usertype_unique_tag(void* ptr) {
using use_align = std::integral_constant<bool,
#if SOL_IS_OFF(SOL_ALIGN_MEMORY_I_)
#if SOL_IS_OFF(SOL_ALIGN_MEMORY)
false
#else
(std::alignment_of<unique_tag>::value > 1)
@ -187,7 +187,7 @@ namespace sol {
template <typename T, bool pre_aligned = false, bool pre_shifted = false>
void* align_usertype_unique(void* ptr) {
typedef std::integral_constant<bool,
#if SOL_IS_OFF(SOL_ALIGN_MEMORY_I_)
#if SOL_IS_OFF(SOL_ALIGN_MEMORY)
false
#else
(std::alignment_of_v<T> > 1)
@ -210,7 +210,7 @@ namespace sol {
template <typename T>
void* align_user(void* ptr) {
typedef std::integral_constant<bool,
#if SOL_IS_OFF(SOL_ALIGN_MEMORY_I_)
#if SOL_IS_OFF(SOL_ALIGN_MEMORY)
false
#else
(std::alignment_of_v<T> > 1)
@ -227,7 +227,7 @@ namespace sol {
template <typename T>
T** usertype_allocate_pointer(lua_State* L) {
typedef std::integral_constant<bool,
#if SOL_IS_OFF(SOL_ALIGN_MEMORY_I_)
#if SOL_IS_OFF(SOL_ALIGN_MEMORY)
false
#else
(std::alignment_of<T*>::value > 1)
@ -311,7 +311,7 @@ namespace sol {
template <typename T>
T* usertype_allocate(lua_State* L) {
typedef std::integral_constant<bool,
#if SOL_IS_OFF(SOL_ALIGN_MEMORY_I_)
#if SOL_IS_OFF(SOL_ALIGN_MEMORY)
false
#else
(std::alignment_of<T*>::value > 1 || std::alignment_of_v<T> > 1)
@ -352,7 +352,7 @@ namespace sol {
template <typename T, typename Real>
Real* usertype_unique_allocate(lua_State* L, T**& pref, unique_destructor*& dx, unique_tag*& id) {
typedef std::integral_constant<bool,
#if SOL_IS_OFF(SOL_ALIGN_MEMORY_I_)
#if SOL_IS_OFF(SOL_ALIGN_MEMORY)
false
#else
(std::alignment_of<T*>::value > 1 || std::alignment_of<unique_tag>::value > 1 || std::alignment_of<unique_destructor>::value > 1
@ -370,10 +370,10 @@ namespace sol {
constexpr std::size_t initial_size = aligned_space_for<T*, unique_destructor, unique_tag, Real>();
void* pointer_adjusted;
void* dx_adjusted;
void* id_adjusted;
void* data_adjusted;
void* pointer_adjusted = nullptr;
void* dx_adjusted = nullptr;
void* id_adjusted = nullptr;
void* data_adjusted = nullptr;
bool result = attempt_alloc_unique(L,
std::alignment_of_v<T*>,
sizeof(T*),
@ -406,7 +406,7 @@ namespace sol {
template <typename T>
T* user_allocate(lua_State* L) {
typedef std::integral_constant<bool,
#if SOL_IS_OFF(SOL_ALIGN_MEMORY_I_)
#if SOL_IS_OFF(SOL_ALIGN_MEMORY)
false
#else
(std::alignment_of_v<T> > 1)
@ -571,7 +571,7 @@ namespace sol {
template <typename T, type t, typename = void>
struct unqualified_checker;
template <typename T, type t, typename = void>
template <typename T, typename = void>
struct qualified_checker;
template <typename T, typename = void>
@ -709,7 +709,6 @@ namespace sol {
}
else {
unqualified_getter<Tu> g {};
(void)g;
return g.get(L, index, tracking);
}
}
@ -721,7 +720,6 @@ namespace sol {
}
else {
qualified_getter<T> g {};
(void)g;
return g.get(L, index, tracking);
}
}
@ -877,7 +875,6 @@ namespace sol {
}
else {
unqualified_pusher<Tu> p {};
(void)p;
return p.push(L, std::forward<T>(t), std::forward<Args>(args)...);
}
}
@ -897,7 +894,6 @@ namespace sol {
}
else {
unqualified_pusher<Tu> p {};
(void)p;
return p.push(L, std::forward<Arg>(arg), std::forward<Args>(args)...);
}
}
@ -928,7 +924,7 @@ namespace sol {
using use_reference_tag =
meta::all<
meta::neg<is_value_semantic_for_function<T>>
#if SOL_IS_OFF(SOL_FUNCTION_CALL_VALUE_SEMANTICS_I_)
#if SOL_IS_OFF(SOL_FUNCTION_CALL_VALUE_SEMANTICS)
, std::is_lvalue_reference<T>,
meta::neg<std::is_const<std::remove_reference_t<T>>>,
meta::neg<is_lua_primitive<meta::unqualified_t<T>>>,
@ -983,9 +979,7 @@ namespace sol {
return sol_lua_check(types<Tu>(), L, index, std::forward<Handler>(handler), tracking);
}
else {
unqualified_checker<Tu, lua_type_of_v<Tu>> c;
// VC++ has a bad warning here: shut it up
(void)c;
unqualified_checker<Tu, lua_type_of_v<Tu>> c{};
return c.check(L, index, std::forward<Handler>(handler), tracking);
}
}
@ -1008,10 +1002,7 @@ namespace sol {
return sol_lua_check(types<T>(), L, index, std::forward<Handler>(handler), tracking);
}
else {
using Tu = meta::unqualified_t<T>;
qualified_checker<T, lua_type_of_v<Tu>> c;
// VC++ has a bad warning here: shut it up
(void)c;
qualified_checker<T> c{};
return c.check(L, index, std::forward<Handler>(handler), tracking);
}
}
@ -1065,7 +1056,6 @@ namespace sol {
}
else {
unqualified_check_getter<Tu> cg {};
(void)cg;
return cg.get(L, index, std::forward<Handler>(handler), tracking);
}
}
@ -1089,7 +1079,6 @@ namespace sol {
}
else {
qualified_check_getter<T> cg {};
(void)cg;
return cg.get(L, index, std::forward<Handler>(handler), tracking);
}
}
@ -1145,7 +1134,7 @@ namespace sol {
template <typename T>
auto unqualified_get(lua_State* L, int index, record& tracking) -> decltype(stack_detail::unchecked_unqualified_get<T>(L, index, tracking)) {
#if SOL_IS_ON(SOL_SAFE_GETTER_I_)
#if SOL_IS_ON(SOL_SAFE_GETTER)
static constexpr bool is_op = meta::is_optional_v<T>;
if constexpr (is_op) {
return stack_detail::unchecked_unqualified_get<T>(L, index, tracking);
@ -1170,7 +1159,7 @@ namespace sol {
template <typename T>
auto get(lua_State* L, int index, record& tracking) -> decltype(stack_detail::unchecked_get<T>(L, index, tracking)) {
#if SOL_IS_ON(SOL_SAFE_GETTER_I_)
#if SOL_IS_ON(SOL_SAFE_GETTER)
static constexpr bool is_op = meta::is_optional_v<T>;
if constexpr (is_op) {
return stack_detail::unchecked_get<T>(L, index, tracking);

Some files were not shown because too many files have changed in this diff Show more