]> Dogcows Code - chaz/yoink/blob - src/moof/resource.cc
resource loading bugs and new sound class
[chaz/yoink] / src / moof / resource.cc
1
2 /*] Copyright (c) 2009-2010, Charles McGarvey [**************************
3 **] All rights reserved.
4 *
5 * vi:ts=4 sw=4 tw=75
6 *
7 * Distributable under the terms and conditions of the 2-clause BSD license;
8 * see the file COPYING for a complete text of the license.
9 *
10 **************************************************************************/
11
12 #include "config.h"
13
14 #ifdef USE_HOTLOADING
15 #include <sys/inotify.h>
16 #include <sys/ioctl.h>
17 #endif
18
19 #include <queue>
20
21 #include <boost/algorithm/string.hpp>
22 #include <boost/weak_ptr.hpp>
23 #include <stlplus/portability/file_system.hpp>
24
25 #include "hash.hh"
26 #include "resource.hh"
27
28
29 #ifndef BUF_SIZE
30 #define BUF_SIZE 4096
31 #endif
32
33
34 namespace moof {
35
36 void resource::print_types()
37 {
38 }
39
40 void resource::manage_loader(const std::string& extension, loader_ptr& loader, bool set)
41 {
42 static type_lookup lookup;
43
44 if (loader || set)
45 {
46 lookup[extension] = loader;
47 }
48 else
49 {
50 std::map<std::string,loader_ptr>::iterator it;
51 it = lookup.find(extension);
52 if (it != lookup.end()) loader = (*it).second;
53 }
54 }
55
56 static std::string search_paths_;
57
58 typedef boost::weak_ptr<resource> resource_weakptr;
59 static hash<std::string,resource_weakptr,hash_function> resource_table_;
60
61 // static member
62 //resource::type_lookup_ptr resource::type_lookup_;
63 //resource::type_lookup resource::type_lookup_;
64
65
66 #ifdef USE_HOTLOADING
67 static hash<int,std::string,hash_function> monitor_lookup_;
68 static int monitor_fd_ = inotify_init1(IN_NONBLOCK);
69 #endif
70
71 int resource::reload_as_needed()
72 {
73 int num_resources = 0;
74
75 #ifdef USE_HOTLOADING
76 log_info("hotloading?");
77 char bytes[BUF_SIZE];
78 int num_bytes;
79 if (0 < (num_bytes = read(monitor_fd_, bytes, num_bytes)))
80 {
81 char* end = bytes + num_bytes;
82 char* byte = bytes;
83
84 log_warning("num_bytes:", num_bytes);
85 log_error("1");
86
87 while (byte < end)
88 {
89 struct inotify_event* event = (struct inotify_event*)byte;
90
91 if (event->mask & IN_IGNORED)
92 {
93 log_warning("watch", event->wd, "removed");
94 }
95
96 log_error("2");
97 hash<int,std::string,hash_function>::iterator it;
98 it = monitor_lookup_.find(event->wd);
99 if (it != monitor_lookup_.end())
100 {
101 log_error("3");
102 std::string path = (*it).second;
103 monitor_lookup_.erase(it);
104 resource::reload(path);
105 }
106
107 byte += sizeof(*event) + event->len;
108
109 ++num_resources;
110 }
111 }
112 #endif
113
114 return num_resources;
115 }
116
117
118 resource::~resource()
119 {
120 #ifdef USE_HOTLOADING
121 inotify_rm_watch(monitor_fd_, wd_);
122 #endif
123 }
124
125
126 resource_ptr resource::load(const std::string& path)
127 {
128 std::string extension = stlplus::extension_part(path);
129
130 std::string path1 = find_file(path);
131 if (!find(path1))
132 {
133 log_error("trying to load missing resource:", path1);
134 return resource_ptr();
135 }
136
137 hash<std::string,resource_weakptr,hash_function>::iterator it;
138 it = resource_table_.find(path1);
139 if (it != resource_table_.end())
140 {
141 resource_weakptr rsrc = (*it).second;
142 resource_ptr locked = rsrc.lock();
143 if (locked) return locked;
144 }
145
146 loader_ptr loader;
147 manage_loader(extension, loader);
148 if (loader)
149 {
150 resource_ptr rsrc(loader->load(path1));
151 rsrc->set_loader(path1, loader);
152 resource_table_[path1] = rsrc;
153
154 #ifdef USE_HOTLOADING
155 int wd = inotify_add_watch(monitor_fd_, path1.c_str(), IN_MODIFY);
156 rsrc->set_watch_descriptor(wd);
157 monitor_lookup_[wd] = path1;
158 #endif
159
160 log_info("loaded", rsrc.get());
161 return rsrc;
162 }
163
164 return resource_ptr();
165 }
166
167
168 resource_ptr resource::reload(std::string& path)
169 {
170 log_info("reloading...", path);
171 hash<std::string,resource_weakptr,hash_function>::iterator it;
172 it = resource_table_.find(path);
173 if (it != resource_table_.end())
174 {
175 resource_weakptr rsrc = (*it).second;
176 resource_ptr locked = rsrc.lock();
177 if (locked)
178 {
179 locked->reload();
180 return locked;
181 }
182 }
183
184 return load(path);
185 }
186
187 void resource::reload()
188 {
189 log_info("reloaded", path_);
190
191 resource* resource = loader_->load(path_);
192 //*this = *resource;
193 resource_ = resource->resource_;
194 typeinfo_ = resource->typeinfo_;
195 unloader_ = resource->unloader_;
196
197 #ifdef USE_HOTLOADING
198 int wd = inotify_add_watch(monitor_fd_, path_.c_str(), IN_MODIFY);
199 set_watch_descriptor(wd);
200 monitor_lookup_[wd] = path_;
201 #endif
202
203 delete resource;
204 }
205
206
207 void resource::add_search_paths(const std::string& paths)
208 {
209 search_paths_ = paths;
210 }
211
212
213 bool resource::find(const std::string& path)
214 {
215 std::string file = stlplus::lookup(path, search_paths_, ":");
216 log_info("found file", file, "in", search_paths_);
217 return !stlplus::lookup(path, search_paths_, ":").empty();
218 }
219
220 std::string resource::find_file(const std::string& name)
221 {
222 log_info("looking for", name, "in", search_paths_);
223 return stlplus::lookup(name, search_paths_, ":");
224 }
225
226 FILE* resource::open_file(const std::string& path, const std::string& mode)
227 {
228 std::string file = stlplus::lookup(path, search_paths_, ":");
229 return fopen(file.c_str(), mode.c_str());
230 }
231
232
233 } // namespace moof
234
This page took 0.043613 seconds and 4 git commands to generate.