mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-04-29 16:25:42 +00:00
Merge pull request #1907 from elfprince13/osxDedeprecation
OSX de-deprecation (profiler and macFileIO)
This commit is contained in:
commit
87c9fce380
5 changed files with 223 additions and 199 deletions
|
|
@ -491,10 +491,11 @@ template<class T> T ReservedSocketList<T>::resolve(NetSocket socketToResolve)
|
||||||
EntryType &entry = mSocketList[socketToResolve.getHandle()];
|
EntryType &entry = mSocketList[socketToResolve.getHandle()];
|
||||||
return entry.used ? entry.value : -1;
|
return entry.used ? entry.value : -1;
|
||||||
}
|
}
|
||||||
ConnectionNotifyEvent* Net::smConnectionNotify = NULL;
|
|
||||||
ConnectionAcceptedEvent* Net::smConnectionAccept = NULL;
|
static ConnectionNotifyEvent* smConnectionNotify = NULL;
|
||||||
ConnectionReceiveEvent* Net::smConnectionReceive = NULL;
|
static ConnectionAcceptedEvent* smConnectionAccept = NULL;
|
||||||
PacketReceiveEvent* Net::smPacketReceive = NULL;
|
static ConnectionReceiveEvent* smConnectionReceive = NULL;
|
||||||
|
static PacketReceiveEvent* smPacketReceive = NULL;
|
||||||
|
|
||||||
ConnectionNotifyEvent& Net::getConnectionNotifyEvent()
|
ConnectionNotifyEvent& Net::getConnectionNotifyEvent()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -214,13 +214,12 @@ struct Net
|
||||||
static bool smMulticastEnabled;
|
static bool smMulticastEnabled;
|
||||||
static bool smIpv4Enabled;
|
static bool smIpv4Enabled;
|
||||||
static bool smIpv6Enabled;
|
static bool smIpv6Enabled;
|
||||||
|
|
||||||
static ConnectionNotifyEvent* smConnectionNotify;
|
static ConnectionNotifyEvent* smConnectionNotify;
|
||||||
static ConnectionAcceptedEvent* smConnectionAccept;
|
static ConnectionAcceptedEvent* smConnectionAccept;
|
||||||
static ConnectionReceiveEvent* smConnectionReceive;
|
static ConnectionReceiveEvent* smConnectionReceive;
|
||||||
static PacketReceiveEvent* smPacketReceive;
|
static PacketReceiveEvent* smPacketReceive;
|
||||||
|
|
||||||
|
|
||||||
static bool init();
|
static bool init();
|
||||||
static void shutdown();
|
static void shutdown();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(TORQUE_OS_MAC)
|
#if defined(TORQUE_OS_MAC)
|
||||||
#include <CoreServices/CoreServices.h> // For high resolution timer
|
#include <mach/mach_time.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "core/stream/fileStream.h"
|
#include "core/stream/fileStream.h"
|
||||||
|
|
@ -48,15 +48,15 @@ Profiler *gProfiler = NULL;
|
||||||
//#define TORQUE_PROFILER_DEBUG
|
//#define TORQUE_PROFILER_DEBUG
|
||||||
|
|
||||||
// Machinery to record the stack of node names, as a debugging aid to find
|
// Machinery to record the stack of node names, as a debugging aid to find
|
||||||
// mismatched PROFILE_START and PROFILE_END blocks. We profile from the
|
// mismatched PROFILE_START and PROFILE_END blocks. We profile from the
|
||||||
// beginning to catch profile block errors that occur when torque is starting up.
|
// beginning to catch profile block errors that occur when torque is starting up.
|
||||||
#ifdef TORQUE_PROFILER_DEBUG
|
#ifdef TORQUE_PROFILER_DEBUG
|
||||||
Vector<StringTableEntry> gProfilerNodeStack;
|
Vector<StringTableEntry> gProfilerNodeStack;
|
||||||
#define TORQUE_PROFILE_AT_ENGINE_START true
|
#define TORQUE_PROFILE_AT_ENGINE_START true
|
||||||
#define PROFILER_DEBUG_PUSH_NODE( nodename ) \
|
#define PROFILER_DEBUG_PUSH_NODE( nodename ) \
|
||||||
gProfilerNodeStack.push_back( nodename );
|
gProfilerNodeStack.push_back( nodename );
|
||||||
#define PROFILER_DEBUG_POP_NODE() \
|
#define PROFILER_DEBUG_POP_NODE() \
|
||||||
gProfilerNodeStack.pop_back();
|
gProfilerNodeStack.pop_back();
|
||||||
#else
|
#else
|
||||||
#define TORQUE_PROFILE_AT_ENGINE_START false
|
#define TORQUE_PROFILE_AT_ENGINE_START false
|
||||||
#define PROFILER_DEBUG_PUSH_NODE( nodename ) ;
|
#define PROFILER_DEBUG_PUSH_NODE( nodename ) ;
|
||||||
|
|
@ -68,7 +68,7 @@ Vector<StringTableEntry> gProfilerNodeStack;
|
||||||
void startHighResolutionTimer(U32 time[2])
|
void startHighResolutionTimer(U32 time[2])
|
||||||
{
|
{
|
||||||
//time[0] = Platform::getRealMilliseconds();
|
//time[0] = Platform::getRealMilliseconds();
|
||||||
|
|
||||||
__asm
|
__asm
|
||||||
{
|
{
|
||||||
push eax
|
push eax
|
||||||
|
|
@ -89,7 +89,7 @@ U32 endHighResolutionTimer(U32 time[2])
|
||||||
U32 ticks;
|
U32 ticks;
|
||||||
//ticks = Platform::getRealMilliseconds() - time[0];
|
//ticks = Platform::getRealMilliseconds() - time[0];
|
||||||
//return ticks;
|
//return ticks;
|
||||||
|
|
||||||
__asm
|
__asm
|
||||||
{
|
{
|
||||||
push eax
|
push eax
|
||||||
|
|
@ -135,20 +135,26 @@ U32 endHighResolutionTimer(U32 time[2])
|
||||||
|
|
||||||
|
|
||||||
void startHighResolutionTimer(U32 time[2]) {
|
void startHighResolutionTimer(U32 time[2]) {
|
||||||
UnsignedWide t;
|
U64 now = mach_absolute_time();
|
||||||
Microseconds(&t);
|
AssertFatal(sizeof(U32[2]) == sizeof(U64), "Can't pack mach_absolute_time into U32[2]");
|
||||||
time[0] = t.lo;
|
memcpy(time, &now, sizeof(U64));
|
||||||
time[1] = t.hi;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
U32 endHighResolutionTimer(U32 time[2]) {
|
U32 endHighResolutionTimer(U32 time[2]) {
|
||||||
UnsignedWide t;
|
static mach_timebase_info_data_t sTimebaseInfo = {0, 0};
|
||||||
Microseconds(&t);
|
|
||||||
return t.lo - time[0];
|
U64 now = mach_absolute_time();
|
||||||
// given that we're returning a 32 bit integer, and this is unsigned subtraction...
|
AssertFatal(sizeof(U32[2]) == sizeof(U64), "Can't pack mach_absolute_time into U32[2]");
|
||||||
// it will just wrap around, we don't need the upper word of the time.
|
U64 then;
|
||||||
// NOTE: the code assumes that more than 3 hrs will not go by between calls to startHighResolutionTimer() and endHighResolutionTimer().
|
memcpy(&then, time, sizeof(U64));
|
||||||
// I mean... that damn well better not happen anyway.
|
|
||||||
|
if(sTimebaseInfo.denom == 0){
|
||||||
|
mach_timebase_info(&sTimebaseInfo);
|
||||||
|
}
|
||||||
|
// Handle the micros/nanos conversion first, because shedding a few bits is better than overflowing.
|
||||||
|
U64 elapsedMicros = ((now - then) / 1000) * sTimebaseInfo.numer / sTimebaseInfo.denom;
|
||||||
|
|
||||||
|
return (U32)elapsedMicros; // Just truncate, and hope we didn't overflow
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
@ -170,7 +176,7 @@ Profiler::Profiler()
|
||||||
{
|
{
|
||||||
mMaxStackDepth = MaxStackDepth;
|
mMaxStackDepth = MaxStackDepth;
|
||||||
mCurrentHash = 0;
|
mCurrentHash = 0;
|
||||||
|
|
||||||
mCurrentProfilerData = (ProfilerData *) malloc(sizeof(ProfilerData));
|
mCurrentProfilerData = (ProfilerData *) malloc(sizeof(ProfilerData));
|
||||||
mCurrentProfilerData->mRoot = NULL;
|
mCurrentProfilerData->mRoot = NULL;
|
||||||
mCurrentProfilerData->mNextForRoot = NULL;
|
mCurrentProfilerData->mNextForRoot = NULL;
|
||||||
|
|
@ -185,17 +191,17 @@ Profiler::Profiler()
|
||||||
mCurrentProfilerData->mInvokeCount = 0;
|
mCurrentProfilerData->mInvokeCount = 0;
|
||||||
mCurrentProfilerData->mTotalTime = 0;
|
mCurrentProfilerData->mTotalTime = 0;
|
||||||
mCurrentProfilerData->mSubTime = 0;
|
mCurrentProfilerData->mSubTime = 0;
|
||||||
#ifdef TORQUE_ENABLE_PROFILE_PATH
|
#ifdef TORQUE_ENABLE_PROFILE_PATH
|
||||||
mCurrentProfilerData->mPath = "";
|
mCurrentProfilerData->mPath = "";
|
||||||
#endif
|
#endif
|
||||||
mRootProfilerData = mCurrentProfilerData;
|
mRootProfilerData = mCurrentProfilerData;
|
||||||
|
|
||||||
for(U32 i = 0; i < ProfilerData::HashTableSize; i++)
|
for(U32 i = 0; i < ProfilerData::HashTableSize; i++)
|
||||||
mCurrentProfilerData->mChildHash[i] = 0;
|
mCurrentProfilerData->mChildHash[i] = 0;
|
||||||
|
|
||||||
mProfileList = NULL;
|
mProfileList = NULL;
|
||||||
|
|
||||||
mEnabled = TORQUE_PROFILE_AT_ENGINE_START;
|
mEnabled = TORQUE_PROFILE_AT_ENGINE_START;
|
||||||
mNextEnable = TORQUE_PROFILE_AT_ENGINE_START;
|
mNextEnable = TORQUE_PROFILE_AT_ENGINE_START;
|
||||||
mStackDepth = 0;
|
mStackDepth = 0;
|
||||||
gProfiler = this;
|
gProfiler = this;
|
||||||
|
|
@ -216,20 +222,20 @@ void Profiler::reset()
|
||||||
mEnabled = false; // in case we're in a profiler call.
|
mEnabled = false; // in case we're in a profiler call.
|
||||||
ProfilerData * head = mProfileList;
|
ProfilerData * head = mProfileList;
|
||||||
ProfilerData * curr = head;
|
ProfilerData * curr = head;
|
||||||
|
|
||||||
while ( curr )
|
while ( curr )
|
||||||
{
|
{
|
||||||
head = curr->mNextProfilerData;
|
head = curr->mNextProfilerData;
|
||||||
free( curr );
|
free( curr );
|
||||||
|
|
||||||
if ( head )
|
if ( head )
|
||||||
curr = head;
|
curr = head;
|
||||||
else
|
else
|
||||||
curr = NULL;
|
curr = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
mProfileList = NULL;
|
mProfileList = NULL;
|
||||||
|
|
||||||
for(ProfilerRootData *walk = ProfilerRootData::sRootList; walk; walk = walk->mNextRoot)
|
for(ProfilerRootData *walk = ProfilerRootData::sRootList; walk; walk = walk->mNextRoot)
|
||||||
{
|
{
|
||||||
walk->mFirstProfilerData = 0;
|
walk->mFirstProfilerData = 0;
|
||||||
|
|
@ -256,7 +262,7 @@ ProfilerRootData::ProfilerRootData(const char *name)
|
||||||
for(ProfilerRootData *walk = sRootList; walk; walk = walk->mNextRoot)
|
for(ProfilerRootData *walk = sRootList; walk; walk = walk->mNextRoot)
|
||||||
if(!dStrcmp(walk->mName, name))
|
if(!dStrcmp(walk->mName, name))
|
||||||
AssertFatal( false, avar( "Duplicate profile name: %s", name ) );
|
AssertFatal( false, avar( "Duplicate profile name: %s", name ) );
|
||||||
|
|
||||||
mName = name;
|
mName = name;
|
||||||
mNameHash = _StringTable::hashString(name);
|
mNameHash = _StringTable::hashString(name);
|
||||||
mNextRoot = sRootList;
|
mNextRoot = sRootList;
|
||||||
|
|
@ -283,7 +289,7 @@ void Profiler::validate()
|
||||||
if(!wk)
|
if(!wk)
|
||||||
Platform::debugBreak();
|
Platform::debugBreak();
|
||||||
for(wk = dp->mParent->mChildHash[walk->mNameHash & (ProfilerData::HashTableSize - 1)] ;
|
for(wk = dp->mParent->mChildHash[walk->mNameHash & (ProfilerData::HashTableSize - 1)] ;
|
||||||
wk; wk = wk->mNextHash)
|
wk; wk = wk->mNextHash)
|
||||||
if(wk == dp)
|
if(wk == dp)
|
||||||
break;
|
break;
|
||||||
if(!wk)
|
if(!wk)
|
||||||
|
|
@ -300,7 +306,7 @@ const char * Profiler::getProfilePath()
|
||||||
if( !ThreadManager::isMainThread() )
|
if( !ThreadManager::isMainThread() )
|
||||||
return "[non-main thread]";
|
return "[non-main thread]";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return (mEnabled && mCurrentProfilerData) ? mCurrentProfilerData->mPath : "na";
|
return (mEnabled && mCurrentProfilerData) ? mCurrentProfilerData->mPath : "na";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -312,14 +318,14 @@ const char * Profiler::constructProfilePath(ProfilerData * pd)
|
||||||
{
|
{
|
||||||
const bool saveEnable = gProfiler->mEnabled;
|
const bool saveEnable = gProfiler->mEnabled;
|
||||||
gProfiler->mEnabled = false;
|
gProfiler->mEnabled = false;
|
||||||
|
|
||||||
const char * connector = " -> ";
|
const char * connector = " -> ";
|
||||||
U32 len = dStrlen(pd->mParent->mPath);
|
U32 len = dStrlen(pd->mParent->mPath);
|
||||||
if (!len)
|
if (!len)
|
||||||
connector = "";
|
connector = "";
|
||||||
len += dStrlen(connector);
|
len += dStrlen(connector);
|
||||||
len += dStrlen(pd->mRoot->mName);
|
len += dStrlen(pd->mRoot->mName);
|
||||||
|
|
||||||
U32 mark = FrameAllocator::getWaterMark();
|
U32 mark = FrameAllocator::getWaterMark();
|
||||||
char * buf = (char*)FrameAllocator::alloc(len+1);
|
char * buf = (char*)FrameAllocator::alloc(len+1);
|
||||||
dStrcpy(buf,pd->mParent->mPath);
|
dStrcpy(buf,pd->mParent->mPath);
|
||||||
|
|
@ -342,25 +348,25 @@ void Profiler::hashPush(ProfilerRootData *root)
|
||||||
if( !ThreadManager::isMainThread() )
|
if( !ThreadManager::isMainThread() )
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mStackDepth++;
|
mStackDepth++;
|
||||||
PROFILER_DEBUG_PUSH_NODE(root->mName);
|
PROFILER_DEBUG_PUSH_NODE(root->mName);
|
||||||
AssertFatal(mStackDepth <= mMaxStackDepth,
|
AssertFatal(mStackDepth <= mMaxStackDepth,
|
||||||
"Stack overflow in profiler. You may have mismatched PROFILE_START and PROFILE_ENDs");
|
"Stack overflow in profiler. You may have mismatched PROFILE_START and PROFILE_ENDs");
|
||||||
if(!mEnabled)
|
if(!mEnabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ProfilerData *nextProfiler = NULL;
|
ProfilerData *nextProfiler = NULL;
|
||||||
if(!root->mEnabled || mCurrentProfilerData->mRoot == root)
|
if(!root->mEnabled || mCurrentProfilerData->mRoot == root)
|
||||||
{
|
{
|
||||||
mCurrentProfilerData->mSubDepth++;
|
mCurrentProfilerData->mSubDepth++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mCurrentProfilerData->mLastSeenProfiler &&
|
if(mCurrentProfilerData->mLastSeenProfiler &&
|
||||||
mCurrentProfilerData->mLastSeenProfiler->mRoot == root)
|
mCurrentProfilerData->mLastSeenProfiler->mRoot == root)
|
||||||
nextProfiler = mCurrentProfilerData->mLastSeenProfiler;
|
nextProfiler = mCurrentProfilerData->mLastSeenProfiler;
|
||||||
|
|
||||||
if(!nextProfiler)
|
if(!nextProfiler)
|
||||||
{
|
{
|
||||||
// first see if it's in the hash table...
|
// first see if it's in the hash table...
|
||||||
|
|
@ -377,17 +383,17 @@ void Profiler::hashPush(ProfilerRootData *root)
|
||||||
nextProfiler = (ProfilerData *) malloc(sizeof(ProfilerData));
|
nextProfiler = (ProfilerData *) malloc(sizeof(ProfilerData));
|
||||||
for(U32 i = 0; i < ProfilerData::HashTableSize; i++)
|
for(U32 i = 0; i < ProfilerData::HashTableSize; i++)
|
||||||
nextProfiler->mChildHash[i] = 0;
|
nextProfiler->mChildHash[i] = 0;
|
||||||
|
|
||||||
nextProfiler->mRoot = root;
|
nextProfiler->mRoot = root;
|
||||||
nextProfiler->mNextForRoot = root->mFirstProfilerData;
|
nextProfiler->mNextForRoot = root->mFirstProfilerData;
|
||||||
root->mFirstProfilerData = nextProfiler;
|
root->mFirstProfilerData = nextProfiler;
|
||||||
|
|
||||||
nextProfiler->mNextProfilerData = mProfileList;
|
nextProfiler->mNextProfilerData = mProfileList;
|
||||||
mProfileList = nextProfiler;
|
mProfileList = nextProfiler;
|
||||||
|
|
||||||
nextProfiler->mNextHash = mCurrentProfilerData->mChildHash[index];
|
nextProfiler->mNextHash = mCurrentProfilerData->mChildHash[index];
|
||||||
mCurrentProfilerData->mChildHash[index] = nextProfiler;
|
mCurrentProfilerData->mChildHash[index] = nextProfiler;
|
||||||
|
|
||||||
nextProfiler->mParent = mCurrentProfilerData;
|
nextProfiler->mParent = mCurrentProfilerData;
|
||||||
nextProfiler->mNextSibling = mCurrentProfilerData->mFirstChild;
|
nextProfiler->mNextSibling = mCurrentProfilerData->mFirstChild;
|
||||||
mCurrentProfilerData->mFirstChild = nextProfiler;
|
mCurrentProfilerData->mFirstChild = nextProfiler;
|
||||||
|
|
@ -437,7 +443,7 @@ void Profiler::hashPop(ProfilerRootData *expected)
|
||||||
if( !ThreadManager::isMainThread() )
|
if( !ThreadManager::isMainThread() )
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mStackDepth--;
|
mStackDepth--;
|
||||||
PROFILER_DEBUG_POP_NODE();
|
PROFILER_DEBUG_POP_NODE();
|
||||||
AssertFatal(mStackDepth >= 0, "Stack underflow in profiler. You may have mismatched PROFILE_START and PROFILE_ENDs");
|
AssertFatal(mStackDepth >= 0, "Stack underflow in profiler. You may have mismatched PROFILE_START and PROFILE_ENDs");
|
||||||
|
|
@ -453,15 +459,15 @@ void Profiler::hashPop(ProfilerRootData *expected)
|
||||||
{
|
{
|
||||||
AssertISV(expected == mCurrentProfilerData->mRoot, "Profiler::hashPop - didn't get expected ProfilerRoot!");
|
AssertISV(expected == mCurrentProfilerData->mRoot, "Profiler::hashPop - didn't get expected ProfilerRoot!");
|
||||||
}
|
}
|
||||||
|
|
||||||
F64 fElapsed = endHighResolutionTimer(mCurrentProfilerData->mStartTime);
|
F64 fElapsed = endHighResolutionTimer(mCurrentProfilerData->mStartTime);
|
||||||
|
|
||||||
mCurrentProfilerData->mTotalTime += fElapsed;
|
mCurrentProfilerData->mTotalTime += fElapsed;
|
||||||
mCurrentProfilerData->mParent->mSubTime += fElapsed; // mark it in the parent as well...
|
mCurrentProfilerData->mParent->mSubTime += fElapsed; // mark it in the parent as well...
|
||||||
mCurrentProfilerData->mRoot->mTotalTime += fElapsed;
|
mCurrentProfilerData->mRoot->mTotalTime += fElapsed;
|
||||||
if(mCurrentProfilerData->mParent->mRoot)
|
if(mCurrentProfilerData->mParent->mRoot)
|
||||||
mCurrentProfilerData->mParent->mRoot->mSubTime += fElapsed; // mark it in the parent as well...
|
mCurrentProfilerData->mParent->mRoot->mSubTime += fElapsed; // mark it in the parent as well...
|
||||||
|
|
||||||
mCurrentProfilerData = mCurrentProfilerData->mParent;
|
mCurrentProfilerData = mCurrentProfilerData->mParent;
|
||||||
}
|
}
|
||||||
if(mStackDepth == 0)
|
if(mStackDepth == 0)
|
||||||
|
|
@ -474,13 +480,13 @@ void Profiler::hashPop(ProfilerRootData *expected)
|
||||||
}
|
}
|
||||||
if(!mEnabled && mNextEnable)
|
if(!mEnabled && mNextEnable)
|
||||||
startHighResolutionTimer(mCurrentProfilerData->mStartTime);
|
startHighResolutionTimer(mCurrentProfilerData->mStartTime);
|
||||||
|
|
||||||
#if defined(TORQUE_OS_WIN)
|
#if defined(TORQUE_OS_WIN)
|
||||||
// The high performance counters under win32 are unreliable when running on multiple
|
// The high performance counters under win32 are unreliable when running on multiple
|
||||||
// processors. When the profiler is enabled, we restrict Torque to a single processor.
|
// processors. When the profiler is enabled, we restrict Torque to a single processor.
|
||||||
if(mNextEnable != mEnabled)
|
if(mNextEnable != mEnabled)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(mNextEnable)
|
if(mNextEnable)
|
||||||
{
|
{
|
||||||
Con::warnf("Warning: forcing the Torque profiler thread to run only on cpu 1.");
|
Con::warnf("Warning: forcing the Torque profiler thread to run only on cpu 1.");
|
||||||
|
|
@ -496,7 +502,7 @@ void Profiler::hashPop(ProfilerRootData *expected)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mEnabled = mNextEnable;
|
mEnabled = mNextEnable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -514,15 +520,15 @@ static void profilerDataDumpRecurse(ProfilerData *data, char *buffer, U32 buffer
|
||||||
{
|
{
|
||||||
// dump out this one:
|
// dump out this one:
|
||||||
Con::printf("%7.3f %7.3f %8d %s%s",
|
Con::printf("%7.3f %7.3f %8d %s%s",
|
||||||
100 * data->mTotalTime / totalTime,
|
100 * data->mTotalTime / totalTime,
|
||||||
100 * (data->mTotalTime - data->mSubTime) / totalTime,
|
100 * (data->mTotalTime - data->mSubTime) / totalTime,
|
||||||
data->mInvokeCount,
|
data->mInvokeCount,
|
||||||
buffer,
|
buffer,
|
||||||
data->mRoot ? data->mRoot->mName : "ROOT" );
|
data->mRoot ? data->mRoot->mName : "ROOT" );
|
||||||
data->mTotalTime = 0;
|
data->mTotalTime = 0;
|
||||||
data->mSubTime = 0;
|
data->mSubTime = 0;
|
||||||
data->mInvokeCount = 0;
|
data->mInvokeCount = 0;
|
||||||
|
|
||||||
buffer[bufferLen] = ' ';
|
buffer[bufferLen] = ' ';
|
||||||
buffer[bufferLen+1] = ' ';
|
buffer[bufferLen+1] = ' ';
|
||||||
buffer[bufferLen+2] = 0;
|
buffer[bufferLen+2] = 0;
|
||||||
|
|
@ -552,16 +558,16 @@ static void profilerDataDumpRecurseFile(ProfilerData *data, char *buffer, U32 bu
|
||||||
{
|
{
|
||||||
char pbuffer[256];
|
char pbuffer[256];
|
||||||
dSprintf(pbuffer, 255, "%7.3f %7.3f %8d %s%s\n",
|
dSprintf(pbuffer, 255, "%7.3f %7.3f %8d %s%s\n",
|
||||||
100 * data->mTotalTime / totalTime,
|
100 * data->mTotalTime / totalTime,
|
||||||
100 * (data->mTotalTime - data->mSubTime) / totalTime,
|
100 * (data->mTotalTime - data->mSubTime) / totalTime,
|
||||||
data->mInvokeCount,
|
data->mInvokeCount,
|
||||||
buffer,
|
buffer,
|
||||||
data->mRoot ? data->mRoot->mName : "ROOT" );
|
data->mRoot ? data->mRoot->mName : "ROOT" );
|
||||||
fws.write(dStrlen(pbuffer), pbuffer);
|
fws.write(dStrlen(pbuffer), pbuffer);
|
||||||
data->mTotalTime = 0;
|
data->mTotalTime = 0;
|
||||||
data->mSubTime = 0;
|
data->mSubTime = 0;
|
||||||
data->mInvokeCount = 0;
|
data->mInvokeCount = 0;
|
||||||
|
|
||||||
buffer[bufferLen] = ' ';
|
buffer[bufferLen] = ' ';
|
||||||
buffer[bufferLen+1] = ' ';
|
buffer[bufferLen+1] = ' ';
|
||||||
buffer[bufferLen+2] = 0;
|
buffer[bufferLen+2] = 0;
|
||||||
|
|
@ -593,7 +599,7 @@ void Profiler::dump()
|
||||||
mEnabled = false;
|
mEnabled = false;
|
||||||
mStackDepth++;
|
mStackDepth++;
|
||||||
// may have some profiled calls... gotta turn em off.
|
// may have some profiled calls... gotta turn em off.
|
||||||
|
|
||||||
Vector<ProfilerRootData *> rootVector;
|
Vector<ProfilerRootData *> rootVector;
|
||||||
F64 totalTime = 0;
|
F64 totalTime = 0;
|
||||||
for(ProfilerRootData *walk = ProfilerRootData::sRootList; walk; walk = walk->mNextRoot)
|
for(ProfilerRootData *walk = ProfilerRootData::sRootList; walk; walk = walk->mNextRoot)
|
||||||
|
|
@ -602,8 +608,8 @@ void Profiler::dump()
|
||||||
rootVector.push_back(walk);
|
rootVector.push_back(walk);
|
||||||
}
|
}
|
||||||
dQsort((void *) &rootVector[0], rootVector.size(), sizeof(ProfilerRootData *), rootDataCompare);
|
dQsort((void *) &rootVector[0], rootVector.size(), sizeof(ProfilerRootData *), rootDataCompare);
|
||||||
|
|
||||||
|
|
||||||
if (mDumpToConsole == true)
|
if (mDumpToConsole == true)
|
||||||
{
|
{
|
||||||
Con::printf("Profiler Data Dump:");
|
Con::printf("Profiler Data Dump:");
|
||||||
|
|
@ -612,10 +618,10 @@ void Profiler::dump()
|
||||||
for(U32 i = 0; i < rootVector.size(); i++)
|
for(U32 i = 0; i < rootVector.size(); i++)
|
||||||
{
|
{
|
||||||
Con::printf("%7.3f %7.3f %8d %s",
|
Con::printf("%7.3f %7.3f %8d %s",
|
||||||
100 * (rootVector[i]->mTotalTime - rootVector[i]->mSubTime) / totalTime,
|
100 * (rootVector[i]->mTotalTime - rootVector[i]->mSubTime) / totalTime,
|
||||||
100 * rootVector[i]->mTotalTime / totalTime,
|
100 * rootVector[i]->mTotalTime / totalTime,
|
||||||
rootVector[i]->mTotalInvokeCount,
|
rootVector[i]->mTotalInvokeCount,
|
||||||
rootVector[i]->mName);
|
rootVector[i]->mName);
|
||||||
rootVector[i]->mTotalInvokeCount = 0;
|
rootVector[i]->mTotalInvokeCount = 0;
|
||||||
rootVector[i]->mTotalTime = 0;
|
rootVector[i]->mTotalTime = 0;
|
||||||
rootVector[i]->mSubTime = 0;
|
rootVector[i]->mSubTime = 0;
|
||||||
|
|
@ -623,9 +629,9 @@ void Profiler::dump()
|
||||||
Con::printf("");
|
Con::printf("");
|
||||||
Con::printf("Ordered by stack trace total time -");
|
Con::printf("Ordered by stack trace total time -");
|
||||||
Con::printf("%% Time %% NSTime Invoke # Name");
|
Con::printf("%% Time %% NSTime Invoke # Name");
|
||||||
|
|
||||||
mCurrentProfilerData->mTotalTime = endHighResolutionTimer(mCurrentProfilerData->mStartTime);
|
mCurrentProfilerData->mTotalTime = endHighResolutionTimer(mCurrentProfilerData->mStartTime);
|
||||||
|
|
||||||
char depthBuffer[MaxStackDepth * 2 + 1];
|
char depthBuffer[MaxStackDepth * 2 + 1];
|
||||||
depthBuffer[0] = 0;
|
depthBuffer[0] = 0;
|
||||||
profilerDataDumpRecurse(mCurrentProfilerData, depthBuffer, 0, totalTime);
|
profilerDataDumpRecurse(mCurrentProfilerData, depthBuffer, 0, totalTime);
|
||||||
|
|
@ -637,44 +643,44 @@ void Profiler::dump()
|
||||||
FileStream fws;
|
FileStream fws;
|
||||||
bool success = fws.open(mDumpFileName, Torque::FS::File::Write);
|
bool success = fws.open(mDumpFileName, Torque::FS::File::Write);
|
||||||
AssertFatal(success, "Cannot write profile dump to specified file!");
|
AssertFatal(success, "Cannot write profile dump to specified file!");
|
||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
|
|
||||||
dStrcpy(buffer, "Profiler Data Dump:\n");
|
dStrcpy(buffer, "Profiler Data Dump:\n");
|
||||||
|
fws.write(dStrlen(buffer), buffer);
|
||||||
|
dStrcpy(buffer, "Ordered by non-sub total time -\n");
|
||||||
|
fws.write(dStrlen(buffer), buffer);
|
||||||
|
dStrcpy(buffer, "%%NSTime %% Time Invoke # Name\n");
|
||||||
|
fws.write(dStrlen(buffer), buffer);
|
||||||
|
|
||||||
|
for(U32 i = 0; i < rootVector.size(); i++)
|
||||||
|
{
|
||||||
|
dSprintf(buffer, 1023, "%7.3f %7.3f %8d %s\n",
|
||||||
|
100 * (rootVector[i]->mTotalTime - rootVector[i]->mSubTime) / totalTime,
|
||||||
|
100 * rootVector[i]->mTotalTime / totalTime,
|
||||||
|
rootVector[i]->mTotalInvokeCount,
|
||||||
|
rootVector[i]->mName);
|
||||||
fws.write(dStrlen(buffer), buffer);
|
fws.write(dStrlen(buffer), buffer);
|
||||||
dStrcpy(buffer, "Ordered by non-sub total time -\n");
|
|
||||||
fws.write(dStrlen(buffer), buffer);
|
rootVector[i]->mTotalInvokeCount = 0;
|
||||||
dStrcpy(buffer, "%%NSTime %% Time Invoke # Name\n");
|
rootVector[i]->mTotalTime = 0;
|
||||||
fws.write(dStrlen(buffer), buffer);
|
rootVector[i]->mSubTime = 0;
|
||||||
|
}
|
||||||
for(U32 i = 0; i < rootVector.size(); i++)
|
dStrcpy(buffer, "\nOrdered by non-sub total time -\n");
|
||||||
{
|
fws.write(dStrlen(buffer), buffer);
|
||||||
dSprintf(buffer, 1023, "%7.3f %7.3f %8d %s\n",
|
dStrcpy(buffer, "%%NSTime %% Time Invoke # Name\n");
|
||||||
100 * (rootVector[i]->mTotalTime - rootVector[i]->mSubTime) / totalTime,
|
fws.write(dStrlen(buffer), buffer);
|
||||||
100 * rootVector[i]->mTotalTime / totalTime,
|
|
||||||
rootVector[i]->mTotalInvokeCount,
|
|
||||||
rootVector[i]->mName);
|
|
||||||
fws.write(dStrlen(buffer), buffer);
|
|
||||||
|
|
||||||
rootVector[i]->mTotalInvokeCount = 0;
|
|
||||||
rootVector[i]->mTotalTime = 0;
|
|
||||||
rootVector[i]->mSubTime = 0;
|
|
||||||
}
|
|
||||||
dStrcpy(buffer, "\nOrdered by non-sub total time -\n");
|
|
||||||
fws.write(dStrlen(buffer), buffer);
|
|
||||||
dStrcpy(buffer, "%%NSTime %% Time Invoke # Name\n");
|
|
||||||
fws.write(dStrlen(buffer), buffer);
|
|
||||||
|
|
||||||
mCurrentProfilerData->mTotalTime = endHighResolutionTimer(mCurrentProfilerData->mStartTime);
|
mCurrentProfilerData->mTotalTime = endHighResolutionTimer(mCurrentProfilerData->mStartTime);
|
||||||
|
|
||||||
char depthBuffer[MaxStackDepth * 2 + 1];
|
char depthBuffer[MaxStackDepth * 2 + 1];
|
||||||
depthBuffer[0] = 0;
|
depthBuffer[0] = 0;
|
||||||
profilerDataDumpRecurseFile(mCurrentProfilerData, depthBuffer, 0, totalTime, fws);
|
profilerDataDumpRecurseFile(mCurrentProfilerData, depthBuffer, 0, totalTime, fws);
|
||||||
mEnabled = enableSave;
|
mEnabled = enableSave;
|
||||||
mStackDepth--;
|
mStackDepth--;
|
||||||
|
|
||||||
fws.close();
|
fws.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
mDumpToConsole = false;
|
mDumpToConsole = false;
|
||||||
mDumpToFile = false;
|
mDumpToFile = false;
|
||||||
mDumpFileName[0] = '\0';
|
mDumpFileName[0] = '\0';
|
||||||
|
|
@ -709,13 +715,13 @@ void Profiler::enableMarker(const char *marker, bool enable)
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
DefineEngineFunction( profilerMarkerEnable, void, ( const char* markerName, bool enable ), ( true ),
|
DefineEngineFunction( profilerMarkerEnable, void, ( const char* markerName, bool enable ), ( true ),
|
||||||
"@brief Enable or disable a specific profile.\n\n"
|
"@brief Enable or disable a specific profile.\n\n"
|
||||||
"@param enable Optional paramater to enable or disable the profile.\n"
|
"@param enable Optional paramater to enable or disable the profile.\n"
|
||||||
"@param markerName Name of a specific marker to enable or disable.\n"
|
"@param markerName Name of a specific marker to enable or disable.\n"
|
||||||
"@note Calling this function will first call profilerReset(), clearing all data from profiler. "
|
"@note Calling this function will first call profilerReset(), clearing all data from profiler. "
|
||||||
"All profile markers are enabled by default.\n\n"
|
"All profile markers are enabled by default.\n\n"
|
||||||
"@ingroup Debugging")
|
"@ingroup Debugging")
|
||||||
{
|
{
|
||||||
if( gProfiler )
|
if( gProfiler )
|
||||||
gProfiler->enableMarker( markerName, enable );
|
gProfiler->enableMarker( markerName, enable );
|
||||||
|
|
@ -724,37 +730,37 @@ DefineEngineFunction( profilerMarkerEnable, void, ( const char* markerName, bool
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
DefineEngineFunction( profilerEnable, void, ( bool enable ),,
|
DefineEngineFunction( profilerEnable, void, ( bool enable ),,
|
||||||
"@brief Enables or disables the profiler.\n\n"
|
"@brief Enables or disables the profiler.\n\n"
|
||||||
"Data is only gathered while the profiler is enabled.\n\n"
|
"Data is only gathered while the profiler is enabled.\n\n"
|
||||||
"@note Profiler is not available in shipping builds.\n"
|
"@note Profiler is not available in shipping builds.\n"
|
||||||
"T3D has predefined profiling areas surrounded by markers, "
|
"T3D has predefined profiling areas surrounded by markers, "
|
||||||
"but you may need to define additional markers (in C++) around areas you wish to profile,"
|
"but you may need to define additional markers (in C++) around areas you wish to profile,"
|
||||||
" by using the PROFILE_START( markerName ); and PROFILE_END(); macros.\n\n"
|
" by using the PROFILE_START( markerName ); and PROFILE_END(); macros.\n\n"
|
||||||
"@ingroup Debugging\n" )
|
"@ingroup Debugging\n" )
|
||||||
{
|
{
|
||||||
if(gProfiler)
|
if(gProfiler)
|
||||||
gProfiler->enable(enable);
|
gProfiler->enable(enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
DefineEngineFunction(profilerDump, void, (),,
|
DefineEngineFunction(profilerDump, void, (),,
|
||||||
"@brief Dumps current profiling stats to the console window.\n\n"
|
"@brief Dumps current profiling stats to the console window.\n\n"
|
||||||
"@note Markers disabled with profilerMarkerEnable() will be skipped over. "
|
"@note Markers disabled with profilerMarkerEnable() will be skipped over. "
|
||||||
"If the profiler is currently running, it will be disabled.\n"
|
"If the profiler is currently running, it will be disabled.\n"
|
||||||
"@ingroup Debugging")
|
"@ingroup Debugging")
|
||||||
{
|
{
|
||||||
if(gProfiler)
|
if(gProfiler)
|
||||||
gProfiler->dumpToConsole();
|
gProfiler->dumpToConsole();
|
||||||
}
|
}
|
||||||
|
|
||||||
DefineEngineFunction( profilerDumpToFile, void, ( const char* fileName ),,
|
DefineEngineFunction( profilerDumpToFile, void, ( const char* fileName ),,
|
||||||
"@brief Dumps current profiling stats to a file.\n\n"
|
"@brief Dumps current profiling stats to a file.\n\n"
|
||||||
"@note If the profiler is currently running, it will be disabled.\n"
|
"@note If the profiler is currently running, it will be disabled.\n"
|
||||||
"@param fileName Name and path of file to save profiling stats to. Must use forward slashes (/). "
|
"@param fileName Name and path of file to save profiling stats to. Must use forward slashes (/). "
|
||||||
"Will attempt to create the file if it does not already exist.\n"
|
"Will attempt to create the file if it does not already exist.\n"
|
||||||
"@tsexample\n"
|
"@tsexample\n"
|
||||||
"profilerDumpToFile( \"C:/Torque/log1.txt\" );\n"
|
"profilerDumpToFile( \"C:/Torque/log1.txt\" );\n"
|
||||||
"@endtsexample\n\n"
|
"@endtsexample\n\n"
|
||||||
"@ingroup Debugging" )
|
"@ingroup Debugging" )
|
||||||
{
|
{
|
||||||
if(gProfiler)
|
if(gProfiler)
|
||||||
gProfiler->dumpToFile(fileName);
|
gProfiler->dumpToFile(fileName);
|
||||||
|
|
@ -762,9 +768,9 @@ DefineEngineFunction( profilerDumpToFile, void, ( const char* fileName ),,
|
||||||
|
|
||||||
DefineEngineFunction( profilerReset, void, (),,
|
DefineEngineFunction( profilerReset, void, (),,
|
||||||
"@brief Resets the profiler, clearing it of all its data.\n\n"
|
"@brief Resets the profiler, clearing it of all its data.\n\n"
|
||||||
"If the profiler is currently running, it will first be disabled. "
|
"If the profiler is currently running, it will first be disabled. "
|
||||||
"All markers will retain their current enabled/disabled status.\n\n"
|
"All markers will retain their current enabled/disabled status.\n\n"
|
||||||
"@ingroup Debugging" )
|
"@ingroup Debugging" )
|
||||||
{
|
{
|
||||||
if(gProfiler)
|
if(gProfiler)
|
||||||
gProfiler->reset();
|
gProfiler->reset();
|
||||||
|
|
|
||||||
|
|
@ -76,8 +76,8 @@ TEST(Net, TCPRequest)
|
||||||
handler.mDataReceived = 0;
|
handler.mDataReceived = 0;
|
||||||
|
|
||||||
// Hook into the signals.
|
// Hook into the signals.
|
||||||
Net::smConnectionNotify ->notify(&handler, &TcpHandle::notify);
|
Net::smConnectionNotify .notify(&handler, &TcpHandle::notify);
|
||||||
Net::smConnectionReceive->notify(&handler, &TcpHandle::receive);
|
Net::smConnectionReceive.notify(&handler, &TcpHandle::receive);
|
||||||
|
|
||||||
// Open a TCP connection to garagegames.com
|
// Open a TCP connection to garagegames.com
|
||||||
handler.mSocket = Net::openConnectTo("72.246.107.193:80");
|
handler.mSocket = Net::openConnectTo("72.246.107.193:80");
|
||||||
|
|
@ -85,8 +85,8 @@ TEST(Net, TCPRequest)
|
||||||
while(Process::processEvents() && (Platform::getRealMilliseconds() < limit) ) {}
|
while(Process::processEvents() && (Platform::getRealMilliseconds() < limit) ) {}
|
||||||
|
|
||||||
// Unhook from the signals.
|
// Unhook from the signals.
|
||||||
Net::smConnectionNotify ->remove(&handler, &TcpHandle::notify);
|
Net::smConnectionNotify .remove(&handler, &TcpHandle::notify);
|
||||||
Net::smConnectionReceive->remove(&handler, &TcpHandle::receive);
|
Net::smConnectionReceive.remove(&handler, &TcpHandle::receive);
|
||||||
|
|
||||||
EXPECT_GT(handler.mDataReceived, 0)
|
EXPECT_GT(handler.mDataReceived, 0)
|
||||||
<< "Didn't get any data back!";
|
<< "Didn't get any data back!";
|
||||||
|
|
@ -139,8 +139,8 @@ struct JournalHandle
|
||||||
mDataReceived = 0;
|
mDataReceived = 0;
|
||||||
|
|
||||||
// Hook into the signals.
|
// Hook into the signals.
|
||||||
Net::smConnectionNotify ->notify(this, &JournalHandle::notify);
|
Net::smConnectionNotify .notify(this, &JournalHandle::notify);
|
||||||
Net::smConnectionReceive->notify(this, &JournalHandle::receive);
|
Net::smConnectionReceive.notify(this, &JournalHandle::receive);
|
||||||
|
|
||||||
// Open a TCP connection to garagegames.com
|
// Open a TCP connection to garagegames.com
|
||||||
mSocket = Net::openConnectTo("72.246.107.193:80");
|
mSocket = Net::openConnectTo("72.246.107.193:80");
|
||||||
|
|
@ -149,8 +149,8 @@ struct JournalHandle
|
||||||
while(Process::processEvents()) {}
|
while(Process::processEvents()) {}
|
||||||
|
|
||||||
// Unhook from the signals.
|
// Unhook from the signals.
|
||||||
Net::smConnectionNotify ->remove(this, &JournalHandle::notify);
|
Net::smConnectionNotify .remove(this, &JournalHandle::notify);
|
||||||
Net::smConnectionReceive->remove(this, &JournalHandle::receive);
|
Net::smConnectionReceive.remove(this, &JournalHandle::receive);
|
||||||
|
|
||||||
EXPECT_GT(mDataReceived, 0)
|
EXPECT_GT(mDataReceived, 0)
|
||||||
<< "Didn't get any data back!";
|
<< "Didn't get any data back!";
|
||||||
|
|
|
||||||
|
|
@ -68,46 +68,54 @@ bool dFileTouch(const char *path)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
bool dPathCopy(const char* source, const char* dest, bool nooverwrite)
|
bool dPathCopy(const char* source, const char* dest, bool nooverwrite)
|
||||||
{
|
{
|
||||||
NSFileManager *manager = [NSFileManager defaultManager];
|
if(source == NULL || dest == NULL)
|
||||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
|
||||||
|
|
||||||
NSString *nsource = [[NSString stringWithUTF8String:source] stringByStandardizingPath];
|
|
||||||
NSString *ndest = [[NSString stringWithUTF8String:dest] stringByStandardizingPath];
|
|
||||||
NSString *ndestFolder = [ndest stringByDeletingLastPathComponent];
|
|
||||||
|
|
||||||
if(! [manager fileExistsAtPath:nsource])
|
|
||||||
{
|
|
||||||
Con::errorf("dPathCopy: no file exists at %s",source);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if( [manager fileExistsAtPath:ndest] )
|
@autoreleasepool {
|
||||||
{
|
NSFileManager *manager = [NSFileManager defaultManager];
|
||||||
if(nooverwrite)
|
|
||||||
|
NSString *nsource = [manager stringWithFileSystemRepresentation:source length:dStrlen(source)];
|
||||||
|
NSString *ndest = [manager stringWithFileSystemRepresentation:dest length:dStrlen(dest)];
|
||||||
|
NSString *ndestFolder = [ndest stringByDeletingLastPathComponent];
|
||||||
|
|
||||||
|
if(! [manager fileExistsAtPath:nsource])
|
||||||
{
|
{
|
||||||
Con::errorf("dPathCopy: file already exists at %s",dest);
|
Con::errorf("dPathCopy: no file exists at %s",source);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Con::warnf("Deleting files at path: %s", dest);
|
|
||||||
bool deleted = [manager removeFileAtPath:ndest handler:nil];
|
if( [manager fileExistsAtPath:ndest] )
|
||||||
if(!deleted)
|
|
||||||
{
|
{
|
||||||
Con::errorf("Copy failed! Could not delete files at path: %s", dest);
|
if(nooverwrite)
|
||||||
return false;
|
{
|
||||||
|
Con::errorf("dPathCopy: file already exists at %s",dest);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Con::warnf("Deleting files at path: %s", dest);
|
||||||
|
if(![manager removeItemAtPath:ndest error:nil] || [manager fileExistsAtPath:ndest])
|
||||||
|
{
|
||||||
|
Con::errorf("Copy failed! Could not delete files at path: %s", dest);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if([manager fileExistsAtPath:ndestFolder] == NO)
|
||||||
|
{
|
||||||
|
ndestFolder = [ndestFolder stringByAppendingString:@"/"]; // createpath requires a trailing slash
|
||||||
|
Platform::createPath([ndestFolder UTF8String]);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ret = [manager copyItemAtPath:nsource toPath:ndest error:nil];
|
||||||
|
// n.b.: The "success" semantics don't guarantee a copy actually took place, so we'll verify
|
||||||
|
// because this is surprising behavior for a method called copy.
|
||||||
|
if( ![manager fileExistsAtPath:ndest] )
|
||||||
|
{
|
||||||
|
Con::warnf("The filemanager returned success, but the file was not copied. Something strange is happening");
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if([manager fileExistsAtPath:ndestFolder] == NO)
|
|
||||||
{
|
|
||||||
ndestFolder = [ndestFolder stringByAppendingString:@"/"]; // createpath requires a trailing slash
|
|
||||||
Platform::createPath([ndestFolder UTF8String]);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ret = [manager copyPath:nsource toPath:ndest handler:nil];
|
|
||||||
|
|
||||||
[pool release];
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
@ -117,25 +125,35 @@ bool dFileRename(const char *source, const char *dest)
|
||||||
if(source == NULL || dest == NULL)
|
if(source == NULL || dest == NULL)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
NSFileManager *manager = [NSFileManager defaultManager];
|
@autoreleasepool {
|
||||||
|
NSFileManager *manager = [NSFileManager defaultManager];
|
||||||
NSString *nsource = [manager stringWithFileSystemRepresentation:source length:dStrlen(source)];
|
|
||||||
NSString *ndest = [manager stringWithFileSystemRepresentation:dest length:dStrlen(dest)];
|
NSString *nsource = [manager stringWithFileSystemRepresentation:source length:dStrlen(source)];
|
||||||
|
NSString *ndest = [manager stringWithFileSystemRepresentation:dest length:dStrlen(dest)];
|
||||||
if(! [manager fileExistsAtPath:nsource])
|
|
||||||
{
|
if(! [manager fileExistsAtPath:nsource])
|
||||||
Con::errorf("dFileRename: no file exists at %s",source);
|
{
|
||||||
return false;
|
Con::errorf("dFileRename: no file exists at %s",source);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( [manager fileExistsAtPath:ndest] )
|
||||||
|
{
|
||||||
|
Con::warnf("dFileRename: Deleting files at path: %s", dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ret = [manager moveItemAtPath:nsource toPath:ndest error:nil];
|
||||||
|
// n.b.: The "success" semantics don't guarantee a move actually took place, so we'll verify
|
||||||
|
// because this is surprising behavior for a method called rename.
|
||||||
|
|
||||||
|
if( ![manager fileExistsAtPath:ndest] )
|
||||||
|
{
|
||||||
|
Con::warnf("The filemanager returned success, but the file was not moved. Something strange is happening");
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( [manager fileExistsAtPath:ndest] )
|
|
||||||
{
|
|
||||||
Con::warnf("dFileRename: Deleting files at path: %s", dest);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ret = [manager movePath:nsource toPath:ndest handler:nil];
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
@ -722,9 +740,9 @@ bool Platform::isSubDirectory(const char *pathParent, const char *pathSub)
|
||||||
inline bool isGoodDirectory(dirent* entry)
|
inline bool isGoodDirectory(dirent* entry)
|
||||||
{
|
{
|
||||||
return (entry->d_type == DT_DIR // is a dir
|
return (entry->d_type == DT_DIR // is a dir
|
||||||
&& dStrcmp(entry->d_name,".") != 0 // not here
|
&& dStrcmp(entry->d_name,".") != 0 // not here
|
||||||
&& dStrcmp(entry->d_name,"..") != 0 // not parent
|
&& dStrcmp(entry->d_name,"..") != 0 // not parent
|
||||||
&& !Platform::isExcludedDirectory(entry->d_name)); // not excluded
|
&& !Platform::isExcludedDirectory(entry->d_name)); // not excluded
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
@ -856,7 +874,7 @@ static bool recurseDumpDirectories(const char *basePath, const char *subPath, Ve
|
||||||
if ( isDir )
|
if ( isDir )
|
||||||
{
|
{
|
||||||
if (dStrcmp(d->d_name, ".") == 0 ||
|
if (dStrcmp(d->d_name, ".") == 0 ||
|
||||||
dStrcmp(d->d_name, "..") == 0)
|
dStrcmp(d->d_name, "..") == 0)
|
||||||
continue;
|
continue;
|
||||||
if (Platform::isExcludedDirectory(d->d_name))
|
if (Platform::isExcludedDirectory(d->d_name))
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -869,8 +887,8 @@ static bool recurseDumpDirectories(const char *basePath, const char *subPath, Ve
|
||||||
dSprintf(child, 1024, "%s/%s", subPath, d->d_name);
|
dSprintf(child, 1024, "%s/%s", subPath, d->d_name);
|
||||||
if (currentDepth < recurseDepth || recurseDepth == -1 )
|
if (currentDepth < recurseDepth || recurseDepth == -1 )
|
||||||
recurseDumpDirectories(basePath, child, directoryVector,
|
recurseDumpDirectories(basePath, child, directoryVector,
|
||||||
currentDepth + 1, recurseDepth,
|
currentDepth + 1, recurseDepth,
|
||||||
noBasePath);
|
noBasePath);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -881,8 +899,8 @@ static bool recurseDumpDirectories(const char *basePath, const char *subPath, Ve
|
||||||
dSprintf(child, 1024, "/%s", d->d_name);
|
dSprintf(child, 1024, "/%s", d->d_name);
|
||||||
if (currentDepth < recurseDepth || recurseDepth == -1)
|
if (currentDepth < recurseDepth || recurseDepth == -1)
|
||||||
recurseDumpDirectories(basePath, child, directoryVector,
|
recurseDumpDirectories(basePath, child, directoryVector,
|
||||||
currentDepth + 1, recurseDepth,
|
currentDepth + 1, recurseDepth,
|
||||||
noBasePath);
|
noBasePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue