Krotos Modules 3
Loading...
Searching...
No Matches
FactoryAssetsWatcher.cpp
Go to the documentation of this file.
2
3#include <openssl/evp.h>
4#include <openssl/err.h>
5
6namespace krotos
7{
8
9FactoryAssetsWatcher::FactoryAssetsWatcher(const File& dirToWatch) : m_directory(dirToWatch)
10{
11 thread.addTimeSliceClient(this);
12 thread.startThread();
13}
14
16{
17 // Signal thread to exit first so removeTimeSliceClient can return asap.
18 thread.signalThreadShouldExit();
19 thread.notify();
20
21 // Calling stopThread before removeTimeSliceClient can result in a deadlock if the timeout expires and the thread
22 // is killed whilst it's still executing. This is because removeTimeSliceClient doesn't return until the thread
23 // finishes whatever it's doing. If it's killed, the lock is never released and the call will never return. By
24 // signalling the thread to exit first, it should return at the next possible opportunity.
25 thread.removeTimeSliceClient(this);
26
27 bool threadExitedSafely = thread.stopThread(2000);
28 if (!threadExitedSafely)
29 {
30 jassertfalse;
31 }
32}
33
35{
36 // scan and load all valid UCS files to a file array
37 m_filesArray.clear();
39
40 // load embeddings file and load all file names into a StringArray
42 switch (m_assetsStatus)
43 {
45 return removeFileFromEmbeddings(file);
46 }
48 return addFileToEmbeddings(file);
49 }
51 return initEmbeddings(file);
52 }
53 default: {
55 return false;
56 }
57 }
58}
59
60void FactoryAssetsWatcher::getAllFiles(const File& directory, Array<File>& fileArray)
61{
62 std::set<String> fileNames;
63 for (DirectoryEntry entry : RangedDirectoryIterator(directory, true, "*.kaf;*.wav;*.KAF;*.WAV"))
64 {
65 auto file = entry.getFile();
66 auto name = file.getFileNameWithoutExtension();
67 auto catID = name.upToFirstOccurrenceOf("_", false, false);
68 catID = (catID == "AMBROOM") ? "AMBRoom" : catID; // a fix for basement preset assets
69 catID = (catID == "AMBUrb") ? "AMBUrbn" : catID; // a fix for skatepark preset assets
70 auto valid = m_textToAssetsSharedInstance.textToAssets->isUCSValid(catID);
71 // only process valid UCS files
72 if (valid)
73 {
74 // only process unique files
75 if (!fileNames.count(name))
76 {
77 fileNames.insert(name);
78 fileArray.add(file);
79 }
80 }
81 }
82}
83
85{
86 String dirModificationDate = m_directory.getLastModificationTime().toString(true, true);
87
88 String lastRecordedModificationDate;
89
90 File textEmbeddingsStatusFile = m_textToAssetsSharedInstance.textToAssets->createFilePath(ttfStatusFileName);
91
92 File ggmlDataFile = File(utils::StringsIntoPath(AssetManager::getPluginDirectory().getFullPathName(),
93 "ttpResources", modelFileName));
94
95 if (ggmlDataFile.existsAsFile() == false)
96 {
97 return 5000;
98 }
99
100 // trigger ttp update if there is no status file
101 if (textEmbeddingsStatusFile.exists() == false)
102 {
103 textEmbeddingsStatusFile.create();
104
105 // set process to init
107
108 // dir mod date
109 m_dirModificationDate = dirModificationDate;
110
111 // dir size init
113
114 // process
115 bool success = handleContentUpdate();
116
117 if (success)
118 {
119 DynamicObject::Ptr ttfStatus(new DynamicObject());
120
121 ttfStatus->setProperty(ttfStatusDateProperty, var(m_dirModificationDate));
122 ttfStatus->setProperty(ttfStatusSizeProperty, var(String(m_dirSize)));
123
124 FileOutputStream stream(textEmbeddingsStatusFile);
125 if (stream.openedOk())
126 {
127 stream.setPosition(0);
128 stream.truncate();
129 JSON::writeToStream(stream, ttfStatus.get());
130 }
131 }
132 else
133 {
134 DBG("ttf embeddings update aborted");
135 textEmbeddingsStatusFile.deleteFile();
136 }
137 }
138 else
139 {
140 // parse ttp status file
141 auto ttfStatusJSON = JSON::parse(textEmbeddingsStatusFile);
142
143 // get date modified
144 m_dirModificationDate = ttfStatusJSON.getProperty(Identifier(ttfStatusDateProperty), String()).toString();
145
146 // get previous dir size
147 m_dirSize = static_cast<int64>(ttfStatusJSON.getProperty(Identifier(ttfStatusSizeProperty), String(0)));
148
149 // get embeddings file
150 File embeddingsFile = m_textToAssetsSharedInstance.textToAssets->createFilePath(ttfEmbeddingsFileName);
151
152 // if it differs or if embeddings file does not exist (deleted probably) trigger ttp update
153 if ((dirModificationDate != m_dirModificationDate || embeddingsFile.exists() == false) &&
154 !thread.threadShouldExit())
155 {
156 m_dirModificationDate = dirModificationDate;
157 int64 dirSize = getTotalFolderSize(m_directory);
158
159 if (dirSize < m_dirSize)
160 {
162 }
163 else if (dirSize > m_dirSize)
164 {
166 }
167 else
168 {
170 }
171 m_dirSize = dirSize;
172
173 bool success = handleContentUpdate();
174
175 if (success)
176 {
177 DynamicObject::Ptr ttfStatus(new DynamicObject());
178
179 ttfStatus->setProperty(ttfStatusDateProperty, var(m_dirModificationDate));
180 ttfStatus->setProperty(ttfStatusSizeProperty, var(String(m_dirSize)));
181
182 FileOutputStream stream(textEmbeddingsStatusFile);
183 if (stream.openedOk())
184 {
185 stream.setPosition(0);
186 stream.truncate();
187 JSON::writeToStream(stream, ttfStatus.get());
188 }
189 }
190 }
191 }
192 return 5000;
193}
194
195int64 FactoryAssetsWatcher::getTotalFolderSize(const juce::File& folder)
196{
197 jassert(folder.isDirectory());
198 int64 totalSize = 0;
199 for (const auto& entry : juce::RangedDirectoryIterator(folder, true))
200 {
201 totalSize += entry.getFileSize();
202 }
203 return totalSize;
204}
205
207{
208 m_filesToProcess.clear();
209 m_filesWithEmbeddings.clear();
210
211 if (file.existsAsFile())
212 {
213 auto json = JSON::parse(file);
214 var result = json.getProperty(Identifier(fileEmbeddingsIdentifier), 0);
215 for (int i = 0; i < result.size(); ++i)
216 {
217 if (thread.threadShouldExit())
218 {
219 return false;
220 }
221 auto fileName = File(result[i].getProperty(fileNameIdentifier, 0)).getFileName();
222 m_filesWithEmbeddings.add(fileName);
223 }
224 }
225
227
229
230 // calculate embeddings for new presets
232}
233
235{
236 if (file.existsAsFile())
237 {
238 Array<int> indicesToRemove;
239 auto json = JSON::parse(file);
240 var result = json.getProperty(Identifier(fileEmbeddingsIdentifier), 0);
241
242 Array<String> onlyFileNamesArrayFromFileSystem;
243 for (const auto& f : m_filesArray)
244 {
245 onlyFileNamesArrayFromFileSystem.add(f.getFileName());
246 }
247
248 auto embeddingsArray = *result.getArray();
249
250 for (int i = 0; i < embeddingsArray.size(); ++i)
251 {
252 auto fileFullPath =
253 File(embeddingsArray[i].getProperty(fileNameIdentifier, 0).toString()).getFullPathName();
254 auto fileName = File(fileFullPath).getFileName();
255
256 // remove from embeddings
257 if (onlyFileNamesArrayFromFileSystem.contains(fileName) == false)
258 {
259 indicesToRemove.add(i);
260 }
261 }
262
263 // process only if there is files to remove from embeddings
264 if (indicesToRemove.size() > 0)
265 {
266 // sort indices to descending order to avoid shifts
267 std::sort(indicesToRemove.begin(), indicesToRemove.end(), std::greater<int>());
268
269 for (auto& i : indicesToRemove)
270 {
271 embeddingsArray.remove(i);
272 }
273
274 // Update the JSON object with the modified embeddings array
275 DynamicObject::Ptr updatedJson(json.getDynamicObject());
276
277 updatedJson->removeProperty(Identifier(fileEmbeddingsIdentifier));
278 updatedJson->setProperty(Identifier(fileEmbeddingsIdentifier), var(embeddingsArray));
279
280 FileOutputStream jsonOutStream(file);
281 jsonOutStream.setPosition(0);
282 jsonOutStream.truncate();
283 JSON::writeToStream(jsonOutStream, updatedJson.get());
284
286 return true;
287 }
289 return false;
290 }
292 return false;
293}
294
296{
297 m_filesToProcess.clear();
298 m_filesWithEmbeddings.clear();
299
300 if (file.existsAsFile())
301 {
302 auto json = JSON::parse(file);
303 var result = json.getProperty(Identifier(fileEmbeddingsIdentifier), 0);
304 for (int i = 0; i < result.size(); ++i)
305 {
306 if (thread.threadShouldExit())
307 {
308 return false;
309 }
310 auto fileName = File(result[i].getProperty(fileNameIdentifier, 0)).getFileName();
311 m_filesWithEmbeddings.add(fileName);
312 }
313 }
314
316
318
319 // calculate embeddings for new presets
321}
322
324{
325 for (File& file : m_filesArray)
326 {
327 if (thread.threadShouldExit())
328 {
329 return;
330 }
331
332 // file is new and has no embeddings, so ..
333 String filenameToCheck = file.getFileName();
334 if (m_filesWithEmbeddings.contains(filenameToCheck) == false)
335 {
336 m_filesToProcess.add(file);
337 }
338 }
339}
340} // namespace krotos
static File getPluginDirectory()
Definition AssetManager.cpp:392
bool handleContentUpdate()
handles content update and triggers ttp embeddings calculation accordingly
Definition FactoryAssetsWatcher.cpp:34
int64 m_dirSize
Definition FactoryAssetsWatcher.h:42
FactoryAssetsWatcher(const File &dirToWatch)
Definition FactoryAssetsWatcher.cpp:9
TextToAssetsShared m_textToAssetsSharedInstance
Definition FactoryAssetsWatcher.h:50
Array< File > m_filesArray
Definition FactoryAssetsWatcher.h:53
File m_directory
Definition FactoryAssetsWatcher.h:47
String m_dirModificationDate
Definition FactoryAssetsWatcher.h:39
AssetsStatus m_assetsStatus
Definition FactoryAssetsWatcher.h:64
TimeSliceThread thread
Definition FactoryAssetsWatcher.h:33
Array< File > m_filesToProcess
Definition FactoryAssetsWatcher.h:59
~FactoryAssetsWatcher() override
Definition FactoryAssetsWatcher.cpp:15
bool removeFileFromEmbeddings(const File &file)
removes file(s) from embeddigs
Definition FactoryAssetsWatcher.cpp:234
StringArray m_filesWithEmbeddings
Definition FactoryAssetsWatcher.h:56
bool addFileToEmbeddings(const File &file)
adds file(s) to embeddigs
Definition FactoryAssetsWatcher.cpp:206
int64 getTotalFolderSize(const juce::File &folder)
caclulates the folder size recursivelly
Definition FactoryAssetsWatcher.cpp:195
int useTimeSlice() override
timeslice thread checks for modufication dir date and handles it accordingly
Definition FactoryAssetsWatcher.cpp:84
void checkAddFileInEmbeddings()
check if there is available embeddings if not add it to an array that will be processed by TTP module
Definition FactoryAssetsWatcher.cpp:323
void getAllFiles(const File &directory, Array< File > &fileArray)
gets all files under a directory recursivelly
Definition FactoryAssetsWatcher.cpp:60
bool initEmbeddings(const File &file)
inits embeddigs
Definition FactoryAssetsWatcher.cpp:295
SharedResourcePointer< TextToAssets > textToAssets
Definition TextToAssets.h:396
String StringsIntoPath(Args... args)
Joins multiple string arguments into a path string.
Definition helpers.h:25
Definition AirAbsorptionFilter.cpp:2
static const Identifier fileNameIdentifier
Definition TextToAssets.h:13
constexpr char ttfStatusDateProperty[]
Definition TextToAssets.h:8
static const String fileEmbeddingsIdentifier
Definition FactoryAssetsWatcher.h:6
constexpr char ttfEmbeddingsFileName[]
Definition TextToAssets.h:6
@ kAssetsRemoved
Definition TextToAssets.h:30
@ kAssetsAdded
Definition TextToAssets.h:31
@ kAssetsInit
Definition TextToAssets.h:33
@ kAssetsNoChange
Definition TextToAssets.h:32
constexpr char modelFileName[]
Definition SentenceTransformer.h:7
constexpr char ttfStatusFileName[]
Definition TextToAssets.h:7
constexpr char ttfStatusSizeProperty[]
Definition TextToAssets.h:9