source: Plugins/dynamicResources/Monitor.cpp @ 32

Revision 32, 6.5 KB checked in by art, 12 years ago (diff)
Line 
1/***************************************************************************
2 *                                                                         *
3 *   (c) Art Tevs, MPI Informatik Saarbruecken                             *
4 *       mailto: <tevs@mpi-sb.mpg.de>                                      *
5 *                                                                         *
6 *   This program is free software; you can redistribute it and/or modify  *
7 *   it under the terms of the GNU General Public License as published by  *
8 *   the Free Software Foundation; either version 2 of the License, or     *
9 *   (at your option) any later version.                                   *
10 *                                                                         *
11 ***************************************************************************/
12
13#include "Monitor.h"
14using namespace nrEngine;
15
16//if we are using linux system, then include inotify interface
17
18
19//----------------------------------------------------------------------------------
20Monitor::Monitor(Engine* root) : mRoot(root)
21{
22        setTaskName("DynamicResourceMonitor");
23}
24
25
26//----------------------------------------------------------------------------------
27Monitor::~Monitor()
28{
29
30}
31
32//----------------------------------------------------------------------------------
33Result Monitor::onStartTask()
34{
35        Result res = UNKNOWN_ERROR;
36       
37        // use inotify if supported
38        #ifdef USE_INOTIFY
39                res = initInotify();
40        #endif
41
42        init();
43       
44        // nothing supported, so return an error
45        return res;
46}
47
48//----------------------------------------------------------------------------------
49Result Monitor::stopTask()
50{
51        // if we support inotify, then do
52        #ifdef USE_INOTIFY
53                mInotify->Close();
54                NR_Log(Log::LOG_PLUGIN, "dynamicResources: Close inotify subsystem");
55        #endif
56       
57        // ok
58        return OK;
59}
60
61
62//----------------------------------------------------------------------------------
63#ifdef USE_INOTIFY
64Result Monitor::initInotify()
65{
66        // if we support inotify, then do
67        NR_Log(Log::LOG_PLUGIN, "dynamicResources: Use inotify interface for file monitoring");
68       
69        try
70        {
71                mInotify.reset(new Inotify());
72                //mInotify->SetNonBlock(true);
73        }catch(InotifyException& e)
74        {
75                NR_Log(Log::LOG_PLUGIN, Log::LL_ERROR, "dynamicResources: There was an error by initilizing the inotify interafce");
76                NR_Log(Log::LOG_PLUGIN, Log::LL_ERROR, "dynamicResources: %s", e.GetMessage().c_str());
77                return UNKNOWN_ERROR;
78        }
79       
80        return OK;
81}
82#endif
83
84//----------------------------------------------------------------------------------
85void Monitor::init()
86{
87        // now scan through all resources, which are already loaded
88        const ResourceManager::ResourceGroupMap& res = mRoot->sResourceManager()->getResourceMap();
89        ResourceManager::ResourceGroupMap::const_iterator it = res.begin();
90        for (; it != res.end(); it++)
91        {
92                // for each group do
93                std::list<ResourceHandle>::const_iterator jt = it->second.begin();
94                for (; jt != it->second.end(); jt++)
95                {
96                        // get resource according to the handle
97                        IResourcePtr pr = mRoot->sResourceManager()->getByHandle(*jt);
98                       
99                        // resource is valid, so do
100                        if (pr.valid())
101                        {
102                                // now get the file name associated with the resource
103                                pr.lockPure();
104                                        const std::list<std::string>& files = pr.getBase()->getResFilenameList();
105                                        std::list<std::string>::const_iterator kt = files.begin();
106                                       
107                                        // for each filename add a monitor
108                                        for (; kt != files.end(); kt ++)
109                                        {
110                                                addMonitor(pr, *kt);
111                                        }
112                                pr.unlockPure();
113                        }else{
114                                NR_Log(Log::LOG_PLUGIN, Log::LL_WARNING, "dynamicResources: Resource %s seems to be NULL", pr.getBase()->getResName().c_str());
115                        }
116                       
117                }
118        }
119}
120
121#ifdef USE_INOTIFY
122//----------------------------------------------------------------------------------
123void Monitor::addMonitor(IResourcePtr res, const std::string& file)
124{
125        // do only add a watcher if inotify already initialized
126        if (!mInotify || !res.valid() || file.length() < 1) return;
127       
128        // we monitor only non-empty resources
129        res.lockPure();
130        {
131                // create a watch descriptor
132                try
133                {
134                        // create watcher
135                        SharedPtr<InotifyWatch> watch(new InotifyWatch(file, IN_MODIFY));
136                       
137                        // add new watcher
138                        NR_Log(Log::LOG_PLUGIN, Log::LL_DEBUG, "dynamicResources: Monitor %s --> %s", res.getBase()->getResName().c_str(), file.c_str());
139                       
140                        // add the watcher into the map
141                        WatchData data;
142                        data.resource = res;
143                        data.watcher = watch;
144                        data.resourceName = res.getBase()->getResName();
145                        mWatchMap[watch->GetDescriptor()] = data;
146                       
147                        // add the new watch
148                        mInotify->Add(watch.get());
149                       
150                }catch(InotifyException& e)
151                {
152                        NR_Log(Log::LOG_PLUGIN, Log::LL_ERROR, "dynamicResources: Cannot add a monitor %s --> %s", res.getBase()->getResName().c_str(), file.c_str());
153                        NR_Log(Log::LOG_PLUGIN, Log::LL_ERROR, "dynamicResources: %s", e.GetMessage().c_str());
154                        return;
155                }
156               
157        }
158        res.unlockPure();
159}
160
161#else
162
163//----------------------------------------------------------------------------------
164void Monitor::addMonitor(IResourcePtr res, const std::string& file)
165{
166        NR_Log(Log::LOG_PLUGIN, Log::LL_WARNING, "dynamicResources: Not valid monitor interface used to monitor %s --> %s", res.getBase()->getResName().c_str(), file.c_str());
167}
168
169#endif
170
171
172
173#ifdef USE_INOTIFY
174//----------------------------------------------------------------------------------
175Result Monitor::update()
176{
177        if (!mInotify) return OK;
178       
179        printf("update\n");
180        // wait for inotify events
181        try{
182                mInotify->WaitForEvents();
183        }catch(InotifyException& e)
184        {
185                NR_Log(Log::LOG_PLUGIN, Log::LL_ERROR, "dynamicResources: INotify Monitor cannot get events!");
186                NR_Log(Log::LOG_PLUGIN, Log::LL_ERROR, "dynamicResources: %s", e.GetMessage().c_str());
187                return OK;
188        }
189        printf("ok\n");
190       
191        // now extract events until there are no more of them
192        InotifyEvent event;
193        while(mInotify->GetEventCount() > 0)
194        {
195                // get event
196                try
197                {
198                        mInotify->GetEvent(&event);
199                        WatchData& data = mWatchMap[event.GetDescriptor()];
200                       
201                        if (data.resource.valid())
202                        {
203                                data.resource.lockPure();
204                                        printf("modified: %s\n", data.resource.getBase()->getResName().c_str());
205                                data.resource.unlockPure();
206                        }else{
207                                NR_Log(Log::LOG_PLUGIN, Log::LL_WARNING, "dynamicResources: Monitored %s resource is not valid!", data.resourceName.c_str());
208                        }
209                }
210                catch(InotifyException& e)
211                {
212                        NR_Log(Log::LOG_PLUGIN, Log::LL_ERROR, "dynamicResources: Cannot retrieve INotify-Event !");
213                        NR_Log(Log::LOG_PLUGIN, Log::LL_ERROR, "dynamicResources: %s", e.GetMessage().c_str());
214                        return OK;
215                }
216               
217        }
218
219       
220        return OK;
221}
222
223
224#else
225//----------------------------------------------------------------------------------
226Result Monitor::update()
227{
228        return OK;
229}
230
231#endif
232
233
Note: See TracBrowser for help on using the repository browser.