]>
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 **************************************************************************/
14 #include <boost/algorithm/string.hpp>
15 #include <boost/weak_ptr.hpp>
17 #include <stlplus/portability/file_system.hpp>
20 #include "resource.hh"
23 #include "../config.h"
27 #include <sys/inotify.h>
28 #include <sys/ioctl.h>
39 static std::vector
<std::string
> search_paths_
;
41 typedef boost::weak_ptr
<resource
> resource_weakptr
;
42 static hash
<std::string
,resource_weakptr
,hash_function
> resource_table_
;
45 resource::type_lookup_ptr
resource::type_lookup_
;
49 static hash
<int,std::string
,hash_function
> monitor_lookup_
;
50 static int monitor_fd_
= inotify_init1(IN_NONBLOCK
);
53 int resource::reload_as_needed()
55 int num_resources
= 0;
58 log_info("hotloading?");
61 if (0 < (num_bytes
= read(monitor_fd_
, bytes
, num_bytes
)))
63 char* end
= bytes
+ num_bytes
;
66 log_warning("num_bytes:", num_bytes
);
71 struct inotify_event
* event
= (struct inotify_event
*)byte
;
73 if (event
->mask
& IN_IGNORED
)
75 log_warning("watch", event
->wd
, "removed");
79 hash
<int,std::string
,hash_function
>::iterator it
;
80 it
= monitor_lookup_
.find(event
->wd
);
81 if (it
!= monitor_lookup_
.end())
84 std::string path
= (*it
).second
;
85 monitor_lookup_
.erase(it
);
86 resource::reload(path
);
89 byte
+= sizeof(*event
) + event
->len
;
100 resource::~resource()
103 inotify_rm_watch(monitor_fd_
, wd_
);
108 resource_ptr
resource::load(const std::string
& path
)
110 std::string extension
= stlplus::extension_part(path
);
112 if (!find(path
)) return resource_ptr();
114 hash
<std::string
,resource_weakptr
,hash_function
>::iterator it
;
115 it
= resource_table_
.find(path
);
116 if (it
!= resource_table_
.end())
118 resource_weakptr rsrc
= (*it
).second
;
119 resource_ptr locked
= rsrc
.lock();
120 if (locked
) return locked
;
123 std::map
<std::string
,loader_ptr
>::iterator jt
;
124 jt
= type_lookup_
->find(extension
);
125 if (jt
!= type_lookup_
->end())
127 resource_ptr
rsrc((*jt
).second
->load(path
));
128 rsrc
->set_loader(path
, (*jt
).second
);
129 resource_table_
[path
] = rsrc
;
132 int wd
= inotify_add_watch(monitor_fd_
,
133 path
.c_str(), IN_MODIFY
);
134 rsrc
->set_watch_descriptor(wd
);
135 monitor_lookup_
[wd
] = path
;
138 log_info("loaded", rsrc
.get());
142 return resource_ptr();
146 resource_ptr
resource::reload(std::string
& path
)
148 log_info("reloading...", path
);
149 hash
<std::string
,resource_weakptr
,hash_function
>::iterator it
;
150 it
= resource_table_
.find(path
);
151 if (it
!= resource_table_
.end())
153 resource_weakptr rsrc
= (*it
).second
;
154 resource_ptr locked
= rsrc
.lock();
165 void resource::reload()
167 log_info("reloaded", path_
);
169 resource
* resource
= loader_
->load(path_
);
171 resource_
= resource
->resource_
;
172 typeinfo_
= resource
->typeinfo_
;
173 unloader_
= resource
->unloader_
;
176 int wd
= inotify_add_watch(monitor_fd_
,
177 path_
.c_str(), IN_MODIFY
);
178 set_watch_descriptor(wd
);
179 monitor_lookup_
[wd
] = path_
;
186 void resource::add_search_paths(const std::string
& paths
)
188 std::vector
<std::string
> pathList
;
189 boost::split(pathList
, paths
, boost::is_any_of(":"));
191 add_search_paths(pathList
);
194 void resource::add_search_paths(const std::vector
<std::string
>& pathList
)
196 std::vector
<std::string
>::const_iterator it
;
197 for (it
= pathList
.begin(); it
!= pathList
.end(); ++it
)
199 std::string
path(*it
);
201 ASSERT(!path
.empty() && "empty search path string");
203 // add a slash if there isn't one already
204 if (*path
.rbegin() != '/') path
+= '/';
207 //boost::replace_all(path, "/", "\\");
210 search_paths_
.push_back(path
);
211 log_info
<< "added search path " << path
<< std::endl
;
216 bool resource::find(const std::string
& path
)
218 FILE* file
= open_file(path
);
228 FILE* resource::open_file(const std::string
& path
, const std::string
& mode
)
231 // windows always has to be a little different
232 //boost::replace_all(path, "/", "\\");
235 std::vector
<std::string
>::iterator it
;
236 for (it
= search_paths_
.begin(); it
!= search_paths_
.end(); ++it
)
238 // check path relative to search path
239 std::string
complete_path(*it
);
240 complete_path
+= path
;
242 FILE* file
= fopen(complete_path
.c_str(), mode
.c_str());
243 if (file
) return file
;
246 // last ditch effort; maybe it's already a path to a valid resource
247 return fopen(path
.c_str(), mode
.c_str());
This page took 0.042399 seconds and 4 git commands to generate.