root/hydranode/hncgcomm/cgcomm.h

Revision 2957, 19.0 kB (checked in by madcat, 3 years ago)

Support for object updates over cgcomm. Serverlist is now properly in sync with core (1s update rate).

Line 
1 /*
2  *  Copyright (C) 2005-2006 Alo Sarv <madcat_@users.sourceforge.net>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18
19 #ifndef __CGCOMM_H__
20 #define __CGCOMM_H__
21
22 #include <hncgcomm/osdep.h>
23 #include <hncgcomm/fwd.h>
24 #include <hncore/cgcomm/opcodes.h>
25 #include <boost/function.hpp>
26 #include <boost/signal.hpp>
27 #include <boost/scoped_ptr.hpp>
28 #include <boost/shared_ptr.hpp>
29 #include <boost/enable_shared_from_this.hpp>
30 #include <boost/utility.hpp>
31 #include <vector>
32 #include <string>
33 #include <map>
34 #include <set>
35
36 namespace Engine {
37         extern boost::signal<void (const std::string&)> debugMsg;
38
39         namespace Detail {
40                 struct MainSubMap;
41         }
42
43         // Main class initializes core/gui communication, and provides front-end
44         // for inputting data to the parser, as well as signals when user should
45         // send specific data back to the engine over the socket.
46         //
47         // All other subsystem constructors require pointer to this class as
48         // first construction argument, since they need to know information
49         // found here.
50         class DLLEXPORT Main {
51         public:
52                 // Function prototype used for outgoing data
53                 typedef boost::function<void (const std::string&)> SendFunc;
54
55                 // Main constructor; requires a function to be used for outgoing
56                 // data
57                 Main(SendFunc func);
58
59                 ~Main();
60
61                 // Parse data received from engine
62                 void parse(const std::string &data);
63
64                 void addSubSys(SubSysBase *sys);
65                 void delSubSys(SubSysBase *sys);
66
67                 // Sends request to shut down engine completely
68                 void shutdownEngine();
69         private:
70                 // default constructor is forbidden
71                 Main();
72
73                 // copying is forbidden
74                 Main(const Main&);
75                 Main& operator=(const Main&);
76
77                 friend class SubSysBase; // needs to access sendData
78
79                 SendFunc sendData;       // sends data to engine
80                 std::string m_buffer;    // input buffer
81
82                 // list of subsystems active at this time
83                 Detail::MainSubMap *m_list;
84         };
85
86         class DLLEXPORT SubSysBase : boost::noncopyable {
87         public:
88                 SubSysBase(Main *parent, uint8_t subCode);
89                 virtual ~SubSysBase();
90                 virtual void handle(std::istream &packet) = 0;
91                 uint8_t getSubCode() const;
92         protected:
93                 void sendPacket(const std::string &data);
94         private:
95                 SubSysBase();
96
97                 Main *m_parent;
98                 uint8_t m_subCode;
99         };
100
101         /////////////////////////
102         // Searching subsystem //
103         /////////////////////////
104
105         class DLLEXPORT SearchResult : boost::noncopyable {
106         public:
107                 SearchResult(Search *parent);
108
109                 std::string getName()        const { return m_name;        }
110                 uint64_t    getSize()        const { return m_size;        }
111                 uint32_t    getSources()     const { return m_sources;     }
112                 uint32_t    getFullSources() const { return m_fullSources; }
113
114                 uint32_t    getBitrate() const { return m_bitrate; }
115                 uint32_t    getLength()  const { return m_length;  }
116                 std::string getCodec()   const { return m_codec;   }
117
118                 void download();
119                 void download(const std::string &dest);
120                 boost::signal<void()> onUpdated;
121         private:
122                 SearchResult();
123                 void update(SearchResultPtr res);
124
125                 friend class Search;
126                 Search*     m_parent; //!< Needed for download() method
127                 std::string m_name;
128                 uint64_t    m_size;
129                 uint32_t    m_sources;
130                 uint32_t    m_fullSources;
131                 uint32_t    m_num;
132                 // multimedia-specific
133                 uint32_t    m_bitrate;
134                 uint32_t    m_length;
135                 std::string m_codec;
136         };
137
138         // provides means for performing searches
139         class DLLEXPORT Search : public SubSysBase {
140         public:
141                 typedef boost::function<
142                         void (const std::vector<SearchResultPtr>&)
143                 > ResultHandler;
144
145                 Search(
146                         Main *parent, ResultHandler handler,
147                         const std::string &keywords = "",
148                         FileType ft = FT_UNKNOWN
149                 );
150
151                 // run the search
152                 void run();
153
154                 void addKeywords(const std::string &keywords);
155                 void setType(FileType ft);
156                 void setMinSize(uint64_t size);
157                 void setMaxSize(uint64_t size);
158
159         protected:
160                 // handle data coming from engine
161                 virtual void handle(std::istream &packet);
162         private:
163                 Search();
164
165                 friend class SearchResult;
166
167                 // signal that will be emitted when new results are found
168                 ResultHandler m_sigResults;
169                 std::string   m_keywords;
170                 uint64_t      m_minSize;
171                 uint64_t      m_maxSize;
172                 FileType      m_fileType;
173                 uint32_t      m_lastNum;
174                 std::map<uint32_t, SearchResultPtr> m_results;
175         };
176
177         ///////////////////////////
178         // Downloading Subsystem //
179         ///////////////////////////
180
181         typedef boost::shared_ptr<DownloadInfo> DownloadInfoPtr;
182
183         enum DownloadState {
184                 DSTATE_RUNNING   = ::CGComm::DSTATE_RUNNING,
185                 DSTATE_VERIFYING = ::CGComm::DSTATE_VERIFYING,
186                 DSTATE_MOVING    = ::CGComm::DSTATE_MOVING,
187                 DSTATE_COMPLETED = ::CGComm::DSTATE_COMPLETE,
188                 DSTATE_CANCELED  = ::CGComm::DSTATE_CANCELED,
189                 DSTATE_PAUSED    = ::CGComm::DSTATE_PAUSED,
190                 DSTATE_STOPPED   = ::CGComm::DSTATE_STOPPED
191         };
192
193         class DLLEXPORT DownloadInfo
194                 : public boost::enable_shared_from_this<DownloadInfo> {
195         public:
196                 typedef std::set<DownloadInfoPtr>::const_iterator CIter;
197
198                 CIter begin()      const { return m_children.begin(); }
199                 CIter end()        const { return m_children.end();   }
200                 bool hasChildren() const { return m_children.size();  }
201                 bool hasChild(DownloadInfoPtr p) const {
202                         return m_children.find(p) != m_children.end();
203                 }
204
205                 ~DownloadInfo();
206
207                 void pause();
208                 void stop();
209                 void resume();
210                 void cancel();
211                 void setName(const std::string &newName);
212                 void setDest(const std::string &newDest);
213
214                 std::string   getName()       const { return m_name;       }
215                 uint64_t      getSize()       const { return m_size;       }
216                 uint64_t      getCompleted()  const { return m_completed;  }
217                 uint32_t      getSourceCnt()  const { return m_srcCnt;     }
218                 uint32_t      getFullSrcCnt() const { return m_fullSrcCnt; }
219                 std::string   getDestDir()    const { return m_destDir;    }
220                 uint32_t      getId()         const { return m_id;         }
221                 uint32_t      getSpeed()      const { return m_speed;      }
222                 DownloadState getState()      const { return m_state;      }
223                 std::string   getLocation()   const { return m_location;   }
224                 uint8_t       getAvail()      const { return m_avail;      }
225
226                 void getNames();
227                 void getComments();
228                 void getLinks();
229
230                 typedef std::set<std::string>::const_iterator CommentIter;
231                 typedef std::set<std::string>::const_iterator LinkIter;
232                 typedef std::map<std::string,uint32_t>::const_iterator NameIter;
233
234                 CommentIter cbegin() const { return m_comments.begin(); }
235                 CommentIter cend()   const { return m_comments.end();   }
236                 size_t      ccount() const { return m_comments.size();  }
237                 LinkIter    lbegin() const { return m_links.begin();    }
238                 LinkIter    lend()   const { return m_links.end();      }
239                 size_t      lcount() const { return m_links.size();     }
240                 NameIter    nbegin() const { return m_names.begin();    }
241                 NameIter    nend()   const { return m_names.end();      }
242                 size_t      ncount() const { return m_names.size();     }
243
244                 boost::signal<void ()> onUpdated;
245                 boost::signal<void ()> onDeleted;
246         private:
247                 friend class DownloadList;
248
249                 DownloadInfo(DownloadList *parent, uint32_t id);
250                 DownloadInfo(const DownloadInfo&);
251
252                 void update(const DownloadInfo &o);
253
254                 std::string   m_name;
255                 uint64_t      m_size;
256                 uint64_t      m_completed;
257                 std::string   m_destDir;
258                 uint32_t      m_srcCnt;
259                 uint32_t      m_fullSrcCnt;
260                 uint32_t      m_speed;
261                 DownloadState m_state;
262                 std::string   m_location;
263                 uint8_t       m_avail;
264                 uint32_t      m_id;
265
266                 // these three are not sent automatically, but must be requested
267                 // explicitly via getComments(), getNames() and getLinks()
268                 // methods. onUpdated() signal is emitted when the data arrives.
269                 std::set<std::string> m_comments;
270                 std::map<std::string, uint32_t> m_names;
271                 std::set<std::string> m_links;
272
273                 std::set<DownloadInfoPtr> m_children;
274                 DownloadList *m_parent;
275         };
276
277         // access the download list
278         class DLLEXPORT DownloadList : public SubSysBase {
279         public:
280                 DownloadList(Main *parent);
281
282                 // Request the list of current downloads.
283                 void getList();
284
285                 // monitor the list, receiving updates whenever anything changes
286                 void monitor(uint32_t interval);
287
288                 void pause(DownloadInfoPtr d);
289                 void stop(DownloadInfoPtr d);
290                 void resume(DownloadInfoPtr d);
291                 void cancel(DownloadInfoPtr d);
292                 void getNames(DownloadInfoPtr d);
293                 void getComments(DownloadInfoPtr d);
294                 void getLinks(DownloadInfoPtr d);
295                 void setName(DownloadInfoPtr d, const std::string &newName);
296                 void setDest(DownloadInfoPtr d, const std::string &newDest);
297
298                 void downloadFromLink(const std::string &link);
299                 void downloadFromFile(const std::string &contents);
300                 void importDownloads(const std::string &dir);
301        
302                 boost::signal<void (DownloadInfoPtr)> onAdded;
303                 boost::signal<void (DownloadInfoPtr)> onRemoved;
304                 boost::signal<void (DownloadInfoPtr)> onUpdated;
305                 boost::signal<void (DownloadInfoPtr)> onUpdatedNames;
306                 boost::signal<void (DownloadInfoPtr)> onUpdatedComments;
307                 boost::signal<void (DownloadInfoPtr)> onUpdatedLinks;
308                 boost::signal<void ()> onAddedList;
309                 boost::signal<void ()> onUpdatedList;
310         protected:
311                 // handle data coming from engine
312                 virtual void handle(std::istream &packet);
313         private:
314                 DownloadList();
315
316                 //! helper function, reads one DownloadInfo from stream
317                 DownloadInfoPtr readDownload(std::istream &i);
318                 void foundNames(std::istream &packet);
319                 void foundComments(std::istream &packet);
320                 void foundLinks(std::istream &packet);
321                 void sendRequest(uint8_t oc, uint32_t id);
322                 std::map<uint32_t, DownloadInfoPtr> m_list;
323                 typedef std::map<uint32_t, DownloadInfoPtr>::iterator Iter;
324         };
325
326
327         ///////////////////////////
328         // Shared Files listing  //
329         ///////////////////////////
330         class DLLEXPORT SharedFile
331         : public boost::enable_shared_from_this<SharedFile> {
332         public:
333                 typedef std::set<SharedFilePtr>::const_iterator CIter;
334
335                 CIter begin()      const { return m_children.begin(); }
336                 CIter end()        const { return m_children.end();   }
337                 bool hasChildren() const { return m_children.size();  }
338                 bool hasChild(SharedFilePtr p) const {
339                         return m_children.find(p) != m_children.end();
340                 }
341
342                 std::string getName()       const { return m_name;       }
343                 std::string getLocation()   const { return m_location;   }
344                 uint64_t    getSize()       const { return m_size;       }
345                 uint64_t    getUploaded()   const { return m_uploaded;   }
346                 uint32_t    getSpeed()      const { return m_speed;      }
347                 uint32_t    getId()         const { return m_id;         }
348                 uint32_t    getPartDataId() const { return m_partDataId; }
349
350                 boost::signal<void ()> onUpdated;
351                 boost::signal<void ()> onDeleted;
352
353                 ~SharedFile();
354         private:
355                 friend class SharedFilesList;
356
357                 SharedFile();
358                 SharedFile(const SharedFile&);
359                 SharedFile(SharedFilesList *parent, uint32_t id);
360                 SharedFile& operator=(const SharedFile&);
361
362                 void update(const SharedFile &o);
363
364                 std::string m_name;
365                 std::string m_location;
366                 uint64_t    m_size;
367                 uint64_t    m_uploaded;
368                 uint32_t    m_speed;
369                 uint32_t    m_id;
370                 uint32_t    m_partDataId;
371
372                 SharedFilesList *m_parent;
373                 std::set<SharedFilePtr> m_children;
374         };
375
376         class DLLEXPORT SharedFilesList : public SubSysBase {
377         public:
378                 SharedFilesList(Main *parent);
379
380                 void getList();
381                 void monitor(uint32_t interval);
382                 void addShared(const std::string &dir);
383                 void remShared(const std::string &dir);
384
385                 boost::signal<void (SharedFilePtr)> onAdded;
386                 boost::signal<void (SharedFilePtr)> onRemoved;
387                 boost::signal<void (SharedFilePtr)> onUpdated;
388                 boost::signal<void ()> onAddedList;
389                 boost::signal<void ()> onUpdatedList;
390         protected:
391                 // handle data coming from engine
392                 virtual void handle(std::istream &packet);
393         private:
394                 SharedFilesList();
395
396                 SharedFilePtr readFile(std::istream &i);
397                 std::map<uint32_t, SharedFilePtr> m_list;
398                 typedef std::map<uint32_t, SharedFilePtr>::iterator Iter;
399         };
400
401         /////////////////////////////
402         // Configuration subsystem //
403         /////////////////////////////
404
405         class DLLEXPORT Config : public SubSysBase {
406         public:
407                 typedef boost::function<
408                         void (const std::map<std::string, std::string>&)
409                 > ListHandler;
410
411                 Config(Main *parent, ListHandler handler);
412
413                 void getValue(const std::string &key);
414                 void setValue(const std::string &key, const std::string &value);
415                 void getList();
416                 void monitor();
417         protected:
418                 // handle data coming from engine
419                 virtual void handle(std::istream &packet);
420         private:
421                 ListHandler m_handler;
422                 std::map<std::string, std::string> m_list;
423         };
424
425         ///////////////////////
426         // Network subsystem //
427         ///////////////////////
428        
429         class DLLEXPORT Network : public SubSysBase {
430         public:
431                 typedef boost::function<void()> UpdateHandler;
432
433                 Network(Main *parent, UpdateHandler handler);
434                 void getList();
435                 void monitor(uint32_t interval);
436
437                 uint32_t getUpSpeed()        const { return m_upSpeed;       }
438                 uint32_t getDownSpeed()      const { return m_downSpeed;     }
439                 uint32_t getConnCnt()        const { return m_connCnt;       }
440                 uint32_t getConnectingCnt()  const { return m_connectingCnt; }
441                 uint64_t getTotalUp()        const { return m_totalUp;       }
442                 uint64_t getTotalDown()      const { return m_totalDown;     }
443                 uint64_t getSessionUp()      const { return m_sessionUp;     }
444                 uint64_t getSessionDown()    const { return m_sessionDown;   }
445                 uint64_t getUpPackets()      const { return m_upPackets;     }
446                 uint64_t getDownPackets()    const { return m_downPackets;   }
447                 uint32_t getUpLimit()        const { return m_upLimit;       }
448                 uint32_t getDownLimit()      const { return m_downLimit;     }
449                 uint64_t getSessionLength()  const { return m_sessLength;    }
450                 uint64_t getOverallRuntime() const { return m_totalRuntime;  }
451         protected:
452                 virtual void handle(std::istream &i);
453         private:
454                 uint32_t m_upSpeed,   m_downSpeed, m_connCnt,   m_connectingCnt;
455                 uint64_t m_totalUp,   m_totalDown, m_sessionUp, m_sessionDown;
456                 uint64_t m_upPackets, m_downPackets;
457                 uint32_t m_upLimit,   m_downLimit;
458                 uint64_t m_sessLength,m_totalRuntime;
459                 UpdateHandler m_handler;
460         };
461
462         ///////////////////////
463         // Modules subsystem //
464         ///////////////////////
465
466         class DLLEXPORT Module {
467         public:
468                 std::string getName()           const { return m_name;      }
469                 std::string getDesc()           const { return m_desc;      }
470                 uint64_t getSessionUploaded()   const { return m_sessUp;    }
471                 uint64_t getSessionDownloaded() const { return m_sessDown;  }
472                 uint64_t getTotalUploaded()     const { return m_totalUp;   }
473                 uint64_t getTotalDownloaded()   const { return m_totalDown; }
474                 uint32_t getUpSpeed()           const { return m_upSpeed;   }
475                 uint32_t getDownSpeed()         const { return m_downSpeed; }
476                 uint32_t getId()                const { return m_id;        }
477
478                 friend class Modules;
479         private:
480                 std::string m_name, m_desc;
481                 uint64_t m_sessUp, m_sessDown, m_totalUp, m_totalDown;
482                 uint32_t m_upSpeed, m_downSpeed, m_id;
483        
484                 void update(ModulePtr mod);
485
486                 Module();
487                 Module(const Module&);
488         };
489
490         class DLLEXPORT Object : public boost::enable_shared_from_this<Object> {
491         public:
492                 typedef std::vector<std::string>::const_iterator DIter;
493                 typedef std::map<uint32_t, ObjectPtr>::const_iterator CIter;
494
495                 std::string getName()   const { return m_name;   }
496                 uint32_t    getId()     const { return m_id;     }
497                 ObjectPtr   getParent() const { return m_parent; }
498
499                 size_t      dataCount()       const { return m_data.size();  }
500                 std::string getData(size_t n) const { return m_data.at(n);   }
501                 DIter       dbegin()          const { return m_data.begin(); }
502                 DIter       dend()            const { return m_data.end();   }
503
504                 size_t childCount() const { return m_children.size();  }
505                 CIter  begin()      const { return m_children.begin(); }
506                 CIter  end()        const { return m_children.end();   }
507
508                 void doOper(
509                         const std::string &opName,
510                         const std::map<std::string, std::string> &args
511                 );
512                 void setData(uint8_t num, const std::string &newValue);
513
514                 boost::signal<void (ObjectPtr, ObjectPtr)> childAdded;
515                 boost::signal<void (ObjectPtr, ObjectPtr)> childRemoved;
516                 boost::signal<void (ObjectPtr)> onDestroyed;
517         private:
518                 friend class Modules;
519
520                 ObjectPtr m_parent;
521                 Modules *m_parentList;
522                 std::vector<std::string> m_data;
523                 std::map<uint32_t, ObjectPtr> m_children;
524                 std::set<uint32_t> m_childIds;
525                 std::string m_name;
526                 uint32_t m_id;
527
528                 void update(ObjectPtr obj);
529                 void findChildren();
530                 void destroy();
531
532                 Object(Modules *parent);
533                 Object(const Object&);
534                 Object& operator=(const Object&);
535         };
536
537         class DLLEXPORT Modules : public SubSysBase {
538         public:
539                 Modules(Main *parent);
540
541                 // modules specific
542                 void getList();
543                 void monitor(uint32_t interval);
544
545                 boost::signal<void ()> onUpdated;
546                 boost::signal<void (ModulePtr)> onAdded;
547                 boost::signal<void (ModulePtr)> onRemoved;
548
549                 typedef std::map<uint32_t, ModulePtr>::iterator Iter;
550                 typedef std::map<uint32_t, ModulePtr>::const_iterator CIter;
551
552                 size_t count() const { return m_list.size();  }
553                 CIter  begin() const { return m_list.begin(); }
554                 CIter  end()   const { return m_list.end();   }
555
556                 // Object tree specific
557
558                 /**
559                  * Request an object to be sent
560                  *
561                  * @param mod          Module for which the object is child of
562                  * @param name         Name of the object to be sent
563                  * @param recurse      Whether to send the entire subtree
564                  * @param monitorTimer If non-zero, also setup monitoring (ms)
565                  */
566                 void getObject(
567                         ModulePtr mod, const std::string &name,
568                         bool recurse = true, uint32_t monitorTimer = 0
569                 );
570                 /**
571                  * Requests monitoring to be set up for the object
572                  *
573                  * @param obj       Object to be monitored
574                  * @param interval  Minimum update interval (ms)
575                  */
576                 void monitorObject(ObjectPtr obj, uint32_t interval);
577
578                 void doObjectOper(
579                         ObjectPtr obj, const std::string &opName,
580                         const std::map<std::string, std::string> &args
581                 );
582                 void setObjectData(
583                         ObjectPtr obj, uint8_t dNum, const std::string &newValue
584                 );
585
586                 typedef std::map<uint32_t, ObjectPtr>::iterator OIter;
587                 typedef std::map<uint32_t, ObjectPtr>::const_iterator OCIter;
588
589                 ObjectPtr findObject(uint32_t id) const {
590                         OCIter i = m_objects.find(id);
591                         if (i != m_objects.end()) {
592                                 return i->second;
593                         } else {
594                                 return ObjectPtr();
595                         }
596                 }
597
598                 /**
599                  * Emitted when an object is received from core. Note that when
600                  * receiving multiple objects in a tree, this is emitted only
601                  * for the top-most tree object, instead of for each subobject
602                  * of the tree.
603                  */
604                 boost::signal<void (ObjectPtr)> receivedObject;
605
606                 /**
607                  * Signaled when an object has been updated. This is emitted
608                  * for each object that was updated.
609                  */
610                 boost::signal<void (ObjectPtr)> updatedObject;
611
612                 boost::signal<void (ObjectPtr)> addedObject;
613                 boost::signal<void (ObjectPtr)> removedObject;
614         protected:
615                 virtual void handle(std::istream &i);
616         private:
617                 std::map<uint32_t, ModulePtr> m_list;
618
619                 std::map<uint32_t, ObjectPtr> m_objects;
620
621                 ModulePtr readModule(std::istream &i);
622                 ObjectPtr readObject(std::istream &i);
623         };
624
625 } // end namespace Engine
626
627 #endif
Note: See TracBrowser for help on using the browser.