-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest.cpp
More file actions
189 lines (147 loc) · 6.2 KB
/
test.cpp
File metadata and controls
189 lines (147 loc) · 6.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#include <node_api.h>
#include "Watcher.h"
#include <string>
#include <thread>
#include <chrono>
#include <iostream>
#include <filesystem>
using namespace std;
struct WatcherData {
FolderWatcher folderWatcher;
napi_ref callbackRef;
napi_env env;
};
struct AsyncContext {
napi_env env;
napi_ref callbackRef;
std::string folderPath;
};
std::vector<std::filesystem::path> GetCurrentFiles(const std::filesystem::path& directory);
void DetectFileChanges(napi_env env, napi_value jsCallback, const std::vector<std::filesystem::path>& oldFiles, const std::vector<std::filesystem::path>& newFiles);
void NotifyFileChange(napi_env env, napi_value jsCallback, const std::filesystem::path& filePath);
static int initializationCount = 0;
void PrintToConsole(napi_env env, const char* message) {
napi_value console;
napi_value global;
napi_value logFunction;
napi_get_global(env, &global);
napi_get_named_property(env, global, "console", &console);
napi_get_named_property(env, console, "log", &logFunction);
napi_value logMessageValue;
napi_create_string_utf8(env, message, NAPI_AUTO_LENGTH, &logMessageValue);
napi_value logArgs[] = { logMessageValue };
napi_call_function(env, console, logFunction, 1, logArgs, nullptr);
}
// Función de trabajo en segundo plano
void NotifyCallbackAsync(napi_env env, void* data) {
AsyncContext* asyncContext = static_cast<AsyncContext*>(data);
std::vector<std::filesystem::path> currentFiles = GetCurrentFiles(asyncContext->folderPath);
while (true) {
std::this_thread::sleep_for(std::chrono::seconds(1));
std::vector<std::filesystem::path> newFiles = GetCurrentFiles(asyncContext->folderPath);
// Llamar a la función de detección de cambios en el hilo principal
DetectFileChanges(asyncContext->env, asyncContext->callbackRef, currentFiles, newFiles);
currentFiles = newFiles;
}
}
// Función de limpieza después del trabajo en segundo plano
void NotifyCallbackAsyncComplete(napi_env env, napi_status status, void* data) {
AsyncContext* asyncContext = static_cast<AsyncContext*>(data);
// Liberar la referencia al callback
napi_delete_reference(env, asyncContext->callbackRef);
// Liberar la memoria de la estructura de contexto
delete asyncContext;
}
// Obtener la lista de archivos en un directorio
std::vector<std::filesystem::path> GetCurrentFiles(const std::filesystem::path& directory) {
std::vector<std::filesystem::path> files;
std::filesystem::directory_iterator iterator(directory);
for (const auto& entry : iterator) {
files.push_back(entry.path());
}
return files;
}
// Detectar cambios entre dos listas de archivos
void DetectFileChanges(napi_env env, napi_vul jsCallbackRef, const std::vector<std::filesystem::path>& oldFiles, const std::vector<std::filesystem::path>& newFiles) {
for (const auto& newFile : newFiles) {
if (std::find(oldFiles.begin(), oldFiles.end(), newFile) == oldFiles.end()) {
// Nuevo archivo
NotifyFileChange(env, jsCallbackRef, newFile);
}
}
for (const auto& oldFile : oldFiles) {
if (std::find(newFiles.begin(), newFiles.end(), oldFile) == newFiles.end()) {
// Archivo eliminado
NotifyFileChange(env, jsCallbackRef, oldFile);
}
}
}
// Notificar un cambio de archivo al callback de JavaScript
void NotifyFileChange(napi_env env, napi_value jsCallbackRef, const std::filesystem::path& filePath) {
napi_value argv[1];
napi_create_string_utf8(env, filePath.filename().string().c_str(), NAPI_AUTO_LENGTH, &argv[0]);
// Llamar a la función de JavaScript con el contexto correcto
napi_call_function(env, nullptr, jsCallbackRef, 1, argv, nullptr);
}
void CallbackFinalizer(napi_env env, void* finalize_data, void* finalize_hint) {
WatcherData* watcherData = static_cast<WatcherData*>(finalize_data);
napi_delete_reference(env, watcherData->callbackRef);
delete watcherData;
}
napi_value StartWatching(napi_env env, napi_callback_info info) {
size_t argc = 1;
napi_value argv[1];
napi_value thisArg;
napi_get_cb_info(env, info, &argc, argv, &thisArg, nullptr);
WatcherData* watcherData;
napi_unwrap(env, thisArg, reinterpret_cast<void**>(&watcherData));
// Obtener la ruta de la carpeta desde el argumento de JavaScript
size_t strLen;
napi_get_value_string_utf8(env, argv[0], nullptr, 0, &strLen);
std::string folderPath(strLen + 1, '\0');
napi_get_value_string_utf8(env, argv[0], &folderPath[0], strLen + 1, nullptr);
// Imprimir la ruta de la carpeta en la consola
cout << folderPath << endl;
// Configurar la ruta de la carpeta en el WatcherData
watcherData->folderWatcher.setFolderPath(folderPath);
// Crear la estructura de contexto para el trabajo en segundo plano
AsyncContext* asyncContext = new AsyncContext{
env,
nullptr,
folderPath
};
// Crear una referencia al callback para mantenerlo vivo
napi_create_reference(env, argv[1], 1, &asyncContext->callbackRef);
// Crear y ejecutar el trabajo en segundo plano
napi_async_work asyncWork;
napi_value workName;
napi_create_string_utf8(env, "NotifyCallbackAsync", NAPI_AUTO_LENGTH, &workName);
napi_create_async_work(
env,
nullptr,
workName,
NotifyCallbackAsync,
NotifyCallbackAsyncComplete,
asyncContext,
&asyncWork
);
napi_queue_async_work(env, asyncWork);
return nullptr;
}
napi_value InitModule(napi_env env, napi_value exports) {
napi_value fn;
napi_create_function(env, "startWatching", NAPI_AUTO_LENGTH, StartWatching, nullptr, &fn);
napi_set_named_property(env, exports, "startWatching", fn);
return exports;
}
napi_value Init(napi_env env, napi_value exports) {
initializationCount++;
// Imprimir el mensaje en la consola de Node.js
std::string logMessage = "Init llamado " + to_string(initializationCount) + " veces.";
PrintToConsole(env, logMessage.c_str());
WatcherData* watcherData = new WatcherData();
watcherData->callbackRef = nullptr;
napi_wrap(env, exports, watcherData, CallbackFinalizer, nullptr, nullptr);
return InitModule(env, exports);
}
NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)