1 /** @file assetobserver.cpp Utility for observing available assets.
2 *
3 * @authors Copyright (c) 2014-2017 Jaakko Keränen <jaakko.keranen@iki.fi>
4 *
5 * @par License
6 * LGPL: http://www.gnu.org/licenses/lgpl.html
7 *
8 * <small>This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or (at your
11 * option) any later version. This program is distributed in the hope that it
12 * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
14 * General Public License for more details. You should have received a copy of
15 * the GNU Lesser General Public License along with this program; if not, see:
16 * http://www.gnu.org/licenses</small>
17 */
18
19 #include "de/filesys/AssetObserver"
20 #include "de/App"
21 #include "de/FileSystem"
22 #include "de/LinkFile"
23 #include "de/Loop"
24 #include <regex>
25
26 namespace de {
27 namespace filesys {
28
29 static const std::string PREFIX = "asset";
30
DENG2_PIMPL(AssetObserver)31 DENG2_PIMPL(AssetObserver)
32 , DENG2_OBSERVES(FileIndex, Addition)
33 , DENG2_OBSERVES(FileIndex, Removal)
34 {
35 const std::regex pattern;
36 LoopCallback mainCall;
37
38 static FileIndex const &linkIndex() {
39 return App::fileSystem().indexFor(DENG2_TYPE_NAME(LinkFile));
40 }
41
42 static String assetIdentifier(File const &link) {
43 DENG2_ASSERT(link.name().beginsWith(String::fromStdString(PREFIX + ".")));
44 return link.name().mid(6);
45 }
46
47 Impl(Public *i, String const ®ex)
48 : Base(i)
49 , pattern(PREFIX + "\\." + regex.toStdString(), std::regex::icase)
50 {
51 // We will observe available model assets.
52 linkIndex().audienceForAddition() += this;
53 linkIndex().audienceForRemoval() += this;
54 }
55
56 void fileAdded(File const &link, FileIndex const &)
57 {
58 // Only matching assets cause notifications.
59 if (!std::regex_match(link.name().toStdString(), pattern)) return;
60
61 String const ident = assetIdentifier(link);
62 mainCall.enqueue([this, ident] ()
63 {
64 DENG2_FOR_PUBLIC_AUDIENCE2(Availability, i)
65 {
66 i->assetAvailabilityChanged(ident, Added);
67 }
68 });
69 }
70
71 void fileRemoved(File const &link, FileIndex const &)
72 {
73 // Only matching assets cause notifications.
74 if (!std::regex_match(link.name().toStdString(), pattern)) return;
75
76 DENG2_FOR_PUBLIC_AUDIENCE2(Availability, i)
77 {
78 i->assetAvailabilityChanged(assetIdentifier(link), Removed);
79 }
80 }
81
82 DENG2_PIMPL_AUDIENCE(Availability)
83 };
84
DENG2_AUDIENCE_METHOD(AssetObserver,Availability)85 DENG2_AUDIENCE_METHOD(AssetObserver, Availability)
86
87 AssetObserver::AssetObserver(String const ®exPattern)
88 : d(new Impl(this, regexPattern))
89 {}
90
91 } // namespace filesys
92 } // namespace de
93