* Copyright 2015, Axel DΓΆrfler, axeld@pinc-software.de.
* Copyright 2025, JΓ©rΓ΄me Duval, jerome.duval@gmail.com.
* Distributed under the terms of the MIT License.
*/
#include "FileWatcher.h"
#include <Application.h>
#include <Autolock.h>
#include <Path.h>
#include <PathMonitor.h>
#include <stdio.h>
class Path;
static BLocker sLocker("file watcher");
static FileWatcher* sWatcher;
FileListener::~FileListener()
{
}
FileWatcher::FileWatcher()
:
BHandler("file watcher")
{
if (be_app->Lock()) {
be_app->AddHandler(this);
watch_node(NULL, B_WATCH_MOUNT, this);
be_app->Unlock();
}
}
FileWatcher::~FileWatcher()
{
if (be_app->Lock()) {
stop_watching(this);
be_app->RemoveHandler(this);
be_app->Unlock();
}
}
void
FileWatcher::AddListener(FileListener* listener)
{
BAutolock lock(sLocker);
fListeners.AddItem(listener);
}
void
FileWatcher::RemoveListener(FileListener* listener)
{
BAutolock lock(sLocker);
fListeners.RemoveItem(listener);
}
int32
FileWatcher::CountListeners() const
{
BAutolock lock(sLocker);
return fListeners.CountItems();
}
void
FileWatcher::MessageReceived(BMessage* message)
{
switch (message->what) {
case B_PATH_MONITOR:
{
int32 opcode = message->GetInt32("opcode", -1);
if (opcode == B_ENTRY_CREATED) {
const char* path;
const char* watchedPath;
if (message->FindString("watched_path", &watchedPath) != B_OK
|| message->FindString("path", &path) != B_OK) {
break;
}
BAutolock lock(sLocker);
for (int32 i = 0; i < fListeners.CountItems(); i++)
fListeners.ItemAt(i)->FileCreated(watchedPath);
}
break;
}
}
}
status_t
FileWatcher::Register(FileListener* listener, BPath& path)
{
BAutolock lock(sLocker);
if (sWatcher == NULL)
sWatcher = new FileWatcher();
status_t status = BPathMonitor::StartWatching(path.Path(),
B_WATCH_FILES_ONLY, sWatcher);
if (status != B_OK)
return status;
sWatcher->AddListener(listener);
return B_OK;
}
void
FileWatcher::Unregister(FileListener* listener, BPath& path)
{
BAutolock lock(sLocker);
BPathMonitor::StopWatching(path.Path(), sWatcher);
sWatcher->RemoveListener(listener);
if (sWatcher->CountListeners() == 0)
delete sWatcher;
}