diff --git a/.gitignore b/.gitignore index 4dd52f7..db4d37d 100755 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ /bin/ /lib/ # CLion -.idea/ \ No newline at end of file +.idea/ +.orig \ No newline at end of file diff --git a/assets/Models/submarine2.mtl b/assets/Models/Submarine2.mtl similarity index 100% rename from assets/Models/submarine2.mtl rename to assets/Models/Submarine2.mtl diff --git a/assets/Models/submarine2.obj b/assets/Models/Submarine2.obj similarity index 99% rename from assets/Models/submarine2.obj rename to assets/Models/Submarine2.obj index 5796eba..144e0ad 100644 --- a/assets/Models/submarine2.obj +++ b/assets/Models/Submarine2.obj @@ -1,6 +1,6 @@ # Blender v2.75 (sub 0) OBJ File: 'submarine.blend' # www.blender.org -mtllib submarine2.mtl +mtllib Submarine2.mtl o Cube v -0.378953 -0.002680 -0.065172 v 0.212611 0.044805 -0.044067 diff --git a/include/Core/Engine.h b/include/Core/Engine.h index e3d74f5..a2a02e4 100644 --- a/include/Core/Engine.h +++ b/include/Core/Engine.h @@ -552,15 +552,15 @@ private: //Todo: Move this { dd::Events::PlaySound e; - e.path = "Sounds/BGM/under-the-sea-instrumental.wav"; - e.isAmbient = true; + e.FilePath = "Sounds/BGM/under-the-sea-instrumental.wav"; + e.IsAmbient = true; m_EventBroker->Publish(e); } { dd::Events::PlaySound e; - e.path = "Sounds/BGM/water-flowing.wav"; - e.volume = 0.3f; - e.isAmbient = true; + e.FilePath = "Sounds/BGM/water-flowing.wav"; + e.Gain = 0.3f; + e.IsAmbient = true; m_EventBroker->Publish(e); } }; diff --git a/include/Game/LevelSystem.h b/include/Game/LevelSystem.h index 545d2fb..9e73a6b 100755 --- a/include/Game/LevelSystem.h +++ b/include/Game/LevelSystem.h @@ -33,7 +33,6 @@ #include "Game/PadSystem.h" #include #include -#include namespace dd { diff --git a/include/Game/MainMenuOptions.h b/include/Game/MainMenuOptions.h index 476fa4a..b0771de 100644 --- a/include/Game/MainMenuOptions.h +++ b/include/Game/MainMenuOptions.h @@ -61,15 +61,15 @@ private: { if (event.Slider == m_SFXSlider) { Events::MasterVolume e; - e.isAmbient = false; - e.gain = event.Percentage; + e.IsAmbient = false; + e.Gain = event.Percentage; EventBroker->Publish(e); } if (event.Slider == m_BGMSlider) { Events::MasterVolume e; - e.isAmbient = true; - e.gain = event.Percentage; + e.IsAmbient = true; + e.Gain = event.Percentage; EventBroker->Publish(e); } diff --git a/include/Sound/CCollisionSound.h b/include/Sound/CCollisionSound.h index 4a631a3..3bf312a 100644 --- a/include/Sound/CCollisionSound.h +++ b/include/Sound/CCollisionSound.h @@ -1,7 +1,3 @@ -// -// Created by Adam on 2015-09-17. -// - #ifndef COMPONENTS_CCOLLISIONSOUND_H__ #define COMPONENTS_CCOLLISIONSOUND_H__ @@ -9,17 +5,15 @@ namespace dd { - namespace Components { struct CollisionSound : public Component { - std::string filePath; + std::string FilePath; }; } - } #endif diff --git a/include/Sound/EMasterVolume.h b/include/Sound/EMasterVolume.h index 3f95e6d..6c7999b 100644 --- a/include/Sound/EMasterVolume.h +++ b/include/Sound/EMasterVolume.h @@ -1,7 +1,3 @@ -// -// Created by Adam on 2015-09-24. -// - #ifndef EVENTS_EMASTERVOLUME_H__ #define EVENTS_EMASTERVOLUME_H__ @@ -9,19 +5,17 @@ namespace dd { - namespace Events { struct MasterVolume : public Event { - float gain = 1; + float Gain = 1; //To determine what channel group to apply the change to. - bool isAmbient = false; + bool IsAmbient = false; }; } - } #endif diff --git a/include/Sound/EPlaySound.h b/include/Sound/EPlaySound.h index a66300d..ed7ab76 100644 --- a/include/Sound/EPlaySound.h +++ b/include/Sound/EPlaySound.h @@ -1,24 +1,22 @@ -#ifndef Events_PlaySFX_h__ -#define Events_PlaySFX_h__ +#ifndef EVENTS_PLAYSFX_H__ +#define EVENTS_PLAYSFX_H__ #include "Core/EventBroker.h" namespace dd { - namespace Events { struct PlaySound : Event { - std::string path; - float volume = 1.f; - float pitch = 1.f; - bool isAmbient = false; + std::string FilePath; + float Gain = 1.f; + float Pitch = 1.f; + bool IsAmbient = false; }; } - } #endif \ No newline at end of file diff --git a/include/Sound/EStopSound.h b/include/Sound/EStopSound.h index 81ff474..8f7bbd8 100644 --- a/include/Sound/EStopSound.h +++ b/include/Sound/EStopSound.h @@ -8,16 +8,12 @@ namespace dd namespace Events { - struct StopSound : public Event { - std::string path; + std::string FilePath; }; - } - - } #endif diff --git a/include/Sound/Sound.h b/include/Sound/Sound.h index 7084e64..1e892b7 100644 --- a/include/Sound/Sound.h +++ b/include/Sound/Sound.h @@ -12,27 +12,31 @@ namespace dd class Sound : public Resource { friend class ResourceManager; + public: ALuint Buffer() { return m_Buffer; }; std::string Path() { return m_Path; }; + float Gain() { return m_Gain; }; + void SetGain(const float Gain) { m_Gain = Gain; }; + private: Sound(std::string path); + float m_Gain = 1; + ALuint m_Buffer; + std::string m_Path; + //File-info char m_Type[4]; unsigned long m_Size, m_ChunkSize; short m_FormatType, m_Channels; unsigned long m_SampleRate, m_AvgBytesPerSec; short m_BytesPerSample, m_BitsPerSample; - unsigned long m_DataSize; + unsigned int m_DataSize; std::map m_BufferCache; ALuint LoadFile(std::string path); - - ALuint m_Buffer; - std::string m_Path; }; - } #endif diff --git a/include/Sound/SoundSystem.h b/include/Sound/SoundSystem.h index 32dd05e..89713f5 100644 --- a/include/Sound/SoundSystem.h +++ b/include/Sound/SoundSystem.h @@ -1,61 +1,60 @@ -#ifndef DAYDREAM_SOUND_H -#define DAYDREAM_SOUND_H - +#ifndef SYSTEMS_SOUNDSYSTEM_H__ +#define SYSTEMS_SOUNDSYSTEM_H__ #include "AL/al.h" #include "AL/alc.h" + #include "Core/System.h" #include "Core/World.h" #include "Core/EventBroker.h" +#include "Core/ResourceManager.h" #include "Sound.h" #include "Sound/EPlaySound.h" #include "Sound/EStopSound.h" #include "Sound/EMasterVolume.h" +#include "Sound/CCollisionSound.h" #include "Physics/EContact.h" #include "Game/CBall.h" #include "Game/CBrick.h" #include "Game/CPad.h" -#include "Sound/CCollisionSound.h" -#include "Core/ResourceManager.h" - namespace dd { namespace Systems { + class SoundSystem : public System { public: SoundSystem(World *world, std::shared_ptr eventBroker) : System(world, eventBroker) { } + ~SoundSystem(); + void Initialize() override; void Update(double dt) override; - - - private: + float m_BGMMasterVolume = 1.f; + float m_SFXMasterVolume = 1.f; + std::map m_BGMSourcesToBuffers; + std::map m_SFXSourcesToBuffers; + ALCdevice* m_Device = nullptr; + //Events dd::EventRelay m_EPlaySFX; - dd::EventRelay m_EContact; - dd::EventRelay m_EStopSound; - dd::EventRelay m_EMasterVolume; bool OnPlaySound(const dd::Events::PlaySound &event); + //On contact: play the sound given in the CCOllisionSound. + dd::EventRelay m_EContact; bool OnContact(const dd::Events::Contact &event); + dd::EventRelay m_EStopSound; bool OnStopSound(const dd::Events::StopSound &event); + dd::EventRelay m_EMasterVolume; bool OnMasterVolume(const dd::Events::MasterVolume &event); ALuint CreateSource(); - - std::map m_BGMSourcesToBuffers; - std::map m_SFXSourcesToBuffers; - - ALCdevice* m_Device; - - float m_BGMMasterVolume, m_SFXMasterVolume; - }; + } } -#endif //DAYDREAM_SOUND_H +#endif diff --git a/src/game/Core/OBJ.cpp b/src/game/Core/OBJ.cpp index fe6a818..0dd75a5 100644 --- a/src/game/Core/OBJ.cpp +++ b/src/game/Core/OBJ.cpp @@ -263,7 +263,7 @@ void dd::OBJ::ParseMaterial() ParseColorMap(currentLine, ss, prefix, arg, colorMap); } - // HACK: Should we really have to specify the full path here? + // HACK: Should we really have to specify the full FilePath here? colorMap.FileName = (m_MaterialPath.branch_path() / colorMap.FileName).string(); currentMaterial->DiffuseTexture = colorMap; continue; @@ -280,7 +280,7 @@ void dd::OBJ::ParseMaterial() ParseColorMap(currentLine, ss, prefix, arg, colorMap); } - // HACK: Should we really have to specify the full path here? + // HACK: Should we really have to specify the full FilePath here? colorMap.FileName = (m_MaterialPath.branch_path() / colorMap.FileName).string(); currentMaterial->SpecularMap = colorMap; continue; @@ -297,7 +297,7 @@ void dd::OBJ::ParseMaterial() ParseBumpMap(currentLine, ss, prefix, arg, bumpMap); } - // HACK: Should we really have to specify the full path here? + // HACK: Should we really have to specify the full FilePath here? bumpMap.FileName = (m_MaterialPath.branch_path() / bumpMap.FileName).string(); currentMaterial->NormalMap = bumpMap; continue; diff --git a/src/game/Game/BallSystem.cpp b/src/game/Game/BallSystem.cpp index 37df50a..6f1b510 100644 --- a/src/game/Game/BallSystem.cpp +++ b/src/game/Game/BallSystem.cpp @@ -13,7 +13,7 @@ void dd::Systems::BallSystem::RegisterComponents(ComponentFactory *cf) void dd::Systems::BallSystem::Initialize() { - EVENT_SUBSCRIBE_MEMBER(m_Contact, BallSystem::Contact); + EVENT_SUBSCRIBE_MEMBER(m_Contact, &BallSystem::Contact); } void dd::Systems::BallSystem::Update(double dt) diff --git a/src/game/Game/LevelSystem.cpp b/src/game/Game/LevelSystem.cpp index 4130a78..4b87242 100755 --- a/src/game/Game/LevelSystem.cpp +++ b/src/game/Game/LevelSystem.cpp @@ -9,13 +9,13 @@ void dd::Systems::LevelSystem::Initialize() { - EVENT_SUBSCRIBE_MEMBER(m_EContact, LevelSystem::OnContact); - EVENT_SUBSCRIBE_MEMBER(m_ELifeLost, LevelSystem::OnLifeLost); - EVENT_SUBSCRIBE_MEMBER(m_EScoreEvent, LevelSystem::OnScoreEvent); - EVENT_SUBSCRIBE_MEMBER(m_EMultiBall, LevelSystem::OnMultiBall); - EVENT_SUBSCRIBE_MEMBER(m_ECreatePowerUp, LevelSystem::OnCreatePowerUp); - EVENT_SUBSCRIBE_MEMBER(m_EPowerUpTaken, LevelSystem::OnPowerUpTaken); - EVENT_SUBSCRIBE_MEMBER(m_EStageCleared, LevelSystem::OnStageCleared); + EVENT_SUBSCRIBE_MEMBER(m_EContact, &LevelSystem::OnContact); + EVENT_SUBSCRIBE_MEMBER(m_ELifeLost, &LevelSystem::OnLifeLost); + EVENT_SUBSCRIBE_MEMBER(m_EScoreEvent, &LevelSystem::OnScoreEvent); + EVENT_SUBSCRIBE_MEMBER(m_EMultiBall, &LevelSystem::OnMultiBall); + EVENT_SUBSCRIBE_MEMBER(m_ECreatePowerUp, &LevelSystem::OnCreatePowerUp); + EVENT_SUBSCRIBE_MEMBER(m_EPowerUpTaken, &LevelSystem::OnPowerUpTaken); + EVENT_SUBSCRIBE_MEMBER(m_EStageCleared, &LevelSystem::OnStageCleared); for (int i = 0; i < Lives(); i++) { CreateLife(i); @@ -195,7 +195,7 @@ void dd::Systems::LevelSystem::CreateBrick(int row, int line, glm::vec2 spacesBe //sound auto collisionSound = m_World->AddComponent(brick); - collisionSound->filePath = "Sounds/Brick/shortbrickbreak.wav"; + collisionSound->FilePath = "Sounds/Brick/shortbrickbreak.wav"; m_World->CommitEntity(brick); return; diff --git a/src/game/Sound/Sound.cpp b/src/game/Sound/Sound.cpp index 972f71b..f98f8eb 100644 --- a/src/game/Sound/Sound.cpp +++ b/src/game/Sound/Sound.cpp @@ -26,7 +26,7 @@ ALuint dd::Sound::LoadFile(std::string path) return 0; } - fread(&m_Size, sizeof(unsigned long), 1, fp); + fread(&m_Size, 4*sizeof(char), 1, fp); fread(m_Type, sizeof(char), 4, fp); if (m_Type[0] != 'W' || m_Type[1] != 'A' || m_Type[2] != 'V' || m_Type[3]!= 'E') { LOG_ERROR("ERROR: Not WAVE-file"); @@ -40,13 +40,13 @@ ALuint dd::Sound::LoadFile(std::string path) } //READ THE DATA FROM WAVE-FILE - fread(&m_ChunkSize, sizeof(unsigned long), 1, fp); - fread(&m_FormatType, sizeof(short), 1, fp); - fread(&m_Channels, sizeof(short), 1, fp); - fread(&m_SampleRate, sizeof(unsigned long), 1, fp); - fread(&m_AvgBytesPerSec, sizeof(unsigned long), 1, fp); - fread(&m_BytesPerSample, sizeof(short), 1, fp); - fread(&m_BitsPerSample, sizeof(short), 1, fp); + fread(&m_ChunkSize, 4*sizeof(char), 1, fp); + fread(&m_FormatType, 2*sizeof(char), 1, fp); + fread(&m_Channels, 2*sizeof(char), 1, fp); + fread(&m_SampleRate, 4*sizeof(char), 1, fp); + fread(&m_AvgBytesPerSec, 4*sizeof(char), 1, fp); + fread(&m_BytesPerSample, 2*sizeof(char), 1, fp); + fread(&m_BitsPerSample, 2*sizeof(char), 1, fp); fread(m_Type, sizeof(char), 4, fp); if (m_Type[0] !='d' || m_Type[1] != 'a' || m_Type[2] != 't' || m_Type[3] != 'a') { @@ -54,10 +54,10 @@ ALuint dd::Sound::LoadFile(std::string path) return 0; } - fread(&m_DataSize, sizeof(unsigned long), 1, fp); + fread(&m_DataSize, 4*sizeof(char), 1, fp); unsigned char* buf = new unsigned char[m_DataSize]; - fread(buf, sizeof(unsigned char), m_DataSize, fp); + fread(buf, sizeof(char), m_DataSize, fp); fclose(fp); // Create buffer diff --git a/src/game/Sound/SoundSystem.cpp b/src/game/Sound/SoundSystem.cpp index 90939a1..5fca564 100644 --- a/src/game/Sound/SoundSystem.cpp +++ b/src/game/Sound/SoundSystem.cpp @@ -4,7 +4,7 @@ dd::Systems::SoundSystem::~SoundSystem() { alcCloseDevice(m_Device); -} +}; void dd::Systems::SoundSystem::Initialize() { @@ -19,24 +19,28 @@ void dd::Systems::SoundSystem::Initialize() else { LOG_ERROR("OpenAL failed to initialize."); } - alGetError(); - //Probably unnecessary. vec3(0) probably default. - const ALfloat pos[3] = {0, 0, 0}; - //alListenerfv(AL_POSITION, pos); - - m_SFXMasterVolume = 1.f; - m_BGMMasterVolume = 1.f; - //Subscribe to events EVENT_SUBSCRIBE_MEMBER(m_EContact, &SoundSystem::OnContact); EVENT_SUBSCRIBE_MEMBER(m_EPlaySFX, &SoundSystem::OnPlaySound); EVENT_SUBSCRIBE_MEMBER(m_EStopSound, &SoundSystem::OnStopSound); EVENT_SUBSCRIBE_MEMBER(m_EMasterVolume, &SoundSystem::OnMasterVolume); - - + //Todo: Move this + { + dd::Events::PlaySound e; + e.FilePath = "Sounds/BGM/under-the-sea-instrumental.wav"; + e.IsAmbient = true; + EventBroker->Publish(e); + } + { + dd::Events::PlaySound e; + e.FilePath = "Sounds/BGM/water-flowing.wav"; + e.Gain = 0.3f; + e.IsAmbient = true; + EventBroker->Publish(e); + } } void dd::Systems::SoundSystem::Update(double dt) @@ -44,7 +48,7 @@ void dd::Systems::SoundSystem::Update(double dt) //Clean up none-active sources //Only used for SFX's. BGM's are handled on stop sound. std::vector deleteList; - for (auto item : m_SFXSourcesToBuffers) { + for (auto& item : m_SFXSourcesToBuffers) { ALint sourceState; alGetSourcei(item.first, AL_SOURCE_STATE, &sourceState); if (sourceState == AL_STOPPED) { @@ -70,32 +74,32 @@ ALuint dd::Systems::SoundSystem::CreateSource() bool dd::Systems::SoundSystem::OnPlaySound(const dd::Events::PlaySound &event) { //Loading and binding sound buffer to source - Sound *sound = ResourceManager::Load(event.path); + Sound *sound = ResourceManager::Load(event.FilePath); if (sound == nullptr) { return false; } ALuint source = CreateSource(); ALuint buffer = sound->Buffer(); alSourcei(source, AL_BUFFER, buffer); + sound->SetGain(event.Gain); //Sound settings float relativeVolume = 1.f; - if (event.isAmbient) { + if (event.IsAmbient) { alSourcei(source, AL_LOOPING, AL_TRUE); relativeVolume = m_BGMMasterVolume; m_BGMSourcesToBuffers[source] = sound; } - else if (!event.isAmbient) + else if (!event.IsAmbient) { m_SFXSourcesToBuffers[source] = sound; alSourcei(source, AL_LOOPING, AL_FALSE); relativeVolume = m_SFXMasterVolume; } - alSourcef(source, AL_GAIN, (event.volume * relativeVolume)); - alSourcef(source, AL_PITCH, event.pitch); - + alSourcef(source, AL_GAIN, (sound->Gain() * relativeVolume)); + alSourcef(source, AL_PITCH, event.Pitch); //Play alSourcePlay(source); @@ -104,53 +108,50 @@ bool dd::Systems::SoundSystem::OnPlaySound(const dd::Events::PlaySound &event) bool dd::Systems::SoundSystem::OnStopSound(const dd::Events::StopSound &event) { - - //TODO: Delete sources for bgms - ALuint itemToDelete; - for (auto item : m_BGMSourcesToBuffers) + ALuint itemToDeleted; + for (auto& item : m_BGMSourcesToBuffers) { - if (item.second->Path() == event.path) { - itemToDelete = item.first; + if (item.second->Path() == event.FilePath) { + itemToDeleted = item.first; break; } } - alSourceStop(itemToDelete); - alDeleteSources(1, &itemToDelete); - m_BGMSourcesToBuffers.erase(itemToDelete); + alSourceStop(itemToDeleted); + alDeleteSources(1, &itemToDeleted); + m_BGMSourcesToBuffers.erase(itemToDeleted); - //Should not because SFX's should be very short. + //Should not happen because SFX's should be very short. for (auto item : m_SFXSourcesToBuffers) { - if (item.second->Path() == event.path) { + if (item.second->Path() == event.FilePath) { alSourceStop(item.first); return true; } } - return false; } bool dd::Systems::SoundSystem::OnMasterVolume(const dd::Events::MasterVolume &event) { - //TODO: Make the volume depend on the value given when stored. - //TODO: .. now it ONLY uses the master volume - if (event.isAmbient) { - m_BGMMasterVolume = event.gain; - for (auto item : m_BGMSourcesToBuffers) + if (event.IsAmbient) { + m_BGMMasterVolume = event.Gain; + for (auto& item : m_BGMSourcesToBuffers) { - alSourcef(item.first, AL_GAIN, event.gain); + alSourcef(item.first, AL_GAIN, (item.second->Gain() * m_BGMMasterVolume)); } + return true; } - else if (!event.isAmbient) { - m_SFXMasterVolume = event.gain; - for (auto item : m_SFXSourcesToBuffers) + else if (!event.IsAmbient) { + m_SFXMasterVolume = event.Gain; + for (auto& item : m_SFXSourcesToBuffers) { - alSourcef(item.first, AL_GAIN, event.gain); + alSourcef(item.first, AL_GAIN, (item.second->Gain() * m_SFXMasterVolume)); } + return true; } + return false; } -//On contact: play the sound given in the CCOllisionSound. bool dd::Systems::SoundSystem::OnContact(const dd::Events::Contact &event) { //Check which entity has the collisionSound component. @@ -165,10 +166,11 @@ bool dd::Systems::SoundSystem::OnContact(const dd::Events::Contact &event) //Send play-sound event dd::Events::PlaySound e; - e.path = collisionSound->filePath; - e.isAmbient = false; + e.FilePath = collisionSound->FilePath; + e.IsAmbient = false; EventBroker->Publish(e); - //return true; + return true; } + diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index ae7d47f..13604e2 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -1,18 +1,17 @@ project(tests) +find_package(PNG REQUIRED) find_package(Boost REQUIRED COMPONENTS chrono thread unit_test_framework) include_directories( ${CMAKE_SOURCE_DIR}/include + ${PNG_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ) -set(SOURCE_FILES - main.cpp - FileWatcherTest.cpp - EventTest.cpp - ComponentCopyTest.cpp - EntityCloneTest.cpp + +file(GLOB SOURCE_FILES + "*.cpp" ) if(CMAKE_COMPILER_IS_GNUCXX) diff --git a/src/tests/EventFixture.h b/src/tests/EventFixture.h index ef9acbf..1548a08 100644 --- a/src/tests/EventFixture.h +++ b/src/tests/EventFixture.h @@ -40,7 +40,7 @@ struct EventFixture // Publish the event this->EventBroker->Publish(Before); // Clear to swap buffers - this->EventBroker->Clear(); + this->EventBroker->Swap(); // Process the event this->EventBroker->template Process(); } diff --git a/src/tests/FrameTest.cpp b/src/tests/FrameTest.cpp new file mode 100644 index 0000000..57f9712 --- /dev/null +++ b/src/tests/FrameTest.cpp @@ -0,0 +1,41 @@ +#include +#include "PrecompiledHeader.h" +#include "Core/EventBroker.h" +#include "GUI/Frame.h" + +using namespace dd; + +BOOST_AUTO_TEST_CASE(FrameTest) +{ + EventBroker eb; + + GUI::Frame baseFrame(&eb); + baseFrame.X = 100; + baseFrame.Y = 100; + + // Create a frame with a relative position to baseFrame + GUI::Frame f1(&baseFrame, "f1"); + f1.X = 50; + f1.Y = 50; + f1.Width = 50; + f1.Height = 50; + + BOOST_CHECK(f1.Left() == 150); BOOST_CHECK(baseFrame.X + f1.X == 150); + BOOST_CHECK(f1.Top() == 150); BOOST_CHECK(baseFrame.Y + f1.Y == 150); + BOOST_CHECK(f1.Right() == 200); BOOST_CHECK(baseFrame.X + f1.X + f1.Width == 200); + BOOST_CHECK(f1.Bottom() == 200); BOOST_CHECK(baseFrame.Y + f1.Y + f1.Height == 200); + + // Create a frame to the right of f1 + GUI::Frame f2(&baseFrame, "f2"); + f2.SetLeft(f1.Right()); + f2.SetTop(f1.Bottom()); + f2.Width = 50; + f2.Height = 50; + + BOOST_CHECK(f2.X == 100); BOOST_CHECK(f2.X == f1.X + f1.Width); + BOOST_CHECK(f2.Left() == 200); BOOST_CHECK(f2.Left() == f1.Right()); + BOOST_CHECK(f2.Y == 100); BOOST_CHECK(f2.Y == f1.Y + f1.Height); + BOOST_CHECK(f2.Top() == 150); BOOST_CHECK(f2.Top() == f1.Bottom()); + BOOST_CHECK(f2.Right() == 250); BOOST_CHECK(f2.Right() == f1.Right() + f2.Width); + BOOST_CHECK(f2.Bottom() == 200); BOOST_CHECK(f2.Bottom() == f1.Bottom() + f2.Height); +} \ No newline at end of file