LMMS
Loading...
Searching...
No Matches
juce_ContentSharer.cpp
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
12
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
15
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
18
19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21 DISCLAIMED.
22
23 ==============================================================================
24*/
25
26namespace juce
27{
28
29#if JUCE_CONTENT_SHARING
30//==============================================================================
31class ContentSharer::PrepareImagesThread : private Thread
32{
33public:
34 PrepareImagesThread (ContentSharer& cs, const Array<Image>& imagesToUse,
35 ImageFileFormat* imageFileFormatToUse)
36 : Thread ("ContentSharer::PrepareImagesThread"),
37 owner (cs),
38 images (imagesToUse),
39 imageFileFormat (imageFileFormatToUse == nullptr ? new PNGImageFormat()
40 : imageFileFormatToUse),
41 extension (imageFileFormat->getFormatName().toLowerCase())
42 {
43 startThread();
44 }
45
46 ~PrepareImagesThread() override
47 {
48 signalThreadShouldExit();
49 waitForThreadToExit (10000);
50 }
51
52private:
53 void run() override
54 {
55 for (const auto& image : images)
56 {
57 if (threadShouldExit())
58 return;
59
60 File tempFile = File::createTempFile (extension);
61
62 if (! tempFile.create().wasOk())
63 break;
64
65 std::unique_ptr<FileOutputStream> outputStream (tempFile.createOutputStream());
66
67 if (outputStream == nullptr)
68 break;
69
70 if (imageFileFormat->writeImageToStream (image, *outputStream))
71 owner.temporaryFiles.add (tempFile);
72 }
73
74 finish();
75 }
76
77 void finish()
78 {
79 MessageManager::callAsync ([this]() { owner.filesToSharePrepared(); });
80 }
81
82 ContentSharer& owner;
83 const Array<Image> images;
84 std::unique_ptr<ImageFileFormat> imageFileFormat;
85 String extension;
86};
87
88//==============================================================================
89class ContentSharer::PrepareDataThread : private Thread
90{
91public:
92 PrepareDataThread (ContentSharer& cs, const MemoryBlock& mb)
93 : Thread ("ContentSharer::PrepareDataThread"),
94 owner (cs),
95 data (mb)
96 {
97 startThread();
98 }
99
100 ~PrepareDataThread() override
101 {
102 signalThreadShouldExit();
103 waitForThreadToExit (10000);
104 }
105
106private:
107 void run() override
108 {
109 File tempFile = File::createTempFile ("data");
110
111 if (tempFile.create().wasOk())
112 {
113 if (auto outputStream = std::unique_ptr<FileOutputStream> (tempFile.createOutputStream()))
114 {
115 size_t pos = 0;
116 size_t totalSize = data.getSize();
117
118 while (pos < totalSize)
119 {
120 if (threadShouldExit())
121 return;
122
123 size_t numToWrite = std::min ((size_t) 8192, totalSize - pos);
124
125 outputStream->write (data.begin() + pos, numToWrite);
126
127 pos += numToWrite;
128 }
129
130 owner.temporaryFiles.add (tempFile);
131 }
132 }
133
134 finish();
135 }
136
137 void finish()
138 {
139 MessageManager::callAsync ([this]() { owner.filesToSharePrepared(); });
140 }
141
142 ContentSharer& owner;
143 const MemoryBlock data;
144};
145#endif
146
147//==============================================================================
148JUCE_IMPLEMENT_SINGLETON (ContentSharer)
149
151ContentSharer::~ContentSharer() { clearSingletonInstance(); }
152
154 std::function<void (bool, const String&)> callbackToUse)
155{
156 #if JUCE_CONTENT_SHARING
157 startNewShare (callbackToUse);
158 pimpl->shareFiles (files);
159 #else
161
162 // Content sharing is not available on this platform!
164
165 if (callbackToUse)
166 callbackToUse (false, "Content sharing is not available on this platform!");
167 #endif
168}
169
170#if JUCE_CONTENT_SHARING
171void ContentSharer::startNewShare (std::function<void (bool, const String&)> callbackToUse)
172{
173 // You should not start another sharing operation before the previous one is finished.
174 // Forcibly stopping a previous sharing operation is rarely a good idea!
175 jassert (pimpl == nullptr);
176 pimpl.reset();
177
178 prepareDataThread = nullptr;
179 prepareImagesThread = nullptr;
180
181 deleteTemporaryFiles();
182
183 // You need to pass a valid callback.
184 jassert (callbackToUse);
185 callback = std::move (callbackToUse);
186
187 pimpl.reset (createPimpl());
188}
189#endif
190
192 std::function<void (bool, const String&)> callbackToUse)
193{
194 #if JUCE_CONTENT_SHARING
195 startNewShare (callbackToUse);
196 pimpl->shareText (text);
197 #else
199
200 // Content sharing is not available on this platform!
202
203 if (callbackToUse)
204 callbackToUse (false, "Content sharing is not available on this platform!");
205 #endif
206}
207
209 std::function<void (bool, const String&)> callbackToUse,
210 ImageFileFormat* imageFileFormatToUse)
211{
212 #if JUCE_CONTENT_SHARING
213 startNewShare (callbackToUse);
214 prepareImagesThread.reset (new PrepareImagesThread (*this, images, imageFileFormatToUse));
215 #else
216 ignoreUnused (images, imageFileFormatToUse);
217
218 // Content sharing is not available on this platform!
220
221 if (callbackToUse)
222 callbackToUse (false, "Content sharing is not available on this platform!");
223 #endif
224}
225
226#if JUCE_CONTENT_SHARING
227void ContentSharer::filesToSharePrepared()
228{
229 Array<URL> urls;
230
231 for (const auto& tempFile : temporaryFiles)
232 urls.add (URL (tempFile));
233
234 prepareImagesThread = nullptr;
235 prepareDataThread = nullptr;
236
237 pimpl->shareFiles (urls);
238}
239#endif
240
242 std::function<void (bool, const String&)> callbackToUse)
243{
244 #if JUCE_CONTENT_SHARING
245 startNewShare (callbackToUse);
246 prepareDataThread.reset (new PrepareDataThread (*this, mb));
247 #else
248 ignoreUnused (mb);
249
250 if (callbackToUse)
251 callbackToUse (false, "Content sharing not available on this platform!");
252 #endif
253}
254
255void ContentSharer::sharingFinished (bool succeeded, const String& errorDescription)
256{
258
259 std::function<void (bool, String)> cb;
260 std::swap (cb, callback);
261
262 String error (errorDescription);
263
264 #if JUCE_CONTENT_SHARING
265 pimpl.reset();
266 #endif
267
268 if (cb)
269 cb (succeeded, error);
270}
271
273{
274 for (auto& f : temporaryFiles)
275 f.deleteFile();
276
277 temporaryFiles.clear();
278}
279
280} // namespace juce
#define nullptr
Definition DistrhoDefines.h:75
static void run(LV2_Handle instance, uint32_t n_samples)
Definition bindings_test_plugin.c:112
static File createTempFile(StringRef fileNameEnding)
Definition File.cpp:953
Result create() const
Definition File.cpp:494
FileOutputStream * createOutputStream(size_t bufferSize=0x8000) const
Definition File.cpp:743
bool wasOk() const noexcept
Definition Result.cpp:68
Definition juce_Array.h:56
void add(const ElementType &newElement)
Definition juce_Array.h:418
void shareText(const String &text, std::function< void(bool, const String &)> callback)
Definition juce_ContentSharer.cpp:191
void shareData(const MemoryBlock &mb, std::function< void(bool, const String &)> callback)
Definition juce_ContentSharer.cpp:241
std::function< void(bool, String)> callback
Definition juce_ContentSharer.h:110
~ContentSharer()
Definition juce_ContentSharer.cpp:151
Array< File > temporaryFiles
Definition juce_ContentSharer.h:108
void deleteTemporaryFiles()
Definition juce_ContentSharer.cpp:272
ContentSharer()
Definition juce_ContentSharer.cpp:150
void shareImages(const Array< Image > &images, std::function< void(bool, const String &)> callback, ImageFileFormat *imageFileFormatToUse=nullptr)
Definition juce_ContentSharer.cpp:208
void sharingFinished(bool, const String &)
Definition juce_ContentSharer.cpp:255
void shareFiles(const Array< URL > &files, std::function< void(bool, const String &)> callback)
Definition juce_ContentSharer.cpp:153
Definition juce_ImageFileFormat.h:42
Definition juce_MemoryBlock.h:33
Definition juce_String.h:53
Definition juce_URL.h:38
unsigned f
Definition inflate.c:1572
JSAMPIMAGE data
Definition jpeglib.h:945
#define jassert(expression)
#define jassertfalse
#define JUCE_IMPLEMENT_SINGLETON(Classname)
Definition juce_Singleton.h:201
static char ** files
Definition misc.c:28
Definition carla_juce.cpp:31
void ignoreUnused(Types &&...) noexcept
Definition juce_MathsFunctions.h:333
const char * text
Definition swell-functions.h:167
RECT const char void(* callback)(const char *droppath))) SWELL_API_DEFINE(BOOL
Definition swell-functions.h:1004
int error
Definition extract.c:1038
#define void
Definition unzip.h:396