]>
Dogcows Code - chaz/yoink/blob - src/moof/resource.cc
2 /*] Copyright (c) 2009-2010, Charles McGarvey [**************************
3 **] All rights reserved.
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.
10 **************************************************************************/
15 #include <sys/inotify.h>
16 #include <sys/ioctl.h>
21 #include <boost/algorithm/string.hpp>
22 #include <boost/weak_ptr.hpp>
23 #include <stlplus/portability/file_system.hpp>
26 #include "resource.hh"
37 bool resource::call_registry(const std::string
& extension
,
39 registry_action action
)
41 static type_lookup table
;
47 if (loader
) table
[extension
] = loader
;
48 else table
.erase(extension
);
54 std::map
<std::string
,loader_ptr
>::iterator it
;
55 it
= table
.find(extension
);
56 if (it
!= table
.end()) loader
= (*it
).second
;
64 static std::string search_paths_
;
66 typedef boost::weak_ptr
<resource
> resource_weakptr
;
67 static hash
<std::string
,resource_weakptr
,hash_function
> resource_table_
;
69 static hash
<std::string
,std::string
,hash_function
> prefix_table_
;
73 static hash
<int,std::string
,hash_function
> monitor_lookup_
;
74 static int monitor_fd_
= inotify_init1(IN_NONBLOCK
);
77 int resource::reload_as_needed()
79 int num_resources
= 0;
82 log_info("hotloading?");
85 if (0 < (num_bytes
= read(monitor_fd_
, bytes
, num_bytes
)))
87 char* end
= bytes
+ num_bytes
;
90 log_warning("num_bytes:", num_bytes
);
95 struct inotify_event
* event
= (struct inotify_event
*)byte
;
97 if (event
->mask
& IN_IGNORED
)
99 log_warning("watch", event
->wd
, "removed");
103 hash
<int,std::string
,hash_function
>::iterator it
;
104 it
= monitor_lookup_
.find(event
->wd
);
105 if (it
!= monitor_lookup_
.end())
108 std::string path
= (*it
).second
;
109 monitor_lookup_
.erase(it
);
110 resource::reload(path
);
113 byte
+= sizeof(*event
) + event
->len
;
120 return num_resources
;
124 resource::~resource()
126 #ifdef USE_HOTLOADING
127 inotify_rm_watch(monitor_fd_
, wd_
);
132 resource_ptr
resource::load(const std::string
& name
,
133 const std::string
& ext
)
135 return load_with_path(find_file(name
, ext
));
138 resource_ptr
resource::load(const std::string
& name
)
140 return load_with_path(find_file(name
));
144 resource_ptr
resource::load_with_path(const std::string
& path
)
146 std::string extension
= stlplus::extension_part(path
);
148 hash
<std::string
,resource_weakptr
,hash_function
>::iterator it
;
149 it
= resource_table_
.find(path
);
150 if (it
!= resource_table_
.end())
152 resource_weakptr rsrc
= (*it
).second
;
153 resource_ptr locked
= rsrc
.lock();
154 if (locked
) return locked
;
158 call_registry(extension
, loader
, lookup
);
161 resource_ptr
rsrc(loader
->load(path
));
162 rsrc
->set_loader(path
, loader
);
163 resource_table_
[path
] = rsrc
;
165 #ifdef USE_HOTLOADING
166 int wd
= inotify_add_watch(monitor_fd_
, path
.c_str(), IN_MODIFY
);
167 rsrc
->set_watch_descriptor(wd
);
168 monitor_lookup_
[wd
] = path
;
171 log_info("loaded", rsrc
.get());
175 log_warning("cannot load resource of unknown type:", path
);
176 return resource_ptr();
180 resource_ptr
resource::reload(std::string
& path
)
182 log_info("reloading...", path
);
183 hash
<std::string
,resource_weakptr
,hash_function
>::iterator it
;
184 it
= resource_table_
.find(path
);
185 if (it
!= resource_table_
.end())
187 resource_weakptr rsrc
= (*it
).second
;
188 resource_ptr locked
= rsrc
.lock();
199 void resource::reload()
201 log_info("reloaded", path_
);
203 resource
* resource
= loader_
->load(path_
);
205 resource_
= resource
->resource_
;
206 typeinfo_
= resource
->typeinfo_
;
207 unloader_
= resource
->unloader_
;
209 #ifdef USE_HOTLOADING
210 int wd
= inotify_add_watch(monitor_fd_
, path_
.c_str(), IN_MODIFY
);
211 set_watch_descriptor(wd
);
212 monitor_lookup_
[wd
] = path_
;
219 void resource::add_search_paths(const std::string
& paths
)
221 search_paths_
= paths
;
225 bool resource::find(const std::string
& path
)
227 //std::string file = stlplus::lookup(path, search_paths_, ":");
228 //log_info("found file", file, "in", search_paths_);
229 //return !stlplus::lookup(path, search_paths_, ":").empty();
230 return find_file(path
) != "";
234 std::string
resource::find_file(const std::string
& name
)
236 std::vector
<std::string
> paths
;
237 boost::split(paths
, search_paths_
, boost::is_any_of(":"));
239 std::string ext
= stlplus::extension_part(name
);
240 std::string
prefix("hi");
243 call_registry(ext
, loader
, lookup
);
244 if (loader
) prefix
= loader
->prefix();
246 log_info("find_file:", ext
, prefix
);
248 std::vector
<std::string
>::iterator it
;
249 for (it
= paths
.begin(); it
!= paths
.end(); ++it
)
251 std::string path
= stlplus::create_filespec(*it
, name
);
252 log_info("looking for", name
, "at", path
);
253 if (stlplus::file_exists(path
)) return path
;
255 // try it with the prefix added
258 *it
= stlplus::create_filespec(*it
, prefix
);
259 path
= stlplus::create_filespec(*it
, name
);
260 log_info("looking for", name
, "at", path
);
261 if (stlplus::file_exists(path
)) return path
;
266 log_error("cannot find resource file:", name
);
267 return std::string();
270 std::string
resource::find_file(const std::string
& name
,
271 const std::string
& ext
)
273 std::string actual_ext
= stlplus::extension_part(name
);
274 if (actual_ext
!= ext
)
276 return find_file(stlplus::create_filename(name
, ext
));
278 return find_file(name
);
281 FILE* resource::open_file(const std::string
& path
, const std::string
& mode
)
283 return fopen(find_file(path
).c_str(), mode
.c_str());
This page took 0.052509 seconds and 4 git commands to generate.