#include "ViewCtrl.h"
#include "../GameSWF/GameSWFHelper.h"
#include <Utils/DeleteFunctor.h>
#include <CasualCore.h>
#include <algorithm>
#include <functional>
#include <RKFile.h>
#include <RKDevice.h>
ViewCtrl::ViewCtrl()
: m_bBresentingModalViewCtrl(false)
, m_parentCtrl(0)
, m_pFlash(0)
, m_handle()
, m_strName("")
{
}
ViewCtrl::ViewCtrl(const gameswf::CharacterHandle& handle)
: m_bBresentingModalViewCtrl(false)
, m_parentCtrl(0)
, m_pFlash(0)
, m_handle(handle)
, m_strName("")
{
}
ViewCtrl::ViewCtrl(const string& flashSourceFile)
: m_bBresentingModalViewCtrl(false)
, m_parentCtrl(0)
, m_pFlash(0)
, m_strName("")
{
char fileName[128];
snprintf(fileName, sizeof(fileName), "%s.swf", flashSourceFile.c_str());
m_strName = flashSourceFile.c_str();
#ifndef GAME_BOT
m_pFlash = gameswf::load(fileName);
m_handle = m_pFlash->getRootHandle();
#endif
}
ViewCtrl::~ViewCtrl()
{
if (m_handle.isValid())
{
m_handle.setVisible(false);
}
if (m_pFlash)
gameswf::unload(m_pFlash);
for_each(m_children.begin(), m_children.end(), DeleteFunctor<ViewCtrl>());
m_children.clear();
}
void ViewCtrl::AddChildViewCtrl(ViewCtrl * pVC)
{
if (pVC)
{
pVC->SetParentViewCtrl(this);
pVC->SetVisible(this->m_handle.isVisible());
m_children.push_back(pVC);
NotifyFlashOrderChange();
}
}
void ViewCtrl::RemoveChildViewCtrl(ViewCtrl * pVC)
{
if (pVC)
{
std::vector<ViewCtrl*>::iterator it = find_if(m_children.begin(), m_children.end(), std::bind1st(std::equal_to<ViewCtrl*>(), pVC));
if (it != m_children.end())
{
m_childrenToBeRemoved.push_back(pVC);
}
}
}
bool ViewCtrl::PresentModalViewCtrl(ViewCtrl * pVC)
{
if (pVC && !m_bBresentingModalViewCtrl)
{
SetPresentingModalViewCtrl(true);
pVC->SetParentViewCtrl(this);
m_children.push_back(pVC);
NotifyFlashOrderChange();
Hide();
return true;
}
return false;
}
void ViewCtrl::DismissModalViewCtrl()
{
RKASSERT(m_parentCtrl, "No parent controller in ViewCtrl::DismissModalViewCtrl");
if (m_parentCtrl)
{
m_parentCtrl->DismissModalViewCtrl(this);
}
}
void ViewCtrl::Update(float time_elapsed)
{
TryRemoveChildren();
for_each(m_children.begin(), m_children.end(), std::bind2nd(std::mem_fun(&ViewCtrl::Update), time_elapsed));
}
void ViewCtrl::SetVisible(bool isVisible)
{
if (m_handle.isValid())
{
m_handle.setVisible(isVisible);
}
for_each(m_children.begin(), m_children.end(), std::bind2nd(std::mem_fun(&ViewCtrl::SetVisible), isVisible));
}
void ViewCtrl::Show()
{
if (m_pFlash != nullptr) {
m_handle.setVisible(true);
}
}
void ViewCtrl::Hide()
{
if (m_pFlash != nullptr) {
m_handle.setVisible(false);
}
}
void ViewCtrl::SetEnable(bool isEnabled)
{
if (m_handle.isValid())
{
m_handle.setEnabled(isEnabled);
}
for_each(m_children.begin(), m_children.end(), std::bind2nd(std::mem_fun(&ViewCtrl::SetEnable), isEnabled));
}
struct RemoveChild
{
std::vector<ViewCtrl*>& m_children;
explicit RemoveChild(std::vector<ViewCtrl*>& children) : m_children(children){}
void operator()(ViewCtrl* pVC)
{
std::vector<ViewCtrl*>& items = m_children;
std::vector<ViewCtrl*>::iterator it = find_if(items.begin(), items.end(), std::bind1st(std::equal_to<ViewCtrl*>(), pVC));
if (it != items.end())
{
items.erase(it);
RKDELETE(pVC);
}
}
};
void ViewCtrl::TryRemoveChildren()
{
std::vector<ViewCtrl*>& items = m_childrenToBeRemoved;
if (items.size() > 0)
{
for_each(items.begin(), items.end(), RemoveChild(m_children));
items.clear();
NotifyFlashOrderChange();
}
}
void ViewCtrl::DismissModalViewCtrl(ViewCtrl * pVC)
{
if (pVC)
{
RemoveChildViewCtrl(pVC);
SetPresentingModalViewCtrl(false);
Show();
}
}
void ViewCtrl::SetPresentingModalViewCtrl(bool b)
{
m_bBresentingModalViewCtrl = b;
if (m_parentCtrl)
m_parentCtrl->SetPresentingModalViewCtrl(b);
}
void ViewCtrl::NotifyFlashOrderChange()
{
if (m_parentCtrl)
{
if (m_parentCtrl->m_parentCtrl == this) {
RKASSERT(false, "ViewCtrl's parent is also its child; breaking to prevent stack overflow");
}
else {
m_parentCtrl->NotifyFlashOrderChange();
}
}
else
{
CommitFlashOrderChange();
}
}
bool ViewCtrl::SetCustomizedOrder(int aOrder)
{
if (m_pFlash)
{
CGAME->GetFlashManager()->SetFlashOrder(m_pFlash, aOrder);
return true;
}
else
{
return false;
}
}
int ViewCtrl::GetCustomizedOrder()
{
return m_pFlash ? CGAME->GetFlashManager()->GetFlashOrder(m_pFlash) : 0;
}
struct IncreaseOrder
{
int m_currentOrder;
IncreaseOrder() { m_currentOrder = 0; }
explicit IncreaseOrder(int a_startIndex) { m_currentOrder = a_startIndex; }
void operator()(ViewCtrl* pVC)
{
if (pVC->SetCustomizedOrder(m_currentOrder))
m_currentOrder++;
pVC->UpdateFlashOrder(*this);
}
};
void ViewCtrl::CommitFlashOrderChange()
{
IncreaseOrder increaseOrder(GetCustomizedOrder());
increaseOrder(this);
}
void ViewCtrl::UpdateFlashOrder(const IncreaseOrder &aIncreaseOrder)
{
for_each(m_children.begin(), m_children.end(), aIncreaseOrder);
}