add file notification to Mac ticket 514, also change name of class FileInfo to CFileInfo to ease Mac development

This was SVN commit r13821.
This commit is contained in:
stwf 2013-09-10 14:17:04 +00:00
parent d037d97d55
commit b1bd61938e
28 changed files with 352 additions and 65 deletions

View File

@ -279,7 +279,7 @@ public:
m_skeletonHashes.clear(); m_skeletonHashes.clear();
m_skeletonHashes.resize(paths.size()*2); m_skeletonHashes.resize(paths.size()*2);
FileInfo fileInfo; CFileInfo fileInfo;
for (VfsPaths::const_iterator it = paths.begin(); it != paths.end(); ++it) for (VfsPaths::const_iterator it = paths.begin(); it != paths.end(); ++it)
{ {
// This will cause an assertion failure if *it doesn't exist, // This will cause an assertion failure if *it doesn't exist,

View File

@ -55,7 +55,7 @@ struct IArchiveReader
* called for each archive entry. * called for each archive entry.
* @param pathname full pathname of entry; only valid during the callback. * @param pathname full pathname of entry; only valid during the callback.
**/ **/
typedef void (*ArchiveEntryCallback)(const VfsPath& pathname, const FileInfo& fileInfo, PIArchiveFile archiveFile, uintptr_t cbData); typedef void (*ArchiveEntryCallback)(const VfsPath& pathname, const CFileInfo& fileInfo, PIArchiveFile archiveFile, uintptr_t cbData);
virtual Status ReadEntries(ArchiveEntryCallback cb, uintptr_t cbData) = 0; virtual Status ReadEntries(ArchiveEntryCallback cb, uintptr_t cbData) = 0;
}; };

View File

@ -141,7 +141,7 @@ static IdMgr id_mgr;
// optimizations like reading from vfs_tree container directly. // optimizations like reading from vfs_tree container directly.
class FileGatherer class FileGatherer
{ {
static void EntCb(const char* path, const FileInfo* ent, uintptr_t cbData) static void EntCb(const char* path, const CFileInfo* ent, uintptr_t cbData)
{ {
FileNodes* file_nodes = (FileNodes*)cbData; FileNodes* file_nodes = (FileNodes*)cbData;
@ -544,7 +544,7 @@ public:
archive_ext = path_extension(archive_fn); archive_ext = path_extension(archive_fn);
} }
bool operator()(FileInfo& ent) const bool operator()(CFileInfo& ent) const
{ {
// remove if not file // remove if not file
if(ent.IsDirectory) if(ent.IsDirectory)

View File

@ -109,7 +109,7 @@ enum ZipMethod
class LFH class LFH
{ {
public: public:
void Init(const FileInfo& fileInfo, off_t csize, ZipMethod method, u32 checksum, const Path& pathname) void Init(const CFileInfo& fileInfo, off_t csize, ZipMethod method, u32 checksum, const Path& pathname)
{ {
const std::string pathnameUTF8 = utf8_from_wstring(pathname.string()); const std::string pathnameUTF8 = utf8_from_wstring(pathname.string());
const size_t pathnameSize = pathnameUTF8.length(); const size_t pathnameSize = pathnameUTF8.length();
@ -157,7 +157,7 @@ cassert(sizeof(LFH) == 30);
class CDFH class CDFH
{ {
public: public:
void Init(const FileInfo& fileInfo, off_t ofs, off_t csize, ZipMethod method, u32 checksum, const Path& pathname, size_t slack) void Init(const CFileInfo& fileInfo, off_t ofs, off_t csize, ZipMethod method, u32 checksum, const Path& pathname, size_t slack)
{ {
const std::string pathnameUTF8 = utf8_from_wstring(pathname.string()); const std::string pathnameUTF8 = utf8_from_wstring(pathname.string());
const size_t pathnameLength = pathnameUTF8.length(); const size_t pathnameLength = pathnameUTF8.length();
@ -415,7 +415,7 @@ private:
PFile m_file; PFile m_file;
// all relevant LFH/CDFH fields not covered by FileInfo // all relevant LFH/CDFH fields not covered by CFileInfo
mutable off_t m_ofs; mutable off_t m_ofs;
off_t m_csize; off_t m_csize;
u32 m_checksum; u32 m_checksum;
@ -434,7 +434,7 @@ public:
ArchiveReader_Zip(const OsPath& pathname) ArchiveReader_Zip(const OsPath& pathname)
: m_file(new File(pathname, O_RDONLY)) : m_file(new File(pathname, O_RDONLY))
{ {
FileInfo fileInfo; CFileInfo fileInfo;
GetFileInfo(pathname, &fileInfo); GetFileInfo(pathname, &fileInfo);
m_fileSize = fileInfo.Size(); m_fileSize = fileInfo.Size();
const size_t minFileSize = sizeof(LFH)+sizeof(CDFH)+sizeof(ECDR); const size_t minFileSize = sizeof(LFH)+sizeof(CDFH)+sizeof(ECDR);
@ -466,7 +466,7 @@ public:
if(!relativePathname.IsDirectory()) if(!relativePathname.IsDirectory())
{ {
const OsPath name = relativePathname.Filename(); const OsPath name = relativePathname.Filename();
FileInfo fileInfo(name, cdfh->USize(), cdfh->MTime()); CFileInfo fileInfo(name, cdfh->USize(), cdfh->MTime());
shared_ptr<ArchiveFile_Zip> archiveFile(new ArchiveFile_Zip(m_file, cdfh->HeaderOffset(), cdfh->CSize(), cdfh->Checksum(), cdfh->Method())); shared_ptr<ArchiveFile_Zip> archiveFile(new ArchiveFile_Zip(m_file, cdfh->HeaderOffset(), cdfh->CSize(), cdfh->Checksum(), cdfh->Method()));
cb(relativePathname, fileInfo, archiveFile, cbData); cb(relativePathname, fileInfo, archiveFile, cbData);
} }
@ -612,7 +612,7 @@ public:
Status AddFile(const OsPath& pathname, const OsPath& pathnameInArchive) Status AddFile(const OsPath& pathname, const OsPath& pathnameInArchive)
{ {
FileInfo fileInfo; CFileInfo fileInfo;
RETURN_STATUS_IF_ERR(GetFileInfo(pathname, &fileInfo)); RETURN_STATUS_IF_ERR(GetFileInfo(pathname, &fileInfo));
PFile file(new File); PFile file(new File);
@ -623,12 +623,12 @@ public:
Status AddMemory(const u8* data, size_t size, time_t mtime, const OsPath& pathnameInArchive) Status AddMemory(const u8* data, size_t size, time_t mtime, const OsPath& pathnameInArchive)
{ {
FileInfo fileInfo(pathnameInArchive, size, mtime); CFileInfo fileInfo(pathnameInArchive, size, mtime);
return AddFileOrMemory(fileInfo, pathnameInArchive, PFile(), data); return AddFileOrMemory(fileInfo, pathnameInArchive, PFile(), data);
} }
Status AddFileOrMemory(const FileInfo& fileInfo, const OsPath& pathnameInArchive, const PFile& file, const u8* data) Status AddFileOrMemory(const CFileInfo& fileInfo, const OsPath& pathnameInArchive, const PFile& file, const u8* data)
{ {
ENSURE((file && !data) || (data && !file)); ENSURE((file && !data) || (data && !file));

View File

@ -62,7 +62,7 @@ u64 FileSize(const OsPath& pathname)
} }
Status GetFileInfo(const OsPath& pathname, FileInfo* pfileInfo) Status GetFileInfo(const OsPath& pathname, CFileInfo* pPtrInfo)
{ {
errno = 0; errno = 0;
struct stat s; struct stat s;
@ -70,7 +70,7 @@ Status GetFileInfo(const OsPath& pathname, FileInfo* pfileInfo)
if(wstat(pathname, &s) != 0) if(wstat(pathname, &s) != 0)
WARN_RETURN(StatusFromErrno()); WARN_RETURN(StatusFromErrno());
*pfileInfo = FileInfo(pathname.Filename(), s.st_size, s.st_mtime); *pPtrInfo = CFileInfo(pathname.Filename(), s.st_size, s.st_mtime);
return INFO::OK; return INFO::OK;
} }
@ -84,7 +84,7 @@ struct DirDeleter
} }
}; };
Status GetDirectoryEntries(const OsPath& path, FileInfos* files, DirectoryNames* subdirectoryNames) Status GetDirectoryEntries(const OsPath& path, CFileInfos* files, DirectoryNames* subdirectoryNames)
{ {
// open directory // open directory
errno = 0; errno = 0;
@ -123,7 +123,7 @@ Status GetDirectoryEntries(const OsPath& path, FileInfos* files, DirectoryNames*
#endif #endif
if(files && S_ISREG(s.st_mode)) if(files && S_ISREG(s.st_mode))
files->push_back(FileInfo(name, s.st_size, s.st_mtime)); files->push_back(CFileInfo(name, s.st_size, s.st_mtime));
else if(subdirectoryNames && S_ISDIR(s.st_mode) && name != L"." && name != L"..") else if(subdirectoryNames && S_ISDIR(s.st_mode) && name != L"." && name != L"..")
subdirectoryNames->push_back(name); subdirectoryNames->push_back(name);
} }
@ -166,7 +166,7 @@ Status DeleteDirectory(const OsPath& path)
// note: we have to recursively empty the directory before it can // note: we have to recursively empty the directory before it can
// be deleted (required by Windows and POSIX rmdir()). // be deleted (required by Windows and POSIX rmdir()).
FileInfos files; DirectoryNames subdirectoryNames; CFileInfos files; DirectoryNames subdirectoryNames;
RETURN_STATUS_IF_ERR(GetDirectoryEntries(path, &files, &subdirectoryNames)); RETURN_STATUS_IF_ERR(GetDirectoryEntries(path, &files, &subdirectoryNames));
// delete files // delete files

View File

@ -38,14 +38,14 @@ LIB_API u64 FileSize(const OsPath& pathname);
// (bundling size and mtime avoids a second expensive call to stat()) // (bundling size and mtime avoids a second expensive call to stat())
class FileInfo class CFileInfo
{ {
public: public:
FileInfo() CFileInfo()
{ {
} }
FileInfo(const OsPath& name, off_t size, time_t mtime) CFileInfo(const OsPath& name, off_t size, time_t mtime)
: name(name), size(size), mtime(mtime) : name(name), size(size), mtime(mtime)
{ {
} }
@ -71,12 +71,12 @@ private:
time_t mtime; time_t mtime;
}; };
LIB_API Status GetFileInfo(const OsPath& pathname, FileInfo* fileInfo); LIB_API Status GetFileInfo(const OsPath& pathname, CFileInfo* fileInfo);
typedef std::vector<FileInfo> FileInfos; typedef std::vector<CFileInfo> CFileInfos;
typedef std::vector<OsPath> DirectoryNames; typedef std::vector<OsPath> DirectoryNames;
LIB_API Status GetDirectoryEntries(const OsPath& path, FileInfos* files, DirectoryNames* subdirectoryNames); LIB_API Status GetDirectoryEntries(const OsPath& path, CFileInfos* files, DirectoryNames* subdirectoryNames);
// same as boost::filesystem::create_directories, except that mkdir is invoked with // same as boost::filesystem::create_directories, except that mkdir is invoked with
// <mode> instead of 0755. // <mode> instead of 0755.

View File

@ -77,7 +77,7 @@ public:
return INFO::OK; return INFO::OK;
} }
virtual Status GetFileInfo(const VfsPath& pathname, FileInfo* pfileInfo) const virtual Status GetFileInfo(const VfsPath& pathname, CFileInfo* pfileInfo) const
{ {
ScopedLock s; ScopedLock s;
VfsDirectory* directory; VfsFile* file; VfsDirectory* directory; VfsFile* file;
@ -85,7 +85,7 @@ public:
if(!pfileInfo) // just indicate if the file exists without raising warnings. if(!pfileInfo) // just indicate if the file exists without raising warnings.
return ret; return ret;
WARN_RETURN_STATUS_IF_ERR(ret); WARN_RETURN_STATUS_IF_ERR(ret);
*pfileInfo = FileInfo(file->Name(), file->Size(), file->MTime()); *pfileInfo = CFileInfo(file->Name(), file->Size(), file->MTime());
return INFO::OK; return INFO::OK;
} }
@ -98,7 +98,7 @@ public:
return INFO::OK; return INFO::OK;
} }
virtual Status GetDirectoryEntries(const VfsPath& path, FileInfos* fileInfos, DirectoryNames* subdirectoryNames) const virtual Status GetDirectoryEntries(const VfsPath& path, CFileInfos* fileInfos, DirectoryNames* subdirectoryNames) const
{ {
ScopedLock s; ScopedLock s;
VfsDirectory* directory; VfsDirectory* directory;
@ -112,7 +112,7 @@ public:
for(VfsDirectory::VfsFiles::const_iterator it = files.begin(); it != files.end(); ++it) for(VfsDirectory::VfsFiles::const_iterator it = files.begin(); it != files.end(); ++it)
{ {
const VfsFile& file = it->second; const VfsFile& file = it->second;
fileInfos->push_back(FileInfo(file.Name(), file.Size(), file.MTime())); fileInfos->push_back(CFileInfo(file.Name(), file.Size(), file.MTime()));
} }
} }

View File

@ -28,7 +28,7 @@
#ifndef INCLUDED_VFS #ifndef INCLUDED_VFS
#define INCLUDED_VFS #define INCLUDED_VFS
#include "lib/file/file_system.h" // FileInfo #include "lib/file/file_system.h" // CFileInfo
#include "lib/file/vfs/vfs_path.h" #include "lib/file/vfs/vfs_path.h"
namespace ERR namespace ERR
@ -109,7 +109,7 @@ struct IVFS
* *
* @return Status. * @return Status.
**/ **/
virtual Status GetFileInfo(const VfsPath& pathname, FileInfo* pfileInfo) const = 0; virtual Status GetFileInfo(const VfsPath& pathname, CFileInfo* pfileInfo) const = 0;
/** /**
* Retrieve mount priority for a file. * Retrieve mount priority for a file.
@ -132,7 +132,7 @@ struct IVFS
* - we cannot efficiently provide routines for returning files and * - we cannot efficiently provide routines for returning files and
* subdirectories separately due to the underlying POSIX interface. * subdirectories separately due to the underlying POSIX interface.
**/ **/
virtual Status GetDirectoryEntries(const VfsPath& path, FileInfos* fileInfos, DirectoryNames* subdirectoryNames) const = 0; virtual Status GetDirectoryEntries(const VfsPath& path, CFileInfos* fileInfos, DirectoryNames* subdirectoryNames) const = 0;
/** /**
* Create a file with the given contents. * Create a file with the given contents.

View File

@ -41,7 +41,7 @@ static size_t s_numArchivedFiles;
struct CompareFileInfoByName struct CompareFileInfoByName
{ {
bool operator()(const FileInfo& a, const FileInfo& b) bool operator()(const CFileInfo& a, const CFileInfo& b)
{ {
return a.Name() < b.Name(); return a.Name() < b.Name();
} }
@ -64,7 +64,7 @@ public:
s_looseFiles.reserve(10000); s_looseFiles.reserve(10000);
#endif #endif
FileInfos files; files.reserve(500); CFileInfos files; files.reserve(500);
DirectoryNames subdirectoryNames; subdirectoryNames.reserve(50); DirectoryNames subdirectoryNames; subdirectoryNames.reserve(50);
RETURN_STATUS_IF_ERR(GetDirectoryEntries(m_realDirectory->Path(), &files, &subdirectoryNames)); RETURN_STATUS_IF_ERR(GetDirectoryEntries(m_realDirectory->Path(), &files, &subdirectoryNames));
@ -82,7 +82,7 @@ public:
} }
private: private:
void AddFile(const FileInfo& fileInfo) const void AddFile(const CFileInfo& fileInfo) const
{ {
const VfsPath name = fileInfo.Name(); const VfsPath name = fileInfo.Name();
if(name.Extension() == L".DELETED") if(name.Extension() == L".DELETED")
@ -108,7 +108,7 @@ private:
#endif #endif
} }
static void AddArchiveFile(const VfsPath& pathname, const FileInfo& fileInfo, PIArchiveFile archiveFile, uintptr_t cbData) static void AddArchiveFile(const VfsPath& pathname, const CFileInfo& fileInfo, PIArchiveFile archiveFile, uintptr_t cbData)
{ {
PopulateHelper* this_ = (PopulateHelper*)cbData; PopulateHelper* this_ = (PopulateHelper*)cbData;
@ -133,7 +133,7 @@ private:
#endif #endif
} }
Status AddFiles(const FileInfos& files) const Status AddFiles(const CFileInfos& files) const
{ {
const OsPath path(m_realDirectory->Path()); const OsPath path(m_realDirectory->Path());

View File

@ -29,7 +29,7 @@
#include <map> #include <map>
#include "lib/file/file_system.h" // FileInfo #include "lib/file/file_system.h" // CFileInfo
#include "lib/file/common/file_loader.h" // PIFileLoader #include "lib/file/common/file_loader.h" // PIFileLoader
#include "lib/file/common/real_directory.h" // PRealDirectory #include "lib/file/common/real_directory.h" // PRealDirectory
#include "lib/file/vfs/vfs_path.h" #include "lib/file/vfs/vfs_path.h"

View File

@ -39,7 +39,7 @@ namespace vfs {
Status GetPathnames(const PIVFS& fs, const VfsPath& path, const wchar_t* filter, VfsPaths& pathnames) Status GetPathnames(const PIVFS& fs, const VfsPath& path, const wchar_t* filter, VfsPaths& pathnames)
{ {
std::vector<FileInfo> files; std::vector<CFileInfo> files;
RETURN_STATUS_IF_ERR(fs->GetDirectoryEntries(path, &files, 0)); RETURN_STATUS_IF_ERR(fs->GetDirectoryEntries(path, &files, 0));
pathnames.clear(); pathnames.clear();
@ -58,7 +58,7 @@ Status GetPathnames(const PIVFS& fs, const VfsPath& path, const wchar_t* filter,
Status ForEachFile(const PIVFS& fs, const VfsPath& startPath, FileCallback cb, uintptr_t cbData, const wchar_t* pattern, size_t flags) Status ForEachFile(const PIVFS& fs, const VfsPath& startPath, FileCallback cb, uintptr_t cbData, const wchar_t* pattern, size_t flags)
{ {
// (declare here to avoid reallocations) // (declare here to avoid reallocations)
FileInfos files; DirectoryNames subdirectoryNames; CFileInfos files; DirectoryNames subdirectoryNames;
// (a FIFO queue is more efficient than recursion because it uses less // (a FIFO queue is more efficient than recursion because it uses less
// stack space and avoids seeks due to breadth-first traversal.) // stack space and avoids seeks due to breadth-first traversal.)
@ -72,11 +72,11 @@ Status ForEachFile(const PIVFS& fs, const VfsPath& startPath, FileCallback cb, u
for(size_t i = 0; i < files.size(); i++) for(size_t i = 0; i < files.size(); i++)
{ {
const FileInfo fileInfo = files[i]; const CFileInfo fileInfo = files[i];
if(!match_wildcard(fileInfo.Name().string().c_str(), pattern)) if(!match_wildcard(fileInfo.Name().string().c_str(), pattern))
continue; continue;
const VfsPath pathname(path / fileInfo.Name()); // (FileInfo only stores the name) const VfsPath pathname(path / fileInfo.Name()); // (CFileInfo only stores the name)
cb(pathname, fileInfo, cbData); cb(pathname, fileInfo, cbData);
} }
@ -105,7 +105,7 @@ void NextNumberedFilename(const PIVFS& fs, const VfsPath& pathnameFormat, size_t
const VfsPath path = pathnameFormat.Parent()/""; const VfsPath path = pathnameFormat.Parent()/"";
size_t maxNumber = 0; size_t maxNumber = 0;
FileInfos files; CFileInfos files;
fs->GetDirectoryEntries(path, &files, 0); fs->GetDirectoryEntries(path, &files, 0);
for(size_t i = 0; i < files.size(); i++) for(size_t i = 0; i < files.size(); i++)
{ {

View File

@ -37,7 +37,7 @@ extern Status GetPathnames(const PIVFS& fs, const VfsPath& path, const wchar_t*
/** /**
* called for files in a directory. * called for files in a directory.
* *
* @param pathname full pathname (since FileInfo only gives the name). * @param pathname full pathname (since CFileInfo only gives the name).
* @param fileInfo file information * @param fileInfo file information
* @param cbData user-specified context * @param cbData user-specified context
* @return INFO::CONTINUE on success; any other value will immediately * @return INFO::CONTINUE on success; any other value will immediately
@ -46,7 +46,7 @@ extern Status GetPathnames(const PIVFS& fs, const VfsPath& path, const wchar_t*
* CAVEAT: pathname and fileInfo are only valid until the function * CAVEAT: pathname and fileInfo are only valid until the function
* returns! * returns!
**/ **/
typedef Status (*FileCallback)(const VfsPath& pathname, const FileInfo& fileInfo, const uintptr_t cbData); typedef Status (*FileCallback)(const VfsPath& pathname, const CFileInfo& fileInfo, const uintptr_t cbData);
enum DirFlags enum DirFlags
{ {

View File

@ -21,16 +21,182 @@
*/ */
#include "precompiled.h" #include "precompiled.h"
#include "lib/sysdep/dir_watch.h" #include "lib/sysdep/dir_watch.h"
#include "lib/file/file_system.h"
#include "osx_sys_version.h"
// stub implementations #include "lib/os_path.h"
#include "lib/file/file.h"
#include "lib/posix/posix_filesystem.h" // mode_t
Status dir_watch_Add(const OsPath& UNUSED(path), PDirWatch& UNUSED(dirWatch)) #include <CoreFoundation/CoreFoundation.h>
#include <CoreServices/CoreServices.h>
#include "ps/CLogger.h"
FSEventStreamRef g_Stream = NULL;
struct DirWatch
{ {
OsPath path;
int reqnum;
};
typedef std::vector<DirWatch> DirWatchMap;
static DirWatchMap g_Paths;
static DirWatchMap g_RootPaths;
static DirWatchNotifications g_QueuedDirs;
bool CanRunNotifications()
{
int major = 0;
int minor = 0;
int bugfix = 0;
GetSystemVersion( major, minor, bugfix);
if ((major == 10 && minor >= 7) || major >= 11)
return true;
return false;
}
#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
#else
#define kFSEventStreamCreateFlagFileEvents 0x00000010
#define kFSEventStreamEventFlagItemIsFile 0x00010000
#define kFSEventStreamEventFlagItemRemoved 0x00000200
#define kFSEventStreamEventFlagItemRenamed 0x00000800
#define kFSEventStreamEventFlagItemCreated 0x00000100
#define kFSEventStreamEventFlagItemModified 0x00001000
#endif
static void fsevent_callback(
ConstFSEventStreamRef UNUSED(streamRef),
void * UNUSED(clientCallBackInfo),
size_t numEvents,
void *eventPaths,
const FSEventStreamEventFlags eventFlags[],
const FSEventStreamEventId UNUSED(eventIds)[] )
{
unsigned long i;
char **paths = (char **)eventPaths;
for (i=0; i<numEvents; i++)
{
bool isWatched = false;
OsPath eventPath = OsPath(paths[i]);
unsigned long eventType = eventFlags[i];
if ( eventPath.Filename().string().c_str()[0] != '.' )
{
for ( DirWatchMap::iterator it = g_Paths.begin() ; it != g_Paths.end(); ++it)
if ( path_is_subpath( it->path.string().c_str(), eventPath.string().c_str() ) )
isWatched = true;
}
if ( ! isWatched )
return;
OsPath filename = Path( eventPath.string().c_str() );
if ( eventType & kFSEventStreamEventFlagItemIsFile)
{
if ( eventType & kFSEventStreamEventFlagItemRemoved )
g_QueuedDirs.push_back(DirWatchNotification( filename.string().c_str(), DirWatchNotification::Deleted ));
else if ( eventType & kFSEventStreamEventFlagItemRenamed )
g_QueuedDirs.push_back(DirWatchNotification( filename.string().c_str(), DirWatchNotification::Deleted ));
else if ( eventType & kFSEventStreamEventFlagItemCreated )
g_QueuedDirs.push_back(DirWatchNotification( filename.string().c_str(), DirWatchNotification::Created ));
else if ( eventType & kFSEventStreamEventFlagItemModified )
g_QueuedDirs.push_back(DirWatchNotification( filename.string().c_str(), DirWatchNotification::Changed ));
}
}
}
FSEventStreamRef CreateEventStream( DirWatchMap path )
{
if ( ( g_Stream == NULL ) && CanRunNotifications() )
{
CFStringRef* pathLists = (CFStringRef*)malloc( sizeof(CFStringRef*) * path.size() );
int index = 0;
for ( DirWatchMap::iterator it = path.begin() ; it != path.end(); ++it)
{
pathLists[index] = CFStringCreateWithFileSystemRepresentation( NULL, OsString(it->path).c_str());
index++;
}
CFArrayRef pathsToWatch = CFArrayCreate(NULL, (const void **)pathLists, index, NULL);
FSEventStreamContext *callbackInfo = NULL;
FSEventStreamRef stream = FSEventStreamCreate(NULL, &fsevent_callback, callbackInfo, pathsToWatch,
kFSEventStreamEventIdSinceNow, 1.0, kFSEventStreamCreateFlagFileEvents );
CFRelease( pathsToWatch );
free( pathLists );
FSEventStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
if (!FSEventStreamStart(stream))
debug_warn(L"event_loop FSEventStreamStart failed!");
else
return stream;
}
return NULL;
}
void DeleteEventStream()
{
if ( g_Stream != NULL )
{
FSEventStreamStop(g_Stream);
FSEventStreamInvalidate(g_Stream);
FSEventStreamRelease(g_Stream);
g_Stream = NULL;
}
}
Status dir_watch_Add(const OsPath& path, PDirWatch& dirWatch)
{
PDirWatch tmpDirWatch(new DirWatch);
dirWatch.swap(tmpDirWatch);
dirWatch->path = path;
dirWatch->reqnum = 0;
g_Paths.push_back( *dirWatch );
bool alreadyInsideRootPath = false;
for ( DirWatchMap::iterator it = g_RootPaths.begin() ; it != g_RootPaths.end(); ++it)
{
if ( path_is_subpath( path.string().c_str(), it->path.string().c_str() ) )
alreadyInsideRootPath = true;
}
if ( !alreadyInsideRootPath )
{
DeleteEventStream();
g_RootPaths.push_back( *dirWatch );
}
return INFO::OK; return INFO::OK;
} }
Status dir_watch_Poll(DirWatchNotifications& UNUSED(notifications)) Status dir_watch_Poll(DirWatchNotifications& notifications)
{ {
if ( g_Stream == NULL )
{
g_Stream = CreateEventStream( g_RootPaths );
}
else
{
for ( DirWatchNotifications::iterator it = g_QueuedDirs.begin() ; it != g_QueuedDirs.end(); ++it)
notifications.push_back(DirWatchNotification( *it ));
g_QueuedDirs.clear();
}
return INFO::OK; return INFO::OK;
} }

View File

@ -0,0 +1,28 @@
/* Copyright (c) 2013 Wildfire Games
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef OSX_SYS_VERSION_H
#define OSX_SYS_VERSION_H
void GetSystemVersion( int &major, int &minor, int &bugfix );
#endif //OSX_SYS_VERSION_H

View File

@ -0,0 +1,67 @@
/* Copyright (c) 2013 Wildfire Games
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#import <AvailabilityMacros.h> // MAC_OS_X_VERSION_MIN_REQUIRED
#import <Foundation/Foundation.h>
#import <string>
#import "osx_bundle.h"
#define STRINGIZE2(id) # id
#define STRINGIZE(id) STRINGIZE2(id)
// Pass the bundle identifier string as a build option
#ifdef BUNDLE_IDENTIFIER
static const char* BUNDLE_ID_STR = STRINGIZE(BUNDLE_IDENTIFIER);
#else
static const char* BUNDLE_ID_STR = "";
#endif
void GetSystemVersion( int &major, int &minor, int &bugfix )
{
// sensible default
static int mMajor = 10;
static int mMinor = 8;
static int mBugfix = 0;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSString* versionString = [[NSDictionary dictionaryWithContentsOfFile:@"/System/Library/CoreServices/SystemVersion.plist"] objectForKey:@"ProductVersion"];
NSArray* versions = [versionString componentsSeparatedByString:@"."];
check( versions.count >= 2 );
if ( versions.count >= 1 ) {
mMajor = [[versions objectAtIndex:0] integerValue];
}
if ( versions.count >= 2 ) {
mMinor = [[versions objectAtIndex:1] integerValue];
}
if ( versions.count >= 3 ) {
mBugfix = [[versions objectAtIndex:2] integerValue];
}
});
major = mMajor;
minor = mMinor;
bugfix = mBugfix;
}

View File

@ -55,7 +55,7 @@ typedef std::set<Path::String> StringSet;
// same name in the system directory. // same name in the system directory.
static void add_oal_dlls_in_dir(const OsPath& path, StringSet& dlls, VersionList& versionList) static void add_oal_dlls_in_dir(const OsPath& path, StringSet& dlls, VersionList& versionList)
{ {
FileInfos files; CFileInfos files;
(void)GetDirectoryEntries(path, &files, 0); (void)GetDirectoryEntries(path, &files, 0);
for(size_t i = 0; i < files.size(); i++) for(size_t i = 0; i < files.size(); i++)
{ {

View File

@ -173,7 +173,7 @@ void CArchiveBuilder::Build(const OsPath& archive, bool compress)
} }
} }
Status CArchiveBuilder::CollectFileCB(const VfsPath& pathname, const FileInfo& UNUSED(fileInfo), const uintptr_t cbData) Status CArchiveBuilder::CollectFileCB(const VfsPath& pathname, const CFileInfo& UNUSED(fileInfo), const uintptr_t cbData)
{ {
CArchiveBuilder* self = static_cast<CArchiveBuilder*>((void*)cbData); CArchiveBuilder* self = static_cast<CArchiveBuilder*>((void*)cbData);
self->m_Files.push_back(pathname); self->m_Files.push_back(pathname);

View File

@ -57,7 +57,7 @@ public:
void Build(const OsPath& archive, bool compress); void Build(const OsPath& archive, bool compress);
private: private:
static Status CollectFileCB(const VfsPath& pathname, const FileInfo& fileInfo, const uintptr_t cbData); static Status CollectFileCB(const VfsPath& pathname, const CFileInfo& fileInfo, const uintptr_t cbData);
PIVFS m_VFS; PIVFS m_VFS;
std::vector<VfsPath> m_Files; std::vector<VfsPath> m_Files;

View File

@ -95,7 +95,7 @@ bool CCacheLoader::CanUseArchiveCache(const VfsPath& sourcePath, const VfsPath&
// If source file is more recent than the archive cache (i.e. the user has edited it), // If source file is more recent than the archive cache (i.e. the user has edited it),
// don't use the old cache // don't use the old cache
FileInfo sourceInfo, archiveCacheInfo; CFileInfo sourceInfo, archiveCacheInfo;
if (m_VFS->GetFileInfo(sourcePath, &sourceInfo) >= 0 && if (m_VFS->GetFileInfo(sourcePath, &sourceInfo) >= 0 &&
m_VFS->GetFileInfo(archiveCachePath, &archiveCacheInfo) >= 0) m_VFS->GetFileInfo(archiveCachePath, &archiveCacheInfo) >= 0)
{ {
@ -116,7 +116,7 @@ VfsPath CCacheLoader::ArchiveCachePath(const VfsPath& sourcePath)
VfsPath CCacheLoader::LooseCachePath(const VfsPath& sourcePath, const MD5& initialHash, u32 version) VfsPath CCacheLoader::LooseCachePath(const VfsPath& sourcePath, const MD5& initialHash, u32 version)
{ {
FileInfo fileInfo; CFileInfo fileInfo;
if (m_VFS->GetFileInfo(sourcePath, &fileInfo) < 0) if (m_VFS->GetFileInfo(sourcePath, &fileInfo) < 0)
{ {
debug_warn(L"source file disappeared"); // this should never happen debug_warn(L"source file disappeared"); // this should never happen

View File

@ -98,7 +98,7 @@ Status SavedGames::Save(const std::wstring& name, const std::wstring& descriptio
archiveWriter.reset(); // close the file archiveWriter.reset(); // close the file
WriteBuffer buffer; WriteBuffer buffer;
FileInfo tempSaveFile; CFileInfo tempSaveFile;
WARN_RETURN_STATUS_IF_ERR(GetFileInfo(tempSaveFileRealPath, &tempSaveFile)); WARN_RETURN_STATUS_IF_ERR(GetFileInfo(tempSaveFileRealPath, &tempSaveFile));
buffer.Reserve(tempSaveFile.Size()); buffer.Reserve(tempSaveFile.Size());
WARN_RETURN_STATUS_IF_ERR(io::Load(tempSaveFileRealPath, buffer.Data().get(), buffer.Size())); WARN_RETURN_STATUS_IF_ERR(io::Load(tempSaveFileRealPath, buffer.Data().get(), buffer.Size()));
@ -123,12 +123,12 @@ public:
{ {
} }
static void ReadEntryCallback(const VfsPath& pathname, const FileInfo& fileInfo, PIArchiveFile archiveFile, uintptr_t cbData) static void ReadEntryCallback(const VfsPath& pathname, const CFileInfo& fileInfo, PIArchiveFile archiveFile, uintptr_t cbData)
{ {
((CGameLoader*)cbData)->ReadEntry(pathname, fileInfo, archiveFile); ((CGameLoader*)cbData)->ReadEntry(pathname, fileInfo, archiveFile);
} }
void ReadEntry(const VfsPath& pathname, const FileInfo& fileInfo, PIArchiveFile archiveFile) void ReadEntry(const VfsPath& pathname, const CFileInfo& fileInfo, PIArchiveFile archiveFile)
{ {
if (pathname == L"metadata.json" && m_Metadata) if (pathname == L"metadata.json" && m_Metadata)
{ {

View File

@ -66,7 +66,7 @@ struct BuildDirEntListState
}; };
// called for each matching directory entry; add its full pathname to array. // called for each matching directory entry; add its full pathname to array.
static Status BuildDirEntListCB(const VfsPath& pathname, const FileInfo& UNUSED(fileINfo), uintptr_t cbData) static Status BuildDirEntListCB(const VfsPath& pathname, const CFileInfo& UNUSED(fileINfo), uintptr_t cbData)
{ {
BuildDirEntListState* s = (BuildDirEntListState*)cbData; BuildDirEntListState* s = (BuildDirEntListState*)cbData;
@ -140,7 +140,7 @@ JSBool JSI_VFS::GetFileMTime(JSContext* cx, uintN argc, jsval* vp)
if (!ToPrimitive<CStrW> (cx, JS_ARGV(cx, vp)[0], filename)) if (!ToPrimitive<CStrW> (cx, JS_ARGV(cx, vp)[0], filename))
return JS_FALSE; return JS_FALSE;
FileInfo fileInfo; CFileInfo fileInfo;
Status err = g_VFS->GetFileInfo(filename, &fileInfo); Status err = g_VFS->GetFileInfo(filename, &fileInfo);
JS_CHECK_FILE_ERR(err); JS_CHECK_FILE_ERR(err);
@ -161,7 +161,7 @@ JSBool JSI_VFS::GetFileSize(JSContext* cx, uintN argc, jsval* vp)
if (!ToPrimitive<CStrW> (cx, JS_ARGV(cx, vp)[0], filename)) if (!ToPrimitive<CStrW> (cx, JS_ARGV(cx, vp)[0], filename))
return JS_FALSE; return JS_FALSE;
FileInfo fileInfo; CFileInfo fileInfo;
Status err = g_VFS->GetFileInfo(filename, &fileInfo); Status err = g_VFS->GetFileInfo(filename, &fileInfo);
JS_CHECK_FILE_ERR(err); JS_CHECK_FILE_ERR(err);

View File

@ -176,7 +176,7 @@ bool CDebuggingServer::GetSettingSimultaneousThreadBreak()
} }
static Status AddFileResponse(const VfsPath& pathname, const FileInfo& UNUSED(fileInfo), const uintptr_t cbData) static Status AddFileResponse(const VfsPath& pathname, const CFileInfo& UNUSED(fileInfo), const uintptr_t cbData)
{ {
std::vector<std::string>& templates = *(std::vector<std::string>*)cbData; std::vector<std::string>& templates = *(std::vector<std::string>*)cbData;
std::wstring str(pathname.string()); std::wstring str(pathname.string());

View File

@ -429,7 +429,7 @@ void CCmpTemplateManager::ConstructTemplateActor(const std::string& actorName, C
CParamNode::LoadXMLString(out, xml.c_str(), actorNameW.c_str()); CParamNode::LoadXMLString(out, xml.c_str(), actorNameW.c_str());
} }
static Status AddToTemplates(const VfsPath& pathname, const FileInfo& UNUSED(fileInfo), const uintptr_t cbData) static Status AddToTemplates(const VfsPath& pathname, const CFileInfo& UNUSED(fileInfo), const uintptr_t cbData)
{ {
std::vector<std::string>& templates = *(std::vector<std::string>*)cbData; std::vector<std::string>& templates = *(std::vector<std::string>*)cbData;
@ -446,7 +446,7 @@ static Status AddToTemplates(const VfsPath& pathname, const FileInfo& UNUSED(fil
return INFO::OK; return INFO::OK;
} }
static Status AddActorToTemplates(const VfsPath& pathname, const FileInfo& UNUSED(fileInfo), const uintptr_t cbData) static Status AddActorToTemplates(const VfsPath& pathname, const CFileInfo& UNUSED(fileInfo), const uintptr_t cbData)
{ {
std::vector<std::string>& templates = *(std::vector<std::string>*)cbData; std::vector<std::string>& templates = *(std::vector<std::string>*)cbData;

View File

@ -47,7 +47,7 @@ public:
vfs::ForEachFile(g_VFS, L"simulation/ai/", Callback, (uintptr_t)this, L"*.json", vfs::DIR_RECURSIVE); vfs::ForEachFile(g_VFS, L"simulation/ai/", Callback, (uintptr_t)this, L"*.json", vfs::DIR_RECURSIVE);
} }
static Status Callback(const VfsPath& pathname, const FileInfo& UNUSED(fileInfo), const uintptr_t cbData) static Status Callback(const VfsPath& pathname, const CFileInfo& UNUSED(fileInfo), const uintptr_t cbData)
{ {
GetAIsHelper* self = (GetAIsHelper*)cbData; GetAIsHelper* self = (GetAIsHelper*)cbData;

View File

@ -962,7 +962,7 @@ CScriptVal CComponentManager::ReadJSONFile(void* cbdata, std::wstring filePath,
return componentManager->GetScriptInterface().ReadJSONFile(path).get(); return componentManager->GetScriptInterface().ReadJSONFile(path).get();
} }
Status CComponentManager::FindJSONFilesCallback(const VfsPath& pathname, const FileInfo& UNUSED(fileInfo), const uintptr_t cbData) Status CComponentManager::FindJSONFilesCallback(const VfsPath& pathname, const CFileInfo& UNUSED(fileInfo), const uintptr_t cbData)
{ {
FindJSONFilesCallbackData* data = (FindJSONFilesCallbackData*)cbData; FindJSONFilesCallbackData* data = (FindJSONFilesCallbackData*)cbData;

View File

@ -245,7 +245,7 @@ private:
static CScriptVal ReadJSONFile(void *cbdata, std::wstring filePath, std::wstring fileName); static CScriptVal ReadJSONFile(void *cbdata, std::wstring filePath, std::wstring fileName);
// callback function to handle recursively finding files in a directory // callback function to handle recursively finding files in a directory
static Status FindJSONFilesCallback(const VfsPath&, const FileInfo&, const uintptr_t); static Status FindJSONFilesCallback(const VfsPath&, const CFileInfo&, const uintptr_t);
CMessage* ConstructMessage(int mtid, CScriptVal data); CMessage* ConstructMessage(int mtid, CScriptVal data);
void SendGlobalMessage(entity_id_t ent, const CMessage& msg) const; void SendGlobalMessage(entity_id_t ent, const CMessage& msg) const;

View File

@ -20,6 +20,8 @@
#include "ISoundManager.h" #include "ISoundManager.h"
#include "SoundManager.h" #include "SoundManager.h"
#include "ps/Filesystem.h"
#include "soundmanager/data/SoundData.h" #include "soundmanager/data/SoundData.h"
#include "soundmanager/items/CSoundItem.h" #include "soundmanager/items/CSoundItem.h"
#include "soundmanager/items/CBufferItem.h" #include "soundmanager/items/CBufferItem.h"
@ -208,6 +210,7 @@ private:
void ISoundManager::CreateSoundManager() void ISoundManager::CreateSoundManager()
{ {
if ( !g_SoundManager )
g_SoundManager = new CSoundManager(); g_SoundManager = new CSoundManager();
} }
@ -217,7 +220,7 @@ void ISoundManager::SetEnabled(bool doEnable)
{ {
SAFE_DELETE(g_SoundManager); SAFE_DELETE(g_SoundManager);
} }
else if ( ! g_SoundManager && doEnable ) else if ( !g_SoundManager && doEnable )
{ {
ISoundManager::CreateSoundManager(); ISoundManager::CreateSoundManager();
} }
@ -240,6 +243,18 @@ void CSoundManager::al_check(const char* caller, int line)
al_ReportError(err, caller, line); al_ReportError(err, caller, line);
} }
Status CSoundManager::ReloadChangedFiles(const VfsPath& UNUSED(path))
{
// LOGERROR(L"GUI file '%ls' changed - reloading page", path.string().c_str());
return INFO::OK;
}
/*static*/ Status CSoundManager::ReloadChangedFileCB(void* param, const VfsPath& path)
{
return static_cast<CSoundManager*>(param)->ReloadChangedFiles(path);
}
CSoundManager::CSoundManager() CSoundManager::CSoundManager()
{ {
m_CurrentEnvirons = 0; m_CurrentEnvirons = 0;
@ -282,10 +297,14 @@ CSoundManager::CSoundManager()
m_Worker = new CSoundManagerWorker(); m_Worker = new CSoundManagerWorker();
m_Worker->SetEnabled( true ); m_Worker->SetEnabled( true );
} }
RegisterFileReloadFunc(ReloadChangedFileCB, this);
} }
CSoundManager::~CSoundManager() CSoundManager::~CSoundManager()
{ {
UnregisterFileReloadFunc(ReloadChangedFileCB, this);
if (m_Worker ) if (m_Worker )
{ {
AL_CHECK AL_CHECK
@ -649,11 +668,14 @@ void CSoundManager::PlayGroupItem(ISoundItem* anItem, ALfloat groupGain )
void CSoundManager::SetMusicEnabled (bool isEnabled) void CSoundManager::SetMusicEnabled (bool isEnabled)
{ {
LOGERROR(L"entering enabled area", isEnabled);
if (m_CurrentTune && !isEnabled) if (m_CurrentTune && !isEnabled)
{ {
m_CurrentTune->FadeAndDelete(1.00); m_CurrentTune->FadeAndDelete(1.00);
m_CurrentTune = 0L; m_CurrentTune = 0L;
} }
LOGERROR(L"exiting enabled area", isEnabled);
m_MusicEnabled = isEnabled; m_MusicEnabled = isEnabled;
} }

View File

@ -102,6 +102,8 @@ public:
ISoundItem* ItemForData(CSoundData* itemData); ISoundItem* ItemForData(CSoundData* itemData);
ISoundItem* ItemForEntity( entity_id_t source, CSoundData* sndData); ISoundItem* ItemForEntity( entity_id_t source, CSoundData* sndData);
Status ReloadChangedFiles(const VfsPath& path);
void ClearPlayListItems(); void ClearPlayListItems();
void StartPlayList( bool doLoop ); void StartPlayList( bool doLoop );
void AddPlayListItem( const VfsPath* itemPath); void AddPlayListItem( const VfsPath* itemPath);
@ -109,6 +111,8 @@ public:
static void ScriptingInit(); static void ScriptingInit();
static void CreateSoundManager(); static void CreateSoundManager();
static void SetEnabled(bool doEnable); static void SetEnabled(bool doEnable);
static Status ReloadChangedFileCB(void* param, const VfsPath& path);
static void CloseGame(); static void CloseGame();
static void al_ReportError(ALenum err, const char* caller, int line); static void al_ReportError(ALenum err, const char* caller, int line);