/******************************************************************************* Copyright © 2017 Philips Lighting Holding B.V. All Rights Reserved. ********************************************************************************/ #include "stdafx.h" #include #include #pragma comment(lib, "winmm.lib") #include #include #include #include #include #include "EffectPlayer.h" #include "huestream/effect/animation/data/Channel.h" #include "huestream/effect/specialized/MultiChannelEffect.h" using namespace std; using namespace std::chrono; using namespace huestream; EffectPlayer::EffectPlayer() { m_hueStream = HueStream::GetInstance(); m_speed = 1.0; m_running = false; m_speedAnimation = make_shared(1.0); m_alpha_saw = make_shared(1); m_alpha_square = make_shared(1); m_alpha_sine = make_shared(1); m_alpha_marquee = make_shared(1); m_alpha_colorloop = make_shared(1); m_alpha_fireballs = make_shared(1); m_alpha_police = make_shared(1); } void EffectPlayer::SetSpeed(double speed) { m_cs.Lock(); m_speed = speed; m_cs.Unlock(); m_hueStream->LockEngine(); m_speedAnimation->SetValue(speed); m_hueStream->UnlockEngine(); } void EffectPlayer::PlayExplosion() { Start(); static auto s_explosionCount = 0; std::string name = "BAM!" + std::to_string(s_explosionCount++); m_hueStream->LockEngine(); auto explosion = make_shared(name, 9); auto color = Color(1.0, 0.7, 0.3); auto radius = 2.0; auto speed = GetSpeed(); auto expAlpha = 150 / speed; auto expRadius = 250 / speed; auto duration = 1500 / speed; auto location = Location(0.0, 0.0); explosion->PrepareEffect(color, location, radius, duration, expAlpha, expRadius); m_hueStream->AddEffect(explosion); explosion->Enable(); m_hueStream->UnlockEngine(); PlaySoundA((LPCSTR)"explosion.wav", NULL, SND_FILENAME | SND_ASYNC); } void EffectPlayer::PlayRedWhiteBlue() { Start(); static auto s_rwbCount = 0; std::string name = "rwb" + std::to_string(s_rwbCount++); m_hueStream->LockEngine(); auto animation = make_shared(0); auto slowUp = make_shared(0, 1, 2500, TweenType::Linear); auto fastDown = make_shared(1, 0.5, 500, TweenType::Linear); auto fastUp = make_shared(0.5, 1, 500, TweenType::Linear); auto fastDownUpRepeated = make_shared(3); fastDownUpRepeated->Append(fastDown, "FastDown"); fastDownUpRepeated->Append(fastUp, "FastUp"); auto slowDown = make_shared(1, 0, 2500, TweenType::Linear); animation->Append(slowUp, "SlowUp"); animation->Append(fastDownUpRepeated, "FastDownUp"); animation->Append(slowDown, "SlowDown"); auto zero = make_shared(0); auto one = make_shared(1); auto redChannel = make_shared(Location(-(2.0 / 3.0), 0), animation, zero, zero, one); auto whiteChannel = make_shared(Location(0, 0), animation, animation, animation, one); auto blueChannel = make_shared(Location((2.0 / 3.0), 0), zero, zero, animation, one); auto rwbEffect = make_shared(name, 0); rwbEffect->AddChannel(redChannel); rwbEffect->AddChannel(whiteChannel); rwbEffect->AddChannel(blueChannel); rwbEffect->SetSpeedAnimation(m_speedAnimation); m_hueStream->AddEffect(rwbEffect); rwbEffect->Enable(); m_hueStream->UnlockEngine(); } void EffectPlayer::PlayCombi() { Start(); static auto s_combiCount = 0; std::string bcName = "Saw" + std::to_string(s_combiCount++); std::string lsName = "RandomFlash" + std::to_string(s_combiCount); m_hueStream->LockEngine(); auto bcEffect = make_shared(bcName, 0); auto b = make_shared(4); b->Append(make_shared(0, 1, 1000, TweenType::Linear), "Up"); b->Append(make_shared(1, 0, 1000, TweenType::Linear), "Down"); auto g = make_shared(0); auto r = make_shared(0); bcEffect->SetColorAnimation(r, g, b); bcEffect->AddArea(Area::All); bcEffect->SetSpeedAnimation(m_speedAnimation); auto lsEffect = make_shared(lsName, 1); auto length = 8000; auto i = make_shared(0.1, 1, 200, 400, TweenType::Linear, length); lsEffect->SetColorAnimation(i, i, i); lsEffect->SetRadiusAnimation(i); auto x = make_shared(-1, 1, 500, 1000, TweenType::Linear, length); auto y = make_shared(-1, 1, 500, 1000, TweenType::Linear, length); lsEffect->SetPositionAnimation(x, y); lsEffect->SetOpacityAnimation(make_shared(0.8)); lsEffect->SetSpeedAnimation(m_speedAnimation); m_hueStream->AddEffect(bcEffect); m_hueStream->AddEffect(lsEffect); bcEffect->Enable(); lsEffect->Enable(); m_hueStream->UnlockEngine(); } void EffectPlayer::PlaySequenceRound() { Start(); AfxBeginThread(SequenceRound, (LPVOID)this); } void EffectPlayer::PlaySequenceLtoR() { Start(); AfxBeginThread(SequenceLtoR, (LPVOID)this); } void EffectPlayer::PlaySequenceFtoB() { Start(); AfxBeginThread(SequenceFtoB, (LPVOID)this); } UINT EffectPlayer::SequenceRound(LPVOID pParam) { EffectPlayer* self = (EffectPlayer*)pParam; auto hueStream = self->m_hueStream; static auto s_roundeffectCount = 0; std::string name = "RoundSeq" + std::to_string(s_roundeffectCount++); hueStream->LockEngine(); auto effect = std::make_shared(name, 1); effect->SetMode(SequenceModeRound); effect->AddColor(Color(1, 1, 0)); effect->AddColor(Color(0, 1, 1)); effect->AddColor(Color(1, 0, 1)); effect->AddColor(Color(1, 0, 0)); effect->AddColor(Color(0, 1, 0)); effect->SetBri(10.0); hueStream->AddEffect(effect); effect->Enable(); hueStream->UnlockEngine(); for (int i = 0; i < 30; i++) { hueStream->LockEngine(); effect->Step(); hueStream->UnlockEngine(); auto waitTime = (int)round(500.0 / self->GetSpeed()); std::unique_lock lk(self->m_cv_mutex); self->m_cv.wait_until(lk, system_clock::now() + milliseconds(waitTime)); if (!self->IsRunning()) { break; } } hueStream->LockEngine(); effect->Disable(); hueStream->UnlockEngine(); return 0; } UINT EffectPlayer::SequenceLtoR(LPVOID pParam) { EffectPlayer* self = (EffectPlayer*)pParam; auto hueStream = self->m_hueStream; static auto s_leftRightSeqCount = 0; std::string name = "LeftRightSeq" + std::to_string(s_leftRightSeqCount++); hueStream->LockEngine(); auto effect = std::make_shared(name, 1); effect->SetMode(SequenceModeLeftRight); effect->AddColor(Color(1, 1, 0)); effect->AddColor(Color(0, 1, 1)); effect->AddColor(Color(1, 0, 1)); effect->AddColor(Color(1, 0, 0)); effect->AddColor(Color(0, 1, 0)); hueStream->AddEffect(effect); effect->Enable(); hueStream->UnlockEngine(); for (int i = 0; i < 30; i++) { hueStream->LockEngine(); effect->Step(); hueStream->UnlockEngine(); auto waitTime = (int)round(500.0 / self->GetSpeed()); std::unique_lock lk(self->m_cv_mutex); self->m_cv.wait_until(lk, system_clock::now() + milliseconds(waitTime)); if (!self->IsRunning()) { break; } } hueStream->LockEngine(); effect->Disable(); hueStream->UnlockEngine(); return 0; } UINT EffectPlayer::SequenceFtoB(LPVOID pParam) { EffectPlayer* self = (EffectPlayer*)pParam; auto hueStream = self->m_hueStream; static auto s_frontbackSeqCount = 0; std::string name = "frontbackSeq" + std::to_string(s_frontbackSeqCount++); hueStream->LockEngine(); auto effect = std::make_shared(name, 1); effect->SetMode(SequenceModeFrontBack); effect->AddColor(Color(1, 0, 0)); effect->AddColor(Color(0, 1, 0)); effect->AddColor(Color(0, 0, 1)); hueStream->AddEffect(effect); effect->Enable(); hueStream->UnlockEngine(); for (int i = 0; i < 30; i++) { hueStream->LockEngine(); effect->Step(); hueStream->UnlockEngine(); auto waitTime = (int)round(500.0 / self->GetSpeed()); std::unique_lock lk(self->m_cv_mutex); self->m_cv.wait_until(lk, system_clock::now() + milliseconds(waitTime)); if (!self->IsRunning()) { break; } } hueStream->LockEngine(); effect->Disable(); hueStream->UnlockEngine(); return 0; } void EffectPlayer::SetSawEnabled(bool enabled) { if (enabled) { Start(); m_hueStream->LockEngine(); if (m_saw == nullptr) { m_saw = std::make_shared("Saw", 8); m_saw->PrepareEffect(m_speedAnimation, m_alpha_saw); m_hueStream->AddEffect(m_saw); } m_saw->Enable(); m_hueStream->UnlockEngine(); } else if (m_saw != nullptr) { m_hueStream->LockEngine(); m_saw->Disable(); m_hueStream->UnlockEngine(); } } void EffectPlayer::SetSquareEnabled(bool enabled) { if (enabled) { Start(); m_hueStream->LockEngine(); if (m_square == nullptr) { m_square = std::make_shared("Square", 7); m_square->PrepareEffect(m_speedAnimation, m_alpha_square); m_hueStream->AddEffect(m_square); } m_square->Enable(); m_hueStream->UnlockEngine(); } else if (m_square != nullptr) { m_hueStream->LockEngine(); m_square->Disable(); m_hueStream->UnlockEngine(); } } void EffectPlayer::SetSineEnabled(bool enabled) { if (enabled) { Start(); m_hueStream->LockEngine(); if (m_sine == nullptr) { m_sine = std::make_shared("Sine", 6); m_sine->PrepareEffect(m_speedAnimation, m_alpha_sine); m_hueStream->AddEffect(m_sine); } m_sine->Enable(); m_hueStream->UnlockEngine(); } else if (m_sine != nullptr) { m_hueStream->LockEngine(); m_sine->Disable(); m_hueStream->UnlockEngine(); } } void EffectPlayer::SetColorloopEnabled(bool enabled) { if (enabled) { Start(); m_hueStream->LockEngine(); if (m_colorloop == nullptr) { m_colorloop = std::make_shared("Colorloop", 5); m_colorloop->PrepareEffect(m_speedAnimation, m_alpha_colorloop); m_hueStream->AddEffect(m_colorloop); } m_colorloop->Enable(); m_hueStream->UnlockEngine(); } else if (m_colorloop != nullptr) { m_hueStream->LockEngine(); m_colorloop->Disable(); m_hueStream->UnlockEngine(); } } void EffectPlayer::SetMarqueeEnabled(bool enabled) { if (enabled) { Start(); m_hueStream->LockEngine(); if (m_marquee == nullptr) { m_marquee = std::make_shared("Marquee", 4); m_marquee->PrepareEffect(m_speedAnimation, m_alpha_marquee); m_hueStream->AddEffect(m_marquee); } m_marquee->Enable(); m_hueStream->UnlockEngine(); } else if (m_marquee != nullptr) { m_hueStream->LockEngine(); m_marquee->Disable(); m_hueStream->UnlockEngine(); } } void EffectPlayer::SetFireballsEnabled(bool enabled) { if (enabled) { Start(); m_hueStream->LockEngine(); if (m_fireballs == nullptr) { m_fireballs = std::make_shared("Fireballs", 3); m_fireballs->PrepareEffect(m_speedAnimation, m_alpha_fireballs); m_hueStream->AddEffect(m_fireballs); } m_fireballs->Enable(); m_hueStream->UnlockEngine(); } else if (m_fireballs != nullptr) { m_hueStream->LockEngine(); m_fireballs->Disable(); m_hueStream->UnlockEngine(); } } void EffectPlayer::SetPoliceEnabled(bool enabled) { if (enabled) { Start(); m_hueStream->LockEngine(); if (m_police_left == nullptr) { m_police_left = std::make_shared("PoliceLeft", 2); m_police_left->AddArea(Area::LeftHalf); auto animationLeft = std::make_shared(INF); animationLeft->Append(std::make_shared(0.2, 1, 160, TweenType::Linear)); animationLeft->Append(std::make_shared(1, 1, 160, TweenType::Linear)); animationLeft->Append(std::make_shared(1, 0.2, 160, TweenType::Linear)); animationLeft->Append(std::make_shared(0.2, 0.1, 160, TweenType::Linear)); m_police_left->SetColorAnimation(animationLeft,std::make_shared(0),std::make_shared(0)); m_police_left->SetOpacityAnimation(m_alpha_fireballs); m_police_left->SetSpeedAnimation(m_speedAnimation); m_hueStream->AddEffect(m_police_left); } if (m_police_right == nullptr) { m_police_right = std::make_shared("PoliceRight", 2); m_police_right->AddArea(Area::RightHalf); auto animationRight = std::make_shared(INF); animationRight->Append(std::make_shared(1, 0.2, 160, TweenType::Linear)); animationRight->Append(std::make_shared(0.2, 0.1, 160, TweenType::Linear)); animationRight->Append(std::make_shared(0.2, 1, 160, TweenType::Linear)); animationRight->Append(std::make_shared(1, 1, 160, TweenType::Linear)); m_police_right->SetColorAnimation(std::make_shared(0),std::make_shared(0),animationRight); m_police_left->SetOpacityAnimation(m_alpha_fireballs); m_police_right->SetSpeedAnimation(m_speedAnimation); m_hueStream->AddEffect(m_police_right); } m_police_left->Enable(); m_police_right->Enable(); m_hueStream->UnlockEngine(); } else if (m_police_left != nullptr && m_police_right != nullptr) { m_hueStream->LockEngine(); m_police_left->Disable(); m_police_right->Disable(); m_hueStream->UnlockEngine(); } } double EffectPlayer::GetSpeed() { m_cs.Lock(); auto speed = m_speed; m_cs.Unlock(); return speed; } void EffectPlayer::Start() { m_cs.Lock(); m_running = true; m_cs.Unlock(); m_hueStream->StartAsync(); } void EffectPlayer::Stop() { m_running = false; m_cv.notify_all(); m_hueStream->Stop(); m_marquee = nullptr; } bool EffectPlayer::IsRunning() { m_cs.Lock(); auto running = m_running; m_cs.Unlock(); return running; }