1 // Copyright (C) 2013 James Turner - zakalawe@mac.com 2 // 3 // This library is free software; you can redistribute it and/or 4 // modify it under the terms of the GNU Library General Public 5 // License as published by the Free Software Foundation; either 6 // version 2 of the License, or (at your option) any later version. 7 // 8 // This library is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 // Library General Public License for more details. 12 // 13 // You should have received a copy of the GNU General Public License 14 // along with this program; if not, write to the Free Software 15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 16 // 17 18 #ifndef SG_PACKAGE_INSTALL_HXX 19 #define SG_PACKAGE_INSTALL_HXX 20 21 #include <vector> 22 23 #include <simgear/misc/sg_path.hxx> 24 #include <simgear/misc/sg_dir.hxx> 25 #include <simgear/package/Delegate.hxx> 26 27 #include <simgear/structure/function_list.hxx> 28 #include <simgear/structure/SGReferenced.hxx> 29 #include <simgear/structure/SGSharedPtr.hxx> 30 #include <simgear/io/HTTPRequest.hxx> 31 32 namespace simgear 33 { 34 35 namespace pkg 36 { 37 38 // forward decls 39 class Package; 40 class Catalog; 41 class Install; 42 43 typedef SGSharedPtr<Package> PackageRef; 44 typedef SGSharedPtr<Catalog> CatalogRef; 45 typedef SGSharedPtr<Install> InstallRef; 46 47 /** 48 * 49 */ 50 class Install : public SGReferenced 51 { 52 public: 53 virtual ~Install(); 54 55 typedef std::function<void(Install*)> Callback; 56 typedef std::function<void(Install*, unsigned int, unsigned int)> ProgressCallback; 57 58 /** 59 * create from a directory on disk, or fail. 60 */ 61 static InstallRef createFromPath(const SGPath& aPath, CatalogRef aCat); 62 revsion() const63 unsigned int revsion() const 64 { return m_revision; } 65 package() const66 PackageRef package() const 67 { return m_package; } 68 path() const69 SGPath path() const 70 { return m_path; } 71 72 bool hasUpdate() const; 73 74 void startUpdate(); 75 76 bool uninstall(); 77 78 bool isDownloading() const; 79 80 bool isQueued() const; 81 82 int downloadedPercent() const; 83 84 size_t downloadedBytes() const; 85 86 Delegate::StatusCode status() const; 87 88 /** 89 * full path to the primary -set.xml file for this install 90 */ 91 SGPath primarySetPath() const; 92 93 /** 94 * if a download is in progress, cancel it. If this is the first install 95 * of the package (as opposed to an update), the install will be cleaned 96 * up once the last reference is gone. 97 */ 98 void cancelDownload(); 99 100 /** 101 * Set the handler to be called when the installation successfully 102 * completes. 103 * 104 * @note If the installation is already complete, the handler is called 105 * immediately. 106 */ 107 Install* done(const Callback& cb); 108 109 template<class C> done(C * instance,void (C::* mem_func)(Install *))110 Install* done(C* instance, void (C::*mem_func)(Install*)) 111 { 112 return done(std::bind(mem_func, instance, std::placeholders::_1)); 113 } 114 115 /** 116 * Set the handler to be called when the installation fails or is aborted. 117 * 118 * @note If the installation has already failed, the handler is called 119 * immediately. 120 */ 121 Install* fail(const Callback& cb); 122 123 template<class C> fail(C * instance,void (C::* mem_func)(Install *))124 Install* fail(C* instance, void (C::*mem_func)(Install*)) 125 { 126 return fail(std::bind(mem_func, instance, std::placeholders::_1)); 127 } 128 129 /** 130 * Set the handler to be called when the installation either successfully 131 * completes or fails. 132 * 133 * @note If the installation is already complete or has already failed, the 134 * handler is called immediately. 135 */ 136 Install* always(const Callback& cb); 137 138 template<class C> always(C * instance,void (C::* mem_func)(Install *))139 Install* always(C* instance, void (C::*mem_func)(Install*)) 140 { 141 return always(std::bind(mem_func, instance, std::placeholders::_1)); 142 } 143 144 /** 145 * Set the handler to be called during downloading the installation file 146 * indicating the progress of the download. 147 * 148 */ 149 Install* progress(const ProgressCallback& cb); 150 151 template<class C> progress(C * instance,void (C::* mem_func)(Install *,unsigned int,unsigned int))152 Install* progress(C* instance, 153 void (C::*mem_func)(Install*, unsigned int, unsigned int)) 154 { 155 return progress(std::bind(mem_func, 156 instance, 157 std::placeholders::_1, 158 std::placeholders::_2, 159 std::placeholders::_3)); 160 } 161 162 private: 163 friend class Package; 164 165 class PackageArchiveDownloader; 166 friend class PackageArchiveDownloader; 167 168 Install(PackageRef aPkg, const SGPath& aPath); 169 170 void parseRevision(); 171 void writeRevisionFile(); 172 173 void installResult(Delegate::StatusCode aReason); 174 void installProgress(unsigned int aBytes, unsigned int aTotal); 175 void startDownload(); 176 177 PackageRef m_package; 178 unsigned int m_revision; ///< revision on disk 179 SGPath m_path; ///< installation point on disk 180 181 HTTP::Request_ptr m_download; 182 183 Delegate::StatusCode m_status; 184 185 function_list<Callback> _cb_done, 186 _cb_fail, 187 _cb_always; 188 function_list<ProgressCallback> _cb_progress; 189 }; 190 191 192 } // of namespace pkg 193 194 } // of namespace simgear 195 196 #endif // of SG_PACKAGE_CATALOG_HXX 197