00001 //---------------------------------------------------------------------------- 00002 /** @file GoBoardSynchronizer.cpp */ 00003 //---------------------------------------------------------------------------- 00004 00005 #include "SgSystem.h" 00006 #include "GoBoardSynchronizer.h" 00007 00008 #include "GoBoard.h" 00009 00010 using namespace std; 00011 00012 //---------------------------------------------------------------------------- 00013 00014 GoBoardSynchronizer::GoBoardSynchronizer(const GoBoard& publisher) 00015 : m_publisher(publisher), 00016 m_subscriber(0) 00017 { 00018 } 00019 00020 GoBoardSynchronizer::~GoBoardSynchronizer() 00021 { 00022 } 00023 00024 void GoBoardSynchronizer::SetSubscriber(GoBoard& subscriber) 00025 { 00026 SG_ASSERT(! m_subscriber); 00027 m_subscriber = &subscriber; 00028 } 00029 00030 int GoBoardSynchronizer::FindNuCommon() const 00031 { 00032 const int nuPublisher = m_publisher.MoveNumber(); 00033 const int nuSubscriber = m_subscriber->MoveNumber(); 00034 int i; 00035 for (i = 0; i < nuPublisher; ++i) 00036 if (i >= nuSubscriber || m_publisher.Move(i) != m_subscriber->Move(i)) 00037 break; 00038 return i; 00039 } 00040 00041 void GoBoardSynchronizer::ExecuteSubscriber(const GoPlayerMove& move) 00042 { 00043 PrePlay(move); 00044 m_subscriber->Play(move); 00045 OnPlay(move); 00046 } 00047 00048 void GoBoardSynchronizer::OnBoardChange() 00049 { 00050 } 00051 00052 void GoBoardSynchronizer::PrePlay(GoPlayerMove move) 00053 { 00054 SG_UNUSED(move); 00055 } 00056 00057 void GoBoardSynchronizer::OnPlay(GoPlayerMove move) 00058 { 00059 SG_UNUSED(move); 00060 } 00061 00062 void GoBoardSynchronizer::PreUndo() 00063 { 00064 } 00065 00066 void GoBoardSynchronizer::OnUndo() 00067 { 00068 } 00069 00070 void GoBoardSynchronizer::UpdateFromInit() 00071 { 00072 m_subscriber->Init(m_publisher.Size(), m_publisher.Setup()); 00073 OnBoardChange(); 00074 const int nuPublisher = m_publisher.MoveNumber(); 00075 for (int i = 0; i < nuPublisher; ++i) 00076 ExecuteSubscriber(m_publisher.Move(i)); 00077 } 00078 00079 void GoBoardSynchronizer::UpdateIncremental() 00080 { 00081 const int nuCommon = FindNuCommon(); 00082 const int nuSubscriber = m_subscriber->MoveNumber(); 00083 const int nuUndo = nuSubscriber - nuCommon; 00084 for (int i = 0; i < nuUndo; ++i) 00085 { 00086 SG_ASSERT(m_subscriber->MoveNumber() > 0); 00087 PreUndo(); 00088 m_subscriber->Undo(); 00089 OnUndo(); 00090 } 00091 const int nuPublisher = m_publisher.MoveNumber(); 00092 for (int i = nuCommon; i < nuPublisher; ++i) 00093 ExecuteSubscriber(m_publisher.Move(i)); 00094 } 00095 00096 void GoBoardSynchronizer::UpdateSubscriber() 00097 { 00098 if (m_subscriber == 0) 00099 return; 00100 m_subscriber->Rules() = m_publisher.Rules(); 00101 if (m_publisher.Size() != m_subscriber->Size() 00102 || m_publisher.Setup() != m_subscriber->Setup()) 00103 UpdateFromInit(); 00104 else 00105 UpdateIncremental(); 00106 UpdateToPlay(); 00107 SG_ASSERT(m_publisher.GetHashCode() == m_subscriber->GetHashCode()); 00108 } 00109 00110 void GoBoardSynchronizer::UpdateToPlay() 00111 { 00112 if (m_publisher.ToPlay() != m_subscriber->ToPlay()) 00113 m_subscriber->SetToPlay(m_publisher.ToPlay()); 00114 } 00115 00116 //----------------------------------------------------------------------------