mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 04:57:00 -04:00
200 lines
8.7 KiB
C++
200 lines
8.7 KiB
C++
//+----------------------------------------------------------------------------+
|
|
//| Description: Magic Set Editor - Program to make card games |
|
|
//| Copyright: (C) Twan van Laarhoven and the other MSE developers |
|
|
//| License: GNU General Public License 2 or later (see file COPYING) |
|
|
//+----------------------------------------------------------------------------+
|
|
|
|
#pragma once
|
|
|
|
// ----------------------------------------------------------------------------- : Includes
|
|
|
|
#include <util/prec.hpp>
|
|
#include <util/io/package.hpp>
|
|
|
|
DECLARE_POINTER_TYPE(Installer);
|
|
DECLARE_POINTER_TYPE(PackageVersion);
|
|
DECLARE_POINTER_TYPE(PackageDescription);
|
|
DECLARE_POINTER_TYPE(DownloadableInstaller);
|
|
DECLARE_POINTER_TYPE(InstallablePackage);
|
|
|
|
// The installer system consists of several layers:
|
|
// - Installer = an actual package available in memory, containing packages to be installed
|
|
// - DownloadableInstaller = an installar (possibly) not yet available, i.e. just its URL
|
|
// - PackageDescription = description of a package version
|
|
// - InstallablePackage = the complete status of a package, both local and remote
|
|
|
|
|
|
// ----------------------------------------------------------------------------- : Installer
|
|
|
|
/// A package that contains other packages that can be installed
|
|
/** Installers will be sent around the internet, etc. so they are fairly selfcontained.
|
|
*/
|
|
class Installer : public Packaged {
|
|
public:
|
|
String prefered_filename; ///< What filename should be used (by default), when creating the installer
|
|
vector<PackageDescriptionP> packages; ///< Packages to install
|
|
|
|
/// Add a package to the installer (if it is not already added).
|
|
/** If the package is named *.mse-installer uses it as the filename instead */
|
|
void addPackage(const String& package);
|
|
/// Add a package to the installer (if it is not already added).
|
|
/** The first package gives the name of the installer.
|
|
*/
|
|
void addPackage(Packaged& package);
|
|
|
|
protected:
|
|
String typeName() const override;
|
|
Version fileVersion() const override;
|
|
void validate(Version file_app_version) override;
|
|
DECLARE_REFLECTION();
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------- : Installer descriptions
|
|
|
|
/// A description of a package in an installer.
|
|
/** This is essentially the same information as in a Packaged object.
|
|
* TODO: try to merge these!
|
|
*/
|
|
class PackageDescription : public IntrusivePtrBase<PackageDescription> {
|
|
public:
|
|
PackageDescription();
|
|
PackageDescription(const Packaged& package);
|
|
|
|
String name; ///< Filename of the package
|
|
Version version; ///< Version number of this package
|
|
String short_name; ///< Short name of this package
|
|
String full_name; ///< Name of this package, for menus etc.
|
|
String icon_url; ///< Filename or URL of icon to use in package lists
|
|
String dark_icon_url; ///< Filename or URL of icon to use in package lists
|
|
Image icon; ///< Icon for the package
|
|
String installer_group; ///< Where to put this package in the installer
|
|
int position_hint; ///< A hint for the package list
|
|
String description; ///< Changelog/description
|
|
vector<PackageDependencyP> dependencies; ///< Dependencies of this package
|
|
|
|
/// Merge two descriptions a package. This package takes precedence
|
|
/** Usually one of the descriptions will refer to the locally installed one, the other to the new one */
|
|
void merge(const PackageDescription& p2);
|
|
|
|
DECLARE_REFLECTION();
|
|
};
|
|
|
|
/// A description of the contents of an installer
|
|
class InstallerDescription : public IntrusivePtrBase<InstallerDescription> {
|
|
public:
|
|
vector<PackageDescriptionP> packages;
|
|
|
|
DECLARE_REFLECTION();
|
|
};
|
|
|
|
/// Information on an installer that can be downloaded
|
|
class DownloadableInstaller : public IntrusivePtrBase<DownloadableInstaller> {
|
|
public:
|
|
DownloadableInstaller() : downloadable(true) {}
|
|
DownloadableInstaller(const InstallerP& installer);
|
|
~DownloadableInstaller();
|
|
|
|
InstallerP installer; ///< The installer, if it is loaded
|
|
String installer_url; ///< The URL where the installer can be found
|
|
String installer_file; ///< The temp file where the installer can be found (after downloading)
|
|
bool downloadable; ///< Is the installer downloadable (in)directly from that url?
|
|
vector<PackageDescriptionP> packages; ///< Packages provided by this installer
|
|
|
|
DECLARE_REFLECTION();
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------- : Installable package
|
|
|
|
/// Installation status of a package
|
|
enum PackageStatus
|
|
{ PACKAGE_NOT_INSTALLED = 0x0000
|
|
, PACKAGE_INSTALLED = 0x0001
|
|
, PACKAGE_REMOVABLE = 0x0002
|
|
, PACKAGE_INSTALLER = 0x0010 ///< Package can be installed (there is an installer)
|
|
, PACKAGE_INSTALLABLE = 0x0110 ///< Package can be installed (and it makes sense to do so)
|
|
, PACKAGE_NOT_UP_TO_DATE= 0x0200 ///< The local installed version (if any) is not up to date
|
|
, PACKAGE_UPDATES = 0x0311 ///< Remote updates available
|
|
, PACKAGE_MODIFIED = 0x1001 ///< Local changes made
|
|
, PACKAGE_MISSING_DEP = 0x2000 ///< Missing a dependency for installation
|
|
, PACKAGE_CONFLICTS = PACKAGE_UPDATES | PACKAGE_MODIFIED
|
|
};
|
|
|
|
/// (un)install a package?
|
|
enum PackageAction
|
|
{ PACKAGE_ACT_NOTHING = 0x001 ///< Don't change anything
|
|
, PACKAGE_ACT_INSTALL = 0x002 ///< Install or upgrade the package
|
|
, PACKAGE_ACT_REMOVE = 0x004 ///< Remove the package (if it was installed)
|
|
, PACKAGE_ACT_LOCAL = 0x010 ///< In the local package directory
|
|
, PACKAGE_ACT_GLOBAL = 0x020 ///< In the global package directory
|
|
, PACKAGE_ACT_WHERE = PACKAGE_ACT_LOCAL | PACKAGE_ACT_GLOBAL
|
|
};
|
|
// bit twidling
|
|
inline PackageAction operator | (PackageAction a, PackageAction b) { return (PackageAction)((int)a | (int) b); }
|
|
inline bool flag(int flags, int flag) { return (flags & flag) == flag; }
|
|
|
|
/// A package that can be installed, or is already installed
|
|
class InstallablePackage : public IntrusivePtrVirtualBase {
|
|
public:
|
|
/// A new package
|
|
InstallablePackage(const PackageDescriptionP&, const DownloadableInstallerP&);
|
|
/// An installed package
|
|
InstallablePackage(const PackageDescriptionP&, const PackageVersionP&);
|
|
|
|
PackageDescriptionP description; ///< The details of the package. Either from the installed package or from an installer
|
|
PackageVersionP installed; ///< The information of the installed package (if installed)
|
|
DownloadableInstallerP installer; ///< The installer to install from (if updates are available)
|
|
PackageStatus status; ///< Status of installation
|
|
PackageAction action; ///< What to do with this package?
|
|
|
|
int automatic; ///< Install/upgrade/remove automaticly to satisfy this many packages
|
|
|
|
PackageAction old_action;
|
|
int old_automatic;
|
|
|
|
void determineStatus();
|
|
bool ensureIsDownloaded();
|
|
|
|
/// After the action, will the package be installed?
|
|
bool willBeInstalled() const;
|
|
|
|
/// Is the action possible?
|
|
bool can(PackageAction act) const;
|
|
/// Is the action currently selected?
|
|
bool has(PackageAction act) const;
|
|
/// Does the package have the given status bits all set?
|
|
bool has(PackageStatus stat) const;
|
|
|
|
/// Merge two descriptions of installable packages
|
|
void merge(const InstallablePackage& p2);
|
|
};
|
|
|
|
|
|
typedef vector<InstallablePackageP> InstallablePackages;
|
|
|
|
/// Sort a list of InstallablePackages by package name
|
|
void sort(InstallablePackages& packages);
|
|
|
|
/// Merge two lists of InstallablePackages.
|
|
/** The first list contains installed packages, the second list contains packages in an installer
|
|
* @pre both lists are sorted by package name
|
|
* @post the output will be sorted
|
|
*/
|
|
void merge(InstallablePackages& installed, const InstallablePackages& from_installer);
|
|
|
|
/// Merge the packages from a DownloadableInstaller into a list of InstallablePackages.
|
|
void merge(InstallablePackages& installed, const DownloadableInstallerP& installer);
|
|
|
|
/// Set the action to perform on a given package, makes sure the dependencies are also set correctly
|
|
/** Returns true on success
|
|
* action may be PACKAGE_NOTHING to clear the action
|
|
*/
|
|
bool set_package_action(InstallablePackages& packages, const InstallablePackageP& package, PackageAction action);
|
|
|
|
// ----------------------------------------------------------------------------- : Program package
|
|
|
|
/// The "Magic Set Editor" package is special, it refers to the program
|
|
extern String mse_package;
|
|
|
|
InstallablePackageP mse_installable_package();
|
|
|