From 534994b42a1ae3d5181039e741807fa27db91fd9 Mon Sep 17 00:00:00 2001 From: Evil Eye Date: Sat, 27 Aug 2022 13:47:15 +0200 Subject: [PATCH] Use more string_view in the character controller --- apps/openmw/mwmechanics/character.cpp | 43 +++++++++++---------- apps/openmw/mwmechanics/character.hpp | 2 +- apps/openmw/mwmechanics/security.cpp | 4 +- apps/openmw/mwmechanics/security.hpp | 4 +- apps/openmw/mwmechanics/spellcasting.cpp | 2 +- apps/openmw/mwmechanics/spellcasting.hpp | 2 +- apps/openmw/mwrender/animation.cpp | 48 +++++++++++------------- apps/openmw/mwrender/animation.hpp | 4 +- 8 files changed, 54 insertions(+), 55 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index e9a631bcc1..9ee7d5097e 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -56,7 +56,7 @@ namespace { -std::string getBestAttack (const ESM::Weapon* weapon) +std::string_view getBestAttack(const ESM::Weapon* weapon) { int slash = weapon->mData.mSlash[0] + weapon->mData.mSlash[1]; int chop = weapon->mData.mChop[0] + weapon->mData.mChop[1]; @@ -104,7 +104,7 @@ MWMechanics::CharacterState hitStateToDeathState (MWMechanics::CharacterState st } // Converts a movement state to its equivalent base animation group as long as it is a movement state. -std::string movementStateToAnimGroup(MWMechanics::CharacterState state) +std::string_view movementStateToAnimGroup(MWMechanics::CharacterState state) { using namespace MWMechanics; switch (state) @@ -143,7 +143,7 @@ std::string movementStateToAnimGroup(MWMechanics::CharacterState state) } // Converts a death state to its equivalent animation group as long as it is a death state. -std::string deathStateToAnimGroup(MWMechanics::CharacterState state) +std::string_view deathStateToAnimGroup(MWMechanics::CharacterState state) { using namespace MWMechanics; switch (state) @@ -350,8 +350,8 @@ void CharacterController::refreshHitRecoilAnims() return; MWRender::Animation::AnimPriority priority(Priority_Knockdown); - std::string startKey = "start"; - std::string stopKey = "stop"; + std::string_view startKey = "start"; + std::string_view stopKey = "stop"; if (knockout) { mHitState = isSwimming ? CharState_SwimKnockOut : CharState_KnockOut; @@ -563,15 +563,16 @@ void CharacterController::refreshMovementAnims(CharacterState movement, bool for if (movement == mMovementState && !force) return; - std::string movementAnimName = movementStateToAnimGroup(movement); + std::string_view movementAnimGroup = movementStateToAnimGroup(movement); - if (movementAnimName.empty()) + if (movementAnimGroup.empty()) { if (!mCurrentMovement.empty()) resetCurrentIdleState(); resetCurrentMovementState(); return; } + std::string movementAnimName{movementAnimGroup}; mMovementState = movement; std::string::size_type swimpos = movementAnimName.find("swim"); @@ -644,7 +645,7 @@ void CharacterController::refreshMovementAnims(CharacterState movement, bool for if (mPtr.getClass().getType() == ESM::Creature::sRecordId && !(mPtr.get()->mBase->mFlags & ESM::Creature::Flies)) { CharacterState walkState = runStateToWalkState(mMovementState); - std::string anim = movementStateToAnimGroup(walkState); + std::string_view anim = movementStateToAnimGroup(walkState); mMovementAnimSpeed = mAnimation->getVelocity(anim); if (mMovementAnimSpeed <= 1.0f) @@ -1009,19 +1010,21 @@ void CharacterController::handleTextKey(std::string_view groupname, SceneUtil::T { std::multimap::const_iterator hitKey = key; - std::string hitKeyName = std::string(groupname) + ": hit"; - std::string stopKeyName = std::string(groupname) + ": stop"; // Not all animations have a hit key defined. If there is none, the hit happens with the start key. bool hasHitKey = false; while (hitKey != map.end()) { - if (hitKey->second == hitKeyName) + if (hitKey->second.starts_with(groupname)) { - hasHitKey = true; - break; + std::string_view suffix = std::string_view(hitKey->second).substr(groupname.size()); + if (suffix == ": hit") + { + hasHitKey = true; + break; + } + if (suffix == ": stop") + break; } - if (hitKey->second == stopKeyName) - break; ++hitKey; } if (!hasHitKey) @@ -1386,7 +1389,7 @@ bool CharacterController::updateWeaponState() const std::string& selectedSpell = MWBase::Environment::get().getWindowManager()->getSelectedSpell(); stats.getSpells().setSelectedSpell(selectedSpell); } - std::string spellid = stats.getSpells().getSelectedSpell(); + std::string_view spellid = stats.getSpells().getSelectedSpell(); bool isMagicItem = false; // Play hand VFX and allow castSpell use (assuming an animation is going to be played) if spellcasting is successful. @@ -1565,7 +1568,7 @@ bool CharacterController::updateWeaponState() if (!target.isEmpty()) { - std::string resultMessage, resultSound; + std::string_view resultMessage, resultSound; if (mWeapon.getType() == ESM::Lockpick::sRecordId) Security(mPtr).pickLock(target, mWeapon, resultMessage, resultSound); else if (mWeapon.getType() == ESM::Probe::sRecordId) @@ -2082,7 +2085,7 @@ void CharacterController::update(float duration) if (playLandingSound) { - std::string sound; + std::string_view sound; osg::Vec3f pos(mPtr.getRefData().getPosition().asVec3()); if (world->isUnderwater(mPtr.getCell(), pos) || world->isWalkingOnWater(mPtr)) sound = "DefaultLandWater"; @@ -2425,7 +2428,7 @@ bool CharacterController::isPersistentAnimPlaying() const return false; } -bool CharacterController::isAnimPlaying(const std::string &groupName) const +bool CharacterController::isAnimPlaying(std::string_view groupName) const { if(mAnimation == nullptr) return false; @@ -2714,7 +2717,7 @@ void CharacterController::setHeadTrackTarget(const MWWorld::ConstPtr &target) void CharacterController::playSwishSound() const { - std::string soundId = "Weapon Swish"; + std::string_view soundId = "Weapon Swish"; float volume = 0.98f + mAttackStrength * 0.02f; float pitch = 0.75f + mAttackStrength * 0.4f; diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 441815e834..3f7dcd1114 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -262,7 +262,7 @@ public: bool playGroup(std::string_view groupname, int mode, int count, bool persist=false); void skipAnim(); - bool isAnimPlaying(const std::string &groupName) const; + bool isAnimPlaying(std::string_view groupName) const; enum KillResult { diff --git a/apps/openmw/mwmechanics/security.cpp b/apps/openmw/mwmechanics/security.cpp index bfb48dd754..d41bf817a3 100644 --- a/apps/openmw/mwmechanics/security.cpp +++ b/apps/openmw/mwmechanics/security.cpp @@ -26,7 +26,7 @@ namespace MWMechanics } void Security::pickLock(const MWWorld::Ptr &lock, const MWWorld::Ptr &lockpick, - std::string& resultMessage, std::string& resultSound) + std::string_view& resultMessage, std::string_view& resultSound) { if (lock.getCellRef().getLockLevel() <= 0 || lock.getCellRef().getLockLevel() == ESM::UnbreakableLock || @@ -72,7 +72,7 @@ namespace MWMechanics } void Security::probeTrap(const MWWorld::Ptr &trap, const MWWorld::Ptr &probe, - std::string& resultMessage, std::string& resultSound) + std::string_view& resultMessage, std::string_view& resultSound) { if (trap.getCellRef().getTrap().empty()) return; diff --git a/apps/openmw/mwmechanics/security.hpp b/apps/openmw/mwmechanics/security.hpp index f3efb04ed8..b555dcc299 100644 --- a/apps/openmw/mwmechanics/security.hpp +++ b/apps/openmw/mwmechanics/security.hpp @@ -13,9 +13,9 @@ namespace MWMechanics Security (const MWWorld::Ptr& actor); void pickLock (const MWWorld::Ptr& lock, const MWWorld::Ptr& lockpick, - std::string& resultMessage, std::string& resultSound); + std::string_view& resultMessage, std::string_view& resultSound); void probeTrap (const MWWorld::Ptr& trap, const MWWorld::Ptr& probe, - std::string& resultMessage, std::string& resultSound); + std::string_view& resultMessage, std::string_view& resultSound); private: float mAgility, mLuck, mSecuritySkill, mFatigueTerm; diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index 58bd76ca49..97530ce293 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -435,7 +435,7 @@ namespace MWMechanics return true; } - void CastSpell::playSpellCastingEffects(const std::string &spellid, bool enchantment) + void CastSpell::playSpellCastingEffects(std::string_view spellid, bool enchantment) { const MWWorld::ESMStore& store = MWBase::Environment::get().getWorld()->getStore(); if (enchantment) diff --git a/apps/openmw/mwmechanics/spellcasting.hpp b/apps/openmw/mwmechanics/spellcasting.hpp index 8dfd2b3f0c..835c3b6633 100644 --- a/apps/openmw/mwmechanics/spellcasting.hpp +++ b/apps/openmw/mwmechanics/spellcasting.hpp @@ -54,7 +54,7 @@ namespace MWMechanics /// @note Auto detects if spell, ingredient or potion bool cast (const std::string& id); - void playSpellCastingEffects(const std::string &spellid, bool enchantment); + void playSpellCastingEffects(std::string_view spellid, bool enchantment); /// Launch a bolt with the given effects. void launchMagicBolt (); diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index 7aab3ec1d9..9b9ad0f770 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -166,13 +166,20 @@ namespace } }; + bool equalsParts(std::string_view value, std::string_view s1, std::string_view s2, std::string_view s3 = {}) + { + if (value.starts_with(s1)) + { + value = value.substr(s1.size()); + if(value.starts_with(s2)) + return value.substr(s2.size()) == s3; + } + return false; + } + float calcAnimVelocity(const SceneUtil::TextKeyMap& keys, SceneUtil::KeyframeController *nonaccumctrl, - const osg::Vec3f& accum, const std::string &groupname) + const osg::Vec3f& accum, std::string_view groupname) { - const std::string start = groupname+": start"; - const std::string loopstart = groupname+": loop start"; - const std::string loopstop = groupname+": loop stop"; - const std::string stop = groupname+": stop"; float starttime = std::numeric_limits::max(); float stoptime = 0.0f; @@ -185,7 +192,7 @@ namespace auto keyiter = keys.rbegin(); while(keyiter != keys.rend()) { - if(keyiter->second == start || keyiter->second == loopstart) + if(equalsParts(keyiter->second, groupname, ": start") || equalsParts(keyiter->second, groupname, ": loop start")) { starttime = keyiter->first; break; @@ -195,9 +202,9 @@ namespace keyiter = keys.rbegin(); while(keyiter != keys.rend()) { - if (keyiter->second == stop) + if (equalsParts(keyiter->second, groupname, ": stop")) stoptime = keyiter->first; - else if (keyiter->second == loopstop) + else if (equalsParts(keyiter->second, groupname, ": loop stop")) { stoptime = keyiter->first; break; @@ -868,24 +875,13 @@ namespace MWRender break; } - auto equals = [] (std::string_view value, std::string_view s1, std::string_view s2, std::string_view s3 = {}) - { - if (value.starts_with(s1)) - { - value = value.substr(s1.size()); - if(value.starts_with(s2)) - return value.substr(s2.size()) == s3; - } - return false; - }; - auto startkey = groupend; - while(startkey != keys.rend() && !equals(startkey->second, groupname, ": ", start)) + while(startkey != keys.rend() && !equalsParts(startkey->second, groupname, ": ", start)) ++startkey; if(startkey == keys.rend() && start == "loop start") { startkey = groupend; - while(startkey != keys.rend() && !equals(startkey->second, groupname, ": start")) + while(startkey != keys.rend() && !equalsParts(startkey->second, groupname, ": start")) ++startkey; } if(startkey == keys.rend()) @@ -897,7 +893,7 @@ namespace MWRender // We have to ignore extra garbage at the end. // The Scrib's idle3 animation has "Idle3: Stop." instead of "Idle3: Stop". // Why, just why? :( - && !equals(std::string_view{stopkey->second}.substr(0, checkLength), groupname, ": ", stop)) + && !equalsParts(std::string_view{stopkey->second}.substr(0, checkLength), groupname, ": ", stop)) ++stopkey; if(stopkey == keys.rend()) return false; @@ -929,9 +925,9 @@ namespace MWRender if (key->first > state.getTime()) continue; - if (equals(key->second, groupname, ": loop start")) + if (equalsParts(key->second, groupname, ": loop start")) state.mLoopStartTime = key->first; - else if (equals(key->second, groupname, ": loop stop")) + else if (equalsParts(key->second, groupname, ": loop stop")) state.mLoopStopTime = key->first; } @@ -1081,7 +1077,7 @@ namespace MWRender resetActiveGroups(); } - float Animation::getVelocity(const std::string &groupname) const + float Animation::getVelocity(std::string_view groupname) const { if (!mAccumRoot) return 0.0f; @@ -1137,7 +1133,7 @@ namespace MWRender } } - mAnimVelocities.insert(std::make_pair(groupname, velocity)); + mAnimVelocities.emplace(groupname, velocity); return velocity; } diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index a958429f39..55f15e3a69 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -285,7 +285,7 @@ protected: float mAlpha; - mutable std::map mAnimVelocities; + mutable std::map> mAnimVelocities; osg::ref_ptr mLightListCallback; @@ -451,7 +451,7 @@ public: void disable(std::string_view groupname); /** Retrieves the velocity (in units per second) that the animation will move. */ - float getVelocity(const std::string &groupname) const; + float getVelocity(std::string_view groupname) const; virtual osg::Vec3f runAnimation(float duration);