浏览代码

Build and Lua bindings fixes. Return 1.0 for unknown master volumes. Change Audio::IsMasterGain() to Audio::HasMasterGain(). Change Audio::GetSoundSourceMasterGain() to use StringHash to avoid per-frame string compares. Guard against out of bounds array access when deserializing cursor's shape attributes.

Lasse Öörni 11 年之前
父节点
当前提交
0e5f6e2070

+ 9 - 7
Source/Engine/Audio/Audio.cpp

@@ -44,6 +44,7 @@ const char* AUDIO_CATEGORY = "Audio";
 static const int MIN_BUFFERLENGTH = 20;
 static const int MIN_MIXRATE = 11025;
 static const int MAX_MIXRATE = 48000;
+static const StringHash SOUND_MASTER_HASH("MASTER");
 
 static void SDLAudioCallback(void *userdata, Uint8 *stream, int len);
 
@@ -54,7 +55,7 @@ Audio::Audio(Context* context) :
     playing_(false)
 {
     // Set the master to the default value
-    masterGain_[SOUND_MASTER] = 1.0f;
+    masterGain_[SOUND_MASTER_HASH] = 1.0f;
     
     // Register Audio library object factories
     RegisterAudioLibrary(context_);
@@ -170,9 +171,10 @@ void Audio::StopSound(Sound* soundClip)
 
 float Audio::GetMasterGain(const String& type) const
 {
-    HashMap<String, Variant>::ConstIterator findIt = masterGain_.Find(type);
+    // By definition previously unknown types return full volume
+    HashMap<StringHash, Variant>::ConstIterator findIt = masterGain_.Find(type);
     if (findIt == masterGain_.End())
-        return 0.0f;
+        return 1.0f;
 
     return findIt->second_.GetFloat();
 }
@@ -198,14 +200,14 @@ void Audio::RemoveSoundSource(SoundSource* channel)
     }
 }
 
-float Audio::GetSoundSourceMasterGain(const String& type) const
+float Audio::GetSoundSourceMasterGain(StringHash typeHash) const
 {
-    HashMap<String, Variant>::ConstIterator masterIt = masterGain_.Find(SOUND_MASTER);
+    HashMap<StringHash, Variant>::ConstIterator masterIt = masterGain_.Find(SOUND_MASTER_HASH);
 
-    if (type == String::EMPTY)
+    if (!typeHash)
         return masterIt->second_.GetFloat();
 
-    HashMap<String, Variant>::ConstIterator typeIt = masterGain_.Find(type);
+    HashMap<StringHash, Variant>::ConstIterator typeIt = masterGain_.Find(typeHash);
 
     if (typeIt == masterGain_.End() || typeIt == masterIt)
         return masterIt->second_.GetFloat();

+ 3 - 3
Source/Engine/Audio/Audio.h

@@ -81,7 +81,7 @@ public:
     const PODVector<SoundSource*>& GetSoundSources() const { return soundSources_; }
 
     /// Return whether the specified master gain has been defined.
-    bool IsMasterGain(const String& type) const { return masterGain_.Contains(type); }
+    bool HasMasterGain(const String& type) const { return masterGain_.Contains(type); }
 
     /// Add a sound source to keep track of. Called by SoundSource.
     void AddSoundSource(SoundSource* soundSource);
@@ -90,7 +90,7 @@ public:
     /// Return audio thread mutex.
     Mutex& GetMutex() { return audioMutex_; }
     /// Return sound type specific gain multiplied by master gain.
-    float GetSoundSourceMasterGain(const String& type) const;
+    float GetSoundSourceMasterGain(StringHash typeHash) const;
 
     /// Mix sound sources into the buffer.
     void MixOutput(void *dest, unsigned samples);
@@ -119,7 +119,7 @@ private:
     /// Playing flag.
     bool playing_;
     /// Master gain by sound source type.
-    HashMap<String, Variant> masterGain_;
+    HashMap<StringHash, Variant> masterGain_;
     /// Sound sources.
     PODVector<SoundSource*> soundSources_;
     /// Sound listener.

+ 6 - 1
Source/Engine/Audio/AudioDefs.h

@@ -22,10 +22,15 @@
 
 #pragma once
 
+#include "Str.h"
+
 namespace Urho3D
 {
 
 /// SoundSource type defaults
 static const String SOUND_MASTER = "Master";
-
+static const String SOUND_EFFECT = "Effect";
+static const String SOUND_AMBIENT = "Ambient";
+static const String SOUND_VOICE = "Voice";
+static const String SOUND_MUSIC = "Music";
 }

+ 4 - 3
Source/Engine/Audio/SoundSource.cpp

@@ -100,7 +100,7 @@ extern const char* AUDIO_CATEGORY;
 
 SoundSource::SoundSource(Context* context) :
     Component(context),
-    soundType_(String::EMPTY),
+    soundType_(SOUND_EFFECT),
     frequency_(0.0f),
     gain_(1.0f),
     attenuation_(1.0f),
@@ -130,7 +130,7 @@ void SoundSource::RegisterObject(Context* context)
 
     ACCESSOR_ATTRIBUTE("Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
     MIXED_ACCESSOR_ATTRIBUTE("Sound", GetSoundAttr, SetSoundAttr, ResourceRef, ResourceRef(Sound::GetTypeStatic()), AM_DEFAULT);
-    MIXED_ACCESSOR_ATTRIBUTE("Type", GetSoundType, SetSoundType, String, "Effect", AM_DEFAULT);
+    MIXED_ACCESSOR_ATTRIBUTE("Type", GetSoundType, SetSoundType, String, SOUND_EFFECT, AM_DEFAULT);
     ATTRIBUTE("Frequency", float, frequency_, 0.0f, AM_DEFAULT);
     ATTRIBUTE("Gain", float, gain_, 1.0f, AM_DEFAULT);
     ATTRIBUTE("Attenuation", float, attenuation_, 1.0f, AM_DEFAULT);
@@ -232,10 +232,11 @@ void SoundSource::SetSoundType(const String& type)
     if (type == SOUND_MASTER)
         return;
 
-    if (!audio_->IsMasterGain(type))
+    if (!audio_->HasMasterGain(type))
         audio_->SetMasterGain(type, 1.0f);
 
     soundType_ = type;
+    soundTypeHash_ = StringHash(type);
     MarkNetworkUpdate();
 }
 

+ 2 - 0
Source/Engine/Audio/SoundSource.h

@@ -117,6 +117,8 @@ protected:
     WeakPtr<Audio> audio_;
     /// SoundSource type, determines the master gain group.
     String soundType_;
+    /// SoundSource type hash.
+    StringHash soundTypeHash_;
     /// Frequency.
     float frequency_;
     /// Gain.

+ 8 - 5
Source/Engine/LuaScript/pkgs/Audio/Audio.pkg

@@ -1,13 +1,17 @@
 $#include "Audio.h"
 
 static const String SOUND_MASTER;
+static const String SOUND_EFFECT;
+static const String SOUND_AMBIENT;
+static const String SOUND_VOICE;
+static const String SOUND_MUSIC;
 
 class Audio : public Object
 {
     bool SetMode(int bufferLengthMSec, int mixRate, bool stereo, bool interpolation = true);
     bool Play();
     void Stop();
-    void SetMasterGain(const String& type, float gain);
+    void SetMasterGain(const String type, float gain);
     void SetListener(SoundListener* listener);
     void StopSound(Sound* sound);
 
@@ -17,15 +21,14 @@ class Audio : public Object
     bool IsStereo() const;
     bool IsPlaying() const;
     bool IsInitialized() const;
-    bool IsMasterGain(const String& type) const;
-    float GetMasterGain(const String& type) const;
+    bool HasMasterGain(const String type) const;
+    float GetMasterGain(const String type) const;
     SoundListener* GetListener() const;
     const PODVector<SoundSource*>& GetSoundSources() const;
 
     void AddSoundSource(SoundSource* soundSource);
     void RemoveSoundSource(SoundSource* soundSource);
-    float GetSoundSourceMasterGain(const String& type) const;
-	
+
     void MixOutput(void *dest, unsigned samples);
 
     tolua_readonly tolua_property__get_set unsigned sampleSize;

+ 1 - 3
Source/Engine/LuaScript/pkgs/Audio/SoundSource.pkg

@@ -1,7 +1,5 @@
 $#include "SoundSource.h"
 
-enum SoundType{};
-
 class SoundSource : public Component
 {
     void Play(Sound* sound);
@@ -9,7 +7,7 @@ class SoundSource : public Component
     void Play(Sound* sound, float frequency, float gain);
     void Play(Sound* sound, float frequency, float gain, float panning);
     void Stop();
-    void SetSoundType(const String& type);
+    void SetSoundType(const String type);
     void SetFrequency(float frequency);
     void SetGain(float gain);
     void SetAttenuation(float attenuation);

+ 2 - 2
Source/Engine/LuaScript/pkgs/UI/Cursor.pkg

@@ -22,11 +22,11 @@ class Cursor : public BorderImage
     Cursor();
     virtual ~Cursor();
 
-    void DefineShape(const String& shape, Image* image, const IntRect& imageRect, const IntVector2& hotSpot);
+    void DefineShape(const String shape, Image* image, const IntRect& imageRect, const IntVector2& hotSpot);
     void DefineShape(CursorShape shape, Image* image, const IntRect& imageRect, const IntVector2& hotSpot);
     
     void SetShape(CursorShape shape);
-    void SetShape(const String& shape);
+    void SetShape(const String shape);
     void SetUseSystemShapes(bool enable);
     String GetShape() const;
     bool GetUseSystemShapes() const;

+ 5 - 1
Source/Engine/Script/AudioAPI.cpp

@@ -46,6 +46,10 @@ void RegisterSound(asIScriptEngine* engine)
 void RegisterSoundSources(asIScriptEngine* engine)
 {
     engine->RegisterGlobalProperty("const String SOUND_MASTER", (void*) &SOUND_MASTER);
+    engine->RegisterGlobalProperty("const String SOUND_EFFECT", (void*) &SOUND_EFFECT);
+    engine->RegisterGlobalProperty("const String SOUND_AMBIENT", (void*) &SOUND_AMBIENT);
+    engine->RegisterGlobalProperty("const String SOUND_VOICE", (void*) &SOUND_VOICE);
+    engine->RegisterGlobalProperty("const String SOUND_MUSIC", (void*) &SOUND_MUSIC);
     
     RegisterSoundSource<SoundSource>(engine, "SoundSource");
     RegisterSoundSource<SoundSource3D>(engine, "SoundSource3D");
@@ -83,7 +87,7 @@ void RegisterAudio(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Audio", "void Stop()", asMETHOD(Audio, Stop), asCALL_THISCALL);
     engine->RegisterObjectMethod("Audio", "void set_masterGain(const String&in, float)", asMETHOD(Audio, SetMasterGain), asCALL_THISCALL);
     engine->RegisterObjectMethod("Audio", "float get_masterGain(const String&in) const", asMETHOD(Audio, GetMasterGain), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Audio", "bool IsMasterGain(const String&in) const", asMETHOD(Audio, IsMasterGain), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Audio", "bool HasMasterGain(const String&in) const", asMETHOD(Audio, HasMasterGain), asCALL_THISCALL);
     engine->RegisterObjectMethod("Audio", "void set_listener(SoundListener@+)", asMETHOD(Audio, SetListener), asCALL_THISCALL);
     engine->RegisterObjectMethod("Audio", "SoundListener@+ get_listener() const", asMETHOD(Audio, GetListener), asCALL_THISCALL);
     engine->RegisterObjectMethod("Audio", "uint get_sampleSize() const", asMETHOD(Audio, GetSampleSize), asCALL_THISCALL);

+ 1 - 1
Source/Engine/Script/UIAPI.cpp

@@ -172,7 +172,7 @@ static void RegisterCursor(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Cursor", "void SetShape(const String&in)", asMETHODPR(Cursor, SetShape, (const String&), void), asCALL_THISCALL);
     engine->RegisterObjectMethod("Cursor", "void SetShape(CursorShape)", asMETHODPR(Cursor, SetShape, (CursorShape), void), asCALL_THISCALL);
     engine->RegisterObjectMethod("Cursor", "void set_shape(const String&in)", asMETHODPR(Cursor, SetShape, (const String&), void), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Cursor", "String get_shape() const", asMETHOD(Cursor, GetShape), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Cursor", "const String& get_shape() const", asMETHOD(Cursor, GetShape), asCALL_THISCALL);
     engine->RegisterObjectMethod("Cursor", "void set_useSystemShapes(bool)", asMETHOD(Cursor, SetUseSystemShapes), asCALL_THISCALL);
     engine->RegisterObjectMethod("Cursor", "bool get_useSystemShapes() const", asMETHOD(Cursor, GetUseSystemShapes), asCALL_THISCALL);
 }

+ 8 - 6
Source/Engine/UI/Cursor.cpp

@@ -221,13 +221,15 @@ void Cursor::SetShapesAttr(const VariantVector& value)
     for (iter; iter != value.End(); iter++)
     {
         VariantVector shapeVector = iter->GetVariantVector();
+        if (shapeVector.Size() >= 4)
+        {
+            String shape = shapeVector[0].GetString();
+            ResourceRef ref = shapeVector[1].GetResourceRef();
+            IntRect imageRect = shapeVector[2].GetIntRect();
+            IntVector2 hotSpot = shapeVector[3].GetIntVector2();
 
-        String shape = shapeVector[0].GetString();
-        ResourceRef ref = shapeVector[1].GetResourceRef();
-        IntRect imageRect = shapeVector[2].GetIntRect();
-        IntVector2 hotSpot = shapeVector[3].GetIntVector2();
-
-        DefineShape(shape, GetSubsystem<ResourceCache>()->GetResource<Image>(ref.name_), imageRect, hotSpot);
+            DefineShape(shape, GetSubsystem<ResourceCache>()->GetResource<Image>(ref.name_), imageRect, hotSpot);
+        }
     }
 }
 

+ 2 - 2
Source/Engine/UI/Cursor.h

@@ -115,7 +115,7 @@ public:
     /// Set whether to use system default shapes. Is only possible when the OS mouse cursor has been set visible from the Input subsystem.
     void SetUseSystemShapes(bool enable);
     /// Get current shape.
-    StringHash GetShape() const { return shape_; }
+    const String& GetShape() const { return shape_; }
     /// Return whether is using system default shapes.
     bool GetUseSystemShapes() const { return useSystemShapes_; }
 
@@ -130,7 +130,7 @@ protected:
     /// Handle operating system mouse cursor visibility change event.
     void HandleMouseVisibleChanged(StringHash eventType, VariantMap& eventData);
 
-    /// Current shape index.
+    /// Current shape definition.
     String shape_;
     /// Shape definitions.
     HashMap<String, CursorShapeInfo> shapeInfos_;