Integrating latest 47acbe8
This commit is contained in:
@@ -31,47 +31,12 @@ namespace
|
||||
CryCriticalSection g_cPerforceValues;
|
||||
}
|
||||
|
||||
void CMyClientUser::Init()
|
||||
{
|
||||
m_e.Clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void CMyClientApi::Run(const char* func)
|
||||
{
|
||||
// The "enableStreams" var has to be set prior to any Run call in order to be able to support Perforce streams
|
||||
ClientApi::SetVar("enableStreams");
|
||||
ClientApi::Run(func);
|
||||
}
|
||||
|
||||
void CMyClientApi::Run(const char* func, ClientUser* clientUserUI)
|
||||
{
|
||||
ClientApi::SetVar("enableStreams");
|
||||
ClientApi::Run(func, clientUserUI);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
CPerforceSourceControl::CPerforceSourceControl()
|
||||
: m_ref(0)
|
||||
{
|
||||
m_bIsWorkOffline = true;
|
||||
m_bIsWorkOfflineBecauseOfConnectionLoss = true;
|
||||
m_bIsFailConnectionLogged = false;
|
||||
m_configurationInvalid = false;
|
||||
m_dwLastAccessTime = 0;
|
||||
m_client = nullptr;
|
||||
m_nextHandle = 0;
|
||||
m_lastWorkOfflineResult = true;
|
||||
m_lastWorkOfflineBecauseOfConnectionLossResult = true;
|
||||
m_clientInitialized = false;
|
||||
}
|
||||
|
||||
ULONG STDMETHODCALLTYPE CPerforceSourceControl::Release()
|
||||
{
|
||||
if ((--m_ref) == 0)
|
||||
{
|
||||
g_cPerforceValues.Lock();
|
||||
FreeData();
|
||||
delete this;
|
||||
g_cPerforceValues.Unlock();
|
||||
return 0;
|
||||
@@ -82,346 +47,49 @@ ULONG STDMETHODCALLTYPE CPerforceSourceControl::Release()
|
||||
}
|
||||
}
|
||||
|
||||
CPerforceSourceControl::~CPerforceSourceControl()
|
||||
{
|
||||
delete m_client;
|
||||
}
|
||||
|
||||
bool CPerforceSourceControl::Connect()
|
||||
{
|
||||
// before we call Init we must set up the connection!
|
||||
// the user may have overridden the connection on a per-project basis.
|
||||
// check the config file.
|
||||
AUTO_LOCK(g_cPerforceValues);
|
||||
|
||||
FreeData();
|
||||
|
||||
m_client = new CMyClientApi();
|
||||
|
||||
// Ensure P4PORT is set before calling ClientApi::Init
|
||||
const bool p4PortIsSet = nullptr != m_client->GetEnviro()->Get("P4PORT");
|
||||
if (p4PortIsSet)
|
||||
{
|
||||
m_client->Init(&m_e);
|
||||
m_clientInitialized = true;
|
||||
}
|
||||
|
||||
if (!p4PortIsSet || m_e.Test())
|
||||
{
|
||||
if (!m_bIsWorkOffline)
|
||||
{
|
||||
m_bIsWorkOfflineBecauseOfConnectionLoss = true;
|
||||
}
|
||||
|
||||
m_bIsWorkOffline = true;
|
||||
if (!m_bIsFailConnectionLogged)
|
||||
{
|
||||
GetIEditor()->GetSystem()->GetILog()->Log(p4PortIsSet ? "\nPerforce plugin: Failed to connect." : "\nPerforce plugin: P4PORT must be set to connect.");
|
||||
m_bIsFailConnectionLogged = true;
|
||||
}
|
||||
if (GetIEditor()->IsSourceControlAvailable())
|
||||
{
|
||||
//Only Check Connection and than Notify Listeners if SourceControl is available at that instance
|
||||
CheckConnectionAndNotifyListeners();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
GetIEditor()->GetSystem()->GetILog()->Log("\nPerforce plugin: Connected.");
|
||||
m_bIsFailConnectionLogged = false;
|
||||
if (m_bIsWorkOfflineBecauseOfConnectionLoss)
|
||||
{
|
||||
m_bIsWorkOffline = false;
|
||||
m_bIsWorkOfflineBecauseOfConnectionLoss = false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CPerforceSourceControl::Reconnect()
|
||||
{
|
||||
AUTO_LOCK(g_cPerforceValues);
|
||||
|
||||
if ((m_client && m_client->Dropped()) || m_bIsWorkOfflineBecauseOfConnectionLoss)
|
||||
{
|
||||
if (!m_bIsFailConnectionLogged)
|
||||
{
|
||||
GetIEditor()->GetSystem()->GetILog()->Log("\nPerforce connection dropped: attempting reconnect");
|
||||
}
|
||||
|
||||
FreeData();
|
||||
if (!Connect())
|
||||
{
|
||||
if (!m_bIsWorkOffline)
|
||||
{
|
||||
m_bIsWorkOfflineBecauseOfConnectionLoss = true;
|
||||
}
|
||||
m_bIsWorkOffline = true;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
CheckConnectionAndNotifyListeners();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CPerforceSourceControl::FreeData()
|
||||
{
|
||||
AUTO_LOCK(g_cPerforceValues);
|
||||
|
||||
if (m_client)
|
||||
{
|
||||
if (m_clientInitialized)
|
||||
{
|
||||
m_client->Final(&m_e);
|
||||
m_clientInitialized = false;
|
||||
}
|
||||
delete m_client;
|
||||
m_client = nullptr;
|
||||
}
|
||||
m_e.Clear();
|
||||
}
|
||||
|
||||
void CPerforceSourceControl::Init()
|
||||
{
|
||||
Connect();
|
||||
|
||||
{
|
||||
AzToolsFramework::SourceControlState state = AzToolsFramework::SourceControlState::Disabled;
|
||||
using SCRequestBus = AzToolsFramework::SourceControlConnectionRequestBus;
|
||||
SCRequestBus::BroadcastResult(state, &SCRequestBus::Events::GetSourceControlState);
|
||||
SetSourceControlState(state);
|
||||
}
|
||||
UpdateSourceControlState();
|
||||
}
|
||||
|
||||
void CPerforceSourceControl::ShowSettings()
|
||||
{
|
||||
AUTO_LOCK(g_cPerforceValues);
|
||||
bool workOffline = (m_bIsWorkOffline && !m_bIsWorkOfflineBecauseOfConnectionLoss);
|
||||
|
||||
if (PerforceConnection::OpenPasswordDlg())
|
||||
{
|
||||
m_bIsWorkOfflineBecauseOfConnectionLoss = false;
|
||||
bool onlineMode = false;
|
||||
{
|
||||
using SCRequestBus = AzToolsFramework::SourceControlConnectionRequestBus;
|
||||
SCRequestBus::BroadcastResult(onlineMode, &SCRequestBus::Events::IsActive);
|
||||
}
|
||||
m_bIsWorkOffline = !onlineMode;
|
||||
|
||||
// reset the connection!
|
||||
if ((!m_bIsWorkOfflineBecauseOfConnectionLoss) && onlineMode)
|
||||
{
|
||||
Connect();
|
||||
}
|
||||
|
||||
CheckConnectionAndNotifyListeners();
|
||||
UpdateSourceControlState();
|
||||
}
|
||||
}
|
||||
|
||||
const char* CPerforceSourceControl::GetErrorByGenericCode(int nGeneric)
|
||||
{
|
||||
switch (nGeneric)
|
||||
{
|
||||
case EV_USAGE:
|
||||
return "Request is not consistent with documentation or cannot support a server version";
|
||||
case EV_UNKNOWN:
|
||||
return "Using unknown entity";
|
||||
case EV_CONTEXT:
|
||||
return "Using entity in wrong context";
|
||||
case EV_ILLEGAL:
|
||||
return "Trying to do something you can't";
|
||||
case EV_NOTYET:
|
||||
return "Something must be corrected first";
|
||||
case EV_PROTECT:
|
||||
return "Operation was prevented by protection level";
|
||||
|
||||
// No fault at all
|
||||
case EV_EMPTY:
|
||||
return "Action returned empty results";
|
||||
|
||||
// not the fault of the user
|
||||
case EV_FAULT:
|
||||
return "Inexplicable program fault";
|
||||
case EV_CLIENT:
|
||||
return "Client side program errors";
|
||||
case EV_ADMIN:
|
||||
return "Server administrative action required";
|
||||
case EV_CONFIG:
|
||||
return "Client configuration is inadequate";
|
||||
case EV_UPGRADE:
|
||||
return "Client or server is too old to interact";
|
||||
case EV_COMM:
|
||||
return "Communication error";
|
||||
case EV_TOOBIG:
|
||||
return "File is too big";
|
||||
}
|
||||
|
||||
return "Undefined";
|
||||
}
|
||||
|
||||
bool CPerforceSourceControl::Run(const char* func, int nArgs, char* argv[], bool bOnlyFatal)
|
||||
{
|
||||
for (int x = 0; x < nArgs; ++x)
|
||||
{
|
||||
if (argv[x][0] == '\0')
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Reconnect())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool bRet = false;
|
||||
|
||||
AUTO_LOCK(g_cPerforceValues);
|
||||
|
||||
m_ui.Init();
|
||||
m_client->SetArgv(nArgs, argv);
|
||||
m_client->Run(func, &m_ui);
|
||||
m_client->WaitTag();
|
||||
|
||||
#if 0 // connection debug
|
||||
for (int argid = 0; argid < nArgs; argid++)
|
||||
{
|
||||
g_pSystem->GetILog()->Log("\n arg %d : %s", argid, argv[argid]);
|
||||
}
|
||||
#endif // connection debug
|
||||
|
||||
if (bOnlyFatal)
|
||||
{
|
||||
if (!m_ui.m_e.IsFatal())
|
||||
{
|
||||
bRet = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!m_ui.m_e.Test())
|
||||
{
|
||||
bRet = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_ui.m_e.GetSeverity() == E_FAILED || m_ui.m_e.GetSeverity() == E_FATAL)
|
||||
{
|
||||
static int nGenericPrev = 0;
|
||||
const int nGeneric = m_ui.m_e.GetGeneric();
|
||||
|
||||
if (IsSomeTimePassed())
|
||||
{
|
||||
nGenericPrev = 0;
|
||||
}
|
||||
|
||||
if (nGenericPrev != nGeneric)
|
||||
{
|
||||
if ((!bOnlyFatal) || (m_ui.m_e.GetSeverity() == E_FATAL))
|
||||
{
|
||||
GetIEditor()->GetSystem()->GetILog()->LogError("Perforce plugin: %s", GetErrorByGenericCode(nGeneric));
|
||||
|
||||
StrBuf m;
|
||||
m_ui.m_e.Fmt(&m);
|
||||
GetIEditor()->GetSystem()->GetILog()->LogError("Perforce plugin: %s", m.Text());
|
||||
}
|
||||
|
||||
nGenericPrev = nGeneric;
|
||||
}
|
||||
}
|
||||
|
||||
m_ui.m_e.Clear();
|
||||
return bRet;
|
||||
}
|
||||
|
||||
void CPerforceSourceControl::SetSourceControlState(SourceControlState state)
|
||||
{
|
||||
AUTO_LOCK(g_cPerforceValues);
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case SourceControlState::Disabled:
|
||||
{
|
||||
m_bIsWorkOffline = true;
|
||||
m_bIsWorkOfflineBecauseOfConnectionLoss = true;
|
||||
m_configurationInvalid = false;
|
||||
break;
|
||||
}
|
||||
case SourceControlState::Active:
|
||||
m_bIsWorkOffline = false;
|
||||
m_bIsWorkOfflineBecauseOfConnectionLoss = false;
|
||||
m_configurationInvalid = false;
|
||||
CheckConnectionAndNotifyListeners();
|
||||
break;
|
||||
|
||||
case SourceControlState::ConfigurationInvalid:
|
||||
m_bIsWorkOffline = false;
|
||||
m_bIsWorkOfflineBecauseOfConnectionLoss = false;
|
||||
m_configurationInvalid = true;
|
||||
break;
|
||||
case SourceControlState::Disabled:
|
||||
m_connectionState = ConnectivityState::Disconnected;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
case SourceControlState::Active:
|
||||
m_connectionState = ConnectivityState::Connected;
|
||||
break;
|
||||
|
||||
case SourceControlState::ConfigurationInvalid:
|
||||
m_connectionState = ConnectivityState::BadConfiguration;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CPerforceSourceControl::ConnectivityState CPerforceSourceControl::GetConnectivityState()
|
||||
void CPerforceSourceControl::UpdateSourceControlState()
|
||||
{
|
||||
ConnectivityState state = ConnectivityState::Disconnected;
|
||||
if (!m_bIsWorkOffline)
|
||||
{
|
||||
state = ConnectivityState::Connected;
|
||||
}
|
||||
else if (m_configurationInvalid)
|
||||
{
|
||||
state = ConnectivityState::BadConfiguration;
|
||||
}
|
||||
using namespace AzToolsFramework;
|
||||
|
||||
return state;
|
||||
SourceControlState state = SourceControlState::Disabled;
|
||||
SourceControlConnectionRequestBus::BroadcastResult(state,
|
||||
&SourceControlConnectionRequestBus::Events::GetSourceControlState);
|
||||
|
||||
SetSourceControlState(state);
|
||||
}
|
||||
|
||||
bool CPerforceSourceControl::CheckConnectionAndNotifyListeners()
|
||||
{
|
||||
AUTO_LOCK(g_cPerforceValues);
|
||||
|
||||
bool bRet = false;
|
||||
|
||||
bool wasWorkOffline = m_bIsWorkOffline;
|
||||
if (!m_bIsWorkOffline)
|
||||
{
|
||||
bRet = Run("info", 0, 0);
|
||||
}
|
||||
|
||||
if (m_bIsWorkOffline || m_configurationInvalid)
|
||||
{
|
||||
if (!wasWorkOffline)
|
||||
{
|
||||
// only log once when transitioning offline.
|
||||
GetIEditor()->GetSystem()->GetILog()->LogError("Perforce plugin: Perforce is offline");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
bool CPerforceSourceControl::IsSomeTimePassed()
|
||||
{
|
||||
AUTO_LOCK(g_cPerforceValues);
|
||||
const DWORD dwSomeTime = 10000; // 10 sec
|
||||
static DWORD dwLastTime = 0;
|
||||
DWORD dwCurTime = GetTickCount();
|
||||
|
||||
if (dwCurTime - dwLastTime > dwSomeTime)
|
||||
{
|
||||
dwLastTime = dwCurTime;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user