Skip to content

Commit 4ef8f49

Browse files
authored
Merge pull request #70 from oblivioncth/dev
Merge to master for v0.8.1
2 parents 0a9df7c + c9d6193 commit 4ef8f49

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+3871
-1309
lines changed

.github/workflows/build-project.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ jobs:
2121
secrets:
2222
ffynnon_access: ${{ secrets.OBYBOT_FFYNNON_ACCESS }}
2323
with:
24+
qt_version: 6.8.2
2425
runs_exclude: >
2526
[
2627
{ "linkage": "shared" },
@@ -31,17 +32,16 @@ jobs:
3132
]
3233
runs_include: >
3334
[
34-
{ "os": "ubuntu-20.04", "compiler": "clang++-18", "linkage": "static" },
35-
{ "os": "ubuntu-22.04", "compiler": "clang++-18", "linkage": "static" }
35+
{ "os": "ubuntu-22.04", "compiler": "clang++-18", "linkage": "static" },
36+
{ "os": "ubuntu-24.04", "compiler": "clang++-18", "linkage": "static" },
37+
{ "os": "ubuntu-24.04", "compiler": "g++-14", "linkage": "static" }
3638
]
3739
pre_build_steps: |
3840
- name: Install Clang 18 [Linux]
39-
if: env.run_is_linux == 'true' && env.run_compiler == 'clang++-18'
41+
if: env.run_os == 'ubuntu-22.04' && env.run_compiler == 'clang++-18'
4042
shell: bash
4143
run: |
4244
wget https://apt.llvm.org/llvm.sh
4345
chmod u+x llvm.sh
4446
sudo ./llvm.sh 18
4547
46-
47-

CMakeLists.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ cmake_minimum_required(VERSION 3.24.0...3.30.0)
66
# Project
77
# NOTE: DON'T USE TRAILING ZEROS IN VERSIONS
88
project(FIL
9-
VERSION 0.8
9+
VERSION 0.8.1
1010
LANGUAGES CXX
1111
DESCRIPTION "Flashpoint Importer for Launchers"
1212
)
@@ -74,20 +74,20 @@ endif()
7474

7575
include(OB/FetchQx)
7676
ob_fetch_qx(
77-
REF "v0.6.1"
77+
REF "v0.6.2"
7878
COMPONENTS
7979
${FIL_QX_COMPONENTS}
8080
)
8181

8282
# Fetch libfp (build and import from source)
8383
include(OB/Fetchlibfp)
84-
ob_fetch_libfp("v0.5.5")
84+
ob_fetch_libfp("v0.5.6")
8585

8686
# Fetch CLIFp (build and import from source)
8787
include(OB/Utility)
8888
ob_cache_project_version(CLIFp)
8989
include(OB/FetchCLIFp)
90-
ob_fetch_clifp("v0.9.13")
90+
ob_fetch_clifp("v0.9.14")
9191

9292
# TODO: The shared build of this is essentially useless as only the CLIFp executable
9393
# is deployed, which only works if it's statically linked. There isn't a simple way

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ You will still be able to use the standard Flashpoint launcher as normal after c
2525
### Supported Launchers
2626
- [LaunchBox](https://www.launchbox-app.com/)
2727
- [AttractMode](http://attractmode.org/)
28+
- [ES-DE](https://es-de.org/)
2829

2930
### Flashpoint
3031
While testing for 100% compatibility is infeasible given the size of Flashpoint, FIL was designed with full compatibility in mind.

app/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ set(FIL_SOURCE
2727
import/backup.cpp
2828
import/details.h
2929
import/details.cpp
30+
import/image.h
31+
import/image.cpp
3032
import/properties.h
3133
import/properties.cpp
3234
import/settings.h
@@ -54,6 +56,16 @@ set(FIL_SOURCE
5456
launcher/implementation/attractmode/am-settings-items.cpp
5557
launcher/implementation/attractmode/am-registration.h
5658
launcher/implementation/attractmode/am-registration.cpp
59+
launcher/implementation/emulationstation/es-data.h
60+
launcher/implementation/emulationstation/es-data.cpp
61+
launcher/implementation/emulationstation/es-install.h
62+
launcher/implementation/emulationstation/es-install.cpp
63+
launcher/implementation/emulationstation/es-install_win.cpp
64+
launcher/implementation/emulationstation/es-install_linux.cpp
65+
launcher/implementation/emulationstation/es-items.h
66+
launcher/implementation/emulationstation/es-items.cpp
67+
launcher/implementation/emulationstation/es-registration.h
68+
launcher/implementation/emulationstation/es-registration.cpp
5769
launcher/interface/lr-data-interface.h
5870
launcher/interface/lr-data-interface.cpp
5971
launcher/interface/lr-install-interface.h
5.47 KB
Loading

app/res/resources.qrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
<file>launcher/LaunchBox/icon.svg</file>
1212
<file>launcher/AttractMode/icon.png</file>
1313
<file>launcher/AttractMode/marquee.png</file>
14+
<file>launcher/EmulationStation/icon.png</file>
1415
<file>flashpoint/icon.png</file>
1516
<file>ui/About.png</file>
1617
</qresource>

app/src/import/backup.cpp

Lines changed: 58 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
#include <QFile>
66
#include <QFileInfo>
77

8+
// Qx Includes
9+
#include <qx/io/qx-common-io.h>
10+
811
namespace Import
912
{
1013

@@ -59,12 +62,12 @@ BackupManager* BackupManager::instance() { static BackupManager inst; return &in
5962
//Private:
6063
BackupError BackupManager::backup(const QString& path, bool (*fn)(const QString& a, const QString& b))
6164
{
62-
// Prevent double+ backups (THIS IS CRITICAL, HENCE WHY A SET IS USED)
63-
if(mRevertablePaths.contains(path))
65+
// Prevent double+ backups (THIS IS CRITICAL, HENCE WHY A HASH IS USED)
66+
if(mRevertables.contains(path))
6467
return BackupError();
6568

6669
// Note revertable
67-
mRevertablePaths.insert(path);
70+
mRevertables[path] = false;
6871

6972
// Backup if exists
7073
if(QFile::exists(path))
@@ -84,12 +87,12 @@ BackupError BackupManager::backup(const QString& path, bool (*fn)(const QString&
8487
return BackupError();
8588
}
8689

87-
BackupError BackupManager::restore(QSet<QString>::const_iterator pathItr)
90+
BackupError BackupManager::restore(RevertItr itr)
8891
{
89-
Q_ASSERT(pathItr != mRevertablePaths.cend());
92+
Q_ASSERT(itr != mRevertables.cend());
9093

91-
const QString path = *pathItr;
92-
mRevertablePaths.erase(pathItr);
94+
const QString path = itr.key();
95+
mRevertables.erase(itr);
9396
QString backupPath = filePathToBackupPath(path);
9497

9598
if(QFile::exists(path) && !QFile::remove(path))
@@ -114,8 +117,8 @@ BackupError BackupManager::backupRename(const QString& path)
114117

115118
BackupError BackupManager::restore(const QString& path)
116119
{
117-
auto store = mRevertablePaths.constFind(path);
118-
if(store == mRevertablePaths.cend())
120+
auto store = mRevertables.constFind(path);
121+
if(store == mRevertables.cend())
119122
return BackupError();
120123

121124
return restore(store);
@@ -151,31 +154,72 @@ BackupError BackupManager::safeReplace(const QString& src, const QString& dst, b
151154
if(dstOccupied)
152155
QFile::remove(backupPath);
153156
else // Mark new files (only) as revertible so that existing ones will remain in the event of a revert
154-
mRevertablePaths.insert(dst);
157+
mRevertables[dst] = false;
158+
159+
return BackupError();
160+
}
161+
162+
BackupError BackupManager::revertableTouch(const QString& path)
163+
{
164+
if(!Qx::createFile(path))
165+
return BackupError(BackupError::FileWontCreate, path);
155166

167+
mRevertables[path] = false;
156168
return BackupError();
157169
}
158170

159-
int BackupManager::revertQueueCount() const { return mRevertablePaths.size(); }
171+
// - Backs up the file at 'path' via copy, and then deletes the backup at the end of the import
172+
// - File is restored on revert.
173+
BackupError BackupManager::revertableRemove(const QString& path)
174+
{
175+
// TODO: Use this for AM extra files
176+
QString backupPath = filePathToBackupPath(path);
177+
178+
if(QFile::exists(backupPath) && QFileInfo(backupPath).isFile())
179+
{
180+
if(!QFile::remove(backupPath))
181+
return BackupError(BackupError::FileWontDelete, backupPath);
182+
}
183+
184+
if(!QFile::rename(path, backupPath))
185+
return BackupError(BackupError::FileWontBackup, path);
186+
187+
mRevertables[path] = true;
188+
return BackupError();
189+
}
190+
191+
bool BackupManager::hasReversions() const { return !mRevertables.isEmpty(); }
192+
int BackupManager::revertQueueCount() const { return mRevertables.size(); }
160193

161194
int BackupManager::revertNextChange(BackupError& error, bool skipOnFail)
162195
{
163196
// Ensure error message is null
164197
error = BackupError();
165198

166199
// Delete new files and restore backups if present
167-
if(!mRevertablePaths.isEmpty())
200+
if(!mRevertables.isEmpty())
168201
{
169-
BackupError rErr = restore(mRevertablePaths.cbegin());
202+
BackupError rErr = restore(mRevertables.cbegin());
170203
if(rErr && !skipOnFail)
171204
error = rErr;
172205

173-
return mRevertablePaths.size();
206+
return mRevertables.size();
174207
}
175208

176209
// Return 0 if all empty (shouldn't be reached if function is used correctly)
177210
qWarning("Reversion function called with no reverts left!");
178211
return 0;
179212
}
180213

214+
void BackupManager::purge()
215+
{
216+
for(auto itr = mRevertables.cbegin(); itr != mRevertables.cend();)
217+
{
218+
bool purge = itr.value();
219+
if(purge)
220+
QFile::remove(itr.key());
221+
itr = mRevertables.erase(itr); // clazy:exclude=strict-iterators
222+
}
223+
}
224+
181225
}

app/src/import/backup.h

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
#ifndef BACKUP_H
2-
#define BACKUP_H
1+
#ifndef IMPORT_BACKUP_H
2+
#define IMPORT_BACKUP_H
33

44
// Qt Includes
55
#include <QString>
@@ -28,7 +28,8 @@ class QX_ERROR_TYPE(BackupError, "Lr::BackupError", 1301)
2828
FileWontDelete,
2929
FileWontRestore,
3030
FileWontBackup,
31-
FileWontReplace
31+
FileWontReplace,
32+
FileWontCreate
3233
};
3334

3435
//-Class Variables-------------------------------------------------------------
@@ -38,7 +39,8 @@ class QX_ERROR_TYPE(BackupError, "Lr::BackupError", 1301)
3839
{FileWontDelete, u"Cannot remove a file. It may need to be deleted manually."_s},
3940
{FileWontRestore, u"Cannot restore a file backup. It may need to be renamed manually.."_s},
4041
{FileWontBackup, u"Cannot backup file."_s},
41-
{FileWontReplace, u"A file that was part of a safe replace operation could not be transfered."_s}
42+
{FileWontReplace, u"A file that was part of a safe replace operation could not be transferred."_s},
43+
{FileWontCreate, u"A file that was part of a safe touch operation could not be created."_s}
4244
};
4345

4446
static inline const QString CAPTION_REVERT_ERR = u"Error managing backups"_s;
@@ -71,14 +73,21 @@ class QX_ERROR_TYPE(BackupError, "Lr::BackupError", 1301)
7173

7274
class BackupManager
7375
{
74-
//-Class Variables-----------------------------------------------------------------------------------------------
76+
//-Aliases---------------------------------------------------------------------------
77+
private:
78+
using OriginalPath = QString;
79+
using Purge = bool;
80+
using Reverts = QHash<OriginalPath, Purge>;
81+
using RevertItr = Reverts::const_iterator;
82+
83+
//-Class Variables-------------------------------------------------------------------
7584
private:
7685
// Files
7786
static inline const QString BACKUP_FILE_EXT = u"fbk"_s;
7887

7988
//-Instance Variables-------------------------------------------------------------
8089
private:
81-
QSet<QString> mRevertablePaths;
90+
Reverts mRevertables;
8291

8392
//-Constructor-------------------------------------------------------------
8493
private:
@@ -94,18 +103,43 @@ class BackupManager
94103
//-Instance Functions-------------------------------------------------------------
95104
private:
96105
BackupError backup(const QString& path, bool (*fn)(const QString& a, const QString& b));
97-
BackupError restore(QSet<QString>::const_iterator pathItr);
106+
BackupError restore(RevertItr itr);
98107

99108
public:
109+
// - If it exists, backs up 'path' via copy, original remains in place to be worked on
110+
// - Backup is restored on revert
111+
// - 'path' is marked such that any new file placed there is deleted on revert
100112
BackupError backupCopy(const QString& path);
113+
114+
// - If it exists, backs up 'path' via rename, original remains in place to be worked on
115+
// - Backup is restored on revert
116+
// - 'path' is marked such that any new file placed there is deleted on revert
101117
BackupError backupRename(const QString& path);
118+
119+
// - Immediately restores a backed up file using its original path
102120
BackupError restore(const QString& path);
121+
122+
// - Replaces dst with src (via a copy or symlink)
123+
// - dst, if present, if temporarily backed up in case the replacement fails and is immediately
124+
// is restored if so. If the replacement succeeds the backup is immediately deleted
125+
// - If dst is new (did not originally exist), the file is marked as revertable for if
126+
// a revert occurs
103127
BackupError safeReplace(const QString& src, const QString& dst, bool symlink);
104128

129+
// - Creates an empty file at 'path' (fails if it already exists) and marks it for deletion
130+
// in the event of a revert
131+
BackupError revertableTouch(const QString& path);
132+
133+
// - Backs up the file at 'path' via copy, and then deletes the backup at the end of the import
134+
// - File is restored on revert.
135+
BackupError revertableRemove(const QString& path);
136+
137+
bool hasReversions() const;
105138
int revertQueueCount() const;
106139
int revertNextChange(BackupError& error, bool skipOnFail);
140+
void purge();
107141
};
108142

109143
}
110144

111-
#endif // BACKUP_H
145+
#endif // IMPORT_BACKUP_H

0 commit comments

Comments
 (0)