Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Git ui /egm integration WIP #198

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ set(RGM_SOURCES
Components/Utility.cpp
Components/QMenuView.cpp
Components/RecentFiles.cpp
Components/GitTreeItem.cpp
Components/GitTreeStyledDelegate.cpp
Components/EGMManager.cpp
Models/TreeSortFilterProxyModel.cpp
Models/MessageModel.cpp
Models/RepeatedImageModel.cpp
Expand All @@ -72,6 +75,7 @@ set(RGM_SOURCES
Models/EventsListModel.cpp
Models/EventTypesListModel.cpp
Models/EventTypesListSortFilterProxyModel.cpp
Models/GitHistoryModel.cpp
Editors/ObjectEditor.cpp
Editors/PathEditor.cpp
Editors/CodeEditor.cpp
Expand Down Expand Up @@ -112,6 +116,9 @@ set(RGM_HEADERS
Components/ArtManager.h
Components/QMenuView_p.h
Components/Utility.h
Components/GitTreeItem.h
Components/GitTreeStyledDelegate.h
Components/EGMManager.h
Models/TreeModel.h
Models/RepeatedStringModel.h
Models/ResourceModelMap.h
Expand All @@ -126,6 +133,7 @@ set(RGM_HEADERS
Models/EventsListModel.h
Models/EventTypesListModel.h
Models/EventTypesListSortFilterProxyModel.h
Models/GitHistoryModel.cpp
Editors/FontEditor.h
Editors/PathEditor.h
Editors/SpriteEditor.h
Expand Down Expand Up @@ -276,6 +284,12 @@ find_package(Freetype REQUIRED)
include_directories(${FREETYPE_INCLUDE_DIRS})
target_link_libraries(${EXE} PRIVATE ${FREETYPE_LIBRARIES})

# Find libgit2
find_path(GIT2_INCLUDE_PATH NAMES git2.h)
include_directories(${GIT2_INCLUDE_PATH})
find_library(GIT2_LIBRARIES git2)
target_link_libraries(${EXE} PRIVATE ${GIT2_LIBRARIES})

# Find JPEG
find_library(LIB_JPEG NAMES jpeg)
target_link_libraries(${EXE} PRIVATE ${LIB_JPEG})
Expand Down
239 changes: 239 additions & 0 deletions Components/EGMManager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
#include "MainWindow.h"
#include "EGMManager.h"
#include "gmk.h"
#include "gmx.h"
#include "yyp.h"
#include "filesystem.h"

#include <QDebug>
#include <QErrorMessage>
#include <QFile>
#include <QFileInfo>
#include <QTemporaryDir>

EGMManager::EGMManager() : _repo(nullptr) {
LoadEventData(MainWindow::EnigmaRoot.absolutePath() + "/events.ey");
qDebug() << "Intializing git library";
git_libgit2_init();
connect(&_gitHistoryModel, &GitHistoryModel::GitError, this, &EGMManager::GitError);
}

EGMManager::~EGMManager() {
git_tree_free(_git_tree);
git_signature_free(_git_sig);
git_repository_free(_repo);
git_libgit2_shutdown();
}

buffers::Project* EGMManager::NewProject() {
_resChangeModel.ClearChanges();

_project = std::make_unique<buffers::Project>();
QTemporaryDir dir;
dir.setAutoRemove(false);
_rootPath = dir.path();
InitRepo();
return _project.get();
}

buffers::Project* EGMManager::LoadProject(const QString& fPath) {
_resChangeModel.ClearChanges();

QFileInfo fileInfo(fPath);
const QString suffix = fileInfo.suffix();

_project = egm::LoadProject(fPath.toStdString());

return _project.get();
}

buffers::Game* EGMManager::GetGame() { return _project->mutable_game(); }

ResourceChangesModel& EGMManager::GetResourceChangesModel() {
return _resChangeModel;
}

GitHistoryModel& EGMManager::GetGitHistoryModel() {
return _gitHistoryModel;
}

void EGMManager::ResourceChanged(Resource& res, ResChange change, const QString& oldName) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this method I need help with and is very incomplete

_resChangeModel.ResourceChanged(res, change, oldName);

QString dir =_rootPath;// + "get the res path somehow???";

// Clear the existing folder I guess
//if (FolderExists(dir.toStdString())) RemoveDir(dir);

if (change != ResChange::Removed) {
egm::WriteResource(res.buffer, dir.toStdString());
//AddFile(res.name + ".ext"); ??
}
}

bool EGMManager::LoadEventData(const QString& fPath) {
QFile f(fPath);
if (f.exists()) {
_event_data = std::make_unique<EventData>(ParseEventFile(fPath.toStdString()));
} else {
qDebug() << "Error: Failed to load events file. Loading internal events.ey.";
QFile internal_events(":/events.ey");
internal_events.open(QIODevice::ReadOnly | QFile::Text);
std::stringstream ss;
ss << internal_events.readAll().toStdString();
_event_data = std::make_unique<EventData>(ParseEventFile(ss));
}

egm::LibEGMInit(_event_data.get());

return _event_data->events().size() > 0;
}

EventData* EGMManager::GetEventData() { return _event_data.get(); }

git_commit* EGMManager::GitLookUp(const git_oid* id) {
git_commit* commit = nullptr;
int error = git_commit_lookup(&commit, _repo, id);
if (error != 0) GitError();
return commit;
}

bool EGMManager::InitRepo() {
qDebug() << "Intializing git repository at: " << _rootPath;
git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT;
opts.description = "ENIGMA Game";
int error = git_repository_init_ext(&_repo, _rootPath.toStdString().c_str(), &opts);
if (error != 0) {
GitError();
return false;
}

error = git_signature_default(&_git_sig, _repo);
if (error != 0) {
GitError();
return false;
}

error = git_repository_index(&_git_index, _repo);
if (error != 0) {
GitError();
return false;
}
error = git_index_write_tree(&_git_tree_id, _git_index);
if (error != 0) {
GitError();
return false;
}
error = git_tree_lookup(&_git_tree, _repo, &_git_tree_id);
if (error != 0) {
GitError();
return false;
}

error = git_commit_create_v(&_git_commit_id, _repo, "HEAD", _git_sig, _git_sig, NULL, "Initial commit", _git_tree, 0);
if (error != 0) {
GitError();
return false;
}

_gitHistoryModel.LoadRepo(_repo);

return CreateBranch("RadialGM") && Checkout("refs/heads/RadialGM");
}

bool EGMManager::CreateBranch(const QString& branchName) {
qDebug() << "Creating git branch: " << branchName;
git_commit* c = GitLookUp(&_git_commit_id);
git_reference* ref = nullptr;
int error = git_branch_create(&ref, _repo, branchName.toStdString().c_str(), c, 0);
git_reference_free(ref);
if (error != 0) {
GitError();
return false;
}
return true;
}

bool EGMManager::Checkout(const QString& ref) {
qDebug() << "Checking out git reference: " << ref;
int error = git_repository_set_head(_repo, ref.toStdString().c_str());
if (error != 0) {
GitError();
return false;
}
return true;
}

/*bool EGMManager::CheckoutFile(const QString& ref, const QString& file) {
}*/

bool EGMManager::AddFile(const QString& file) {
qDebug() << "Adding file to EGM: " << file;
int error = git_index_add_bypath(_git_index, file.toStdString().c_str());
if (error != 0) {
GitError();
return false;
}
return true;
}

bool EGMManager::RemoveFile(const QString& file) {
qDebug() << "Removing file from EGM: " << file;
int error = git_index_remove_bypath(_git_index, file.toStdString().c_str());
if (error != 0) {
GitError();
return false;
}
return true;
}

bool EGMManager::RemoveDir(const QString& dir) {
qDebug() << "Removing directory from EGM: " << dir;
DeleteFolder(dir.toStdString());
int error = git_index_remove_directory(_git_index, dir.toStdString().c_str(), 0);
if (error != 0) {
GitError();
return false;
}
return true;
}

bool EGMManager::CommitChanges(const QString& message) {
qDebug() << "Commiting changes";
int error = git_commit_create_v(&_git_commit_id, _repo, "HEAD", _git_sig, _git_sig, NULL,
message.toStdString().c_str(), _git_tree, 0);
if (error != 0) {
GitError();
return false;
}
return true;
}

/*bool EGMManager::AddRemote(const QString& url) {

}

bool EGMManager::ChangeRemote(unsigned index, const QString& url) {

}

bool EGMManager::RemoveRemote(unsigned index) {

}

const QStringList& EGMManager::GetRemotes() const {

}

bool EGMManager::PushChanges() {

}*/

bool EGMManager::Save(const QString& fPath) {
return false;
}

void EGMManager::GitError() {
const git_error* e = git_error_last();
qDebug() << QString("Git Error: ") + e->message;
}
66 changes: 66 additions & 0 deletions Components/EGMManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#ifndef EGMMANAGER_H
#define EGMMANAGER_H

#include "Models/ResourceChangesModel.h"
#include "Models/GitHistoryModel.h"

#include "event_reader/event_parser.h"
#include "egm.h"

#include <QString>
#include <QStringList>
#include <QObject>

#include <git2.h>

class EGMManager : public QObject {
Q_OBJECT
public:
EGMManager();
~EGMManager();
buffers::Project* NewProject();
buffers::Project* LoadProject(const QString& fPath);
buffers::Game *GetGame();
ResourceChangesModel& GetResourceChangesModel();
GitHistoryModel& GetGitHistoryModel();
void ResourceChanged(Resource &res, ResChange change, const QString &oldName);
bool LoadEventData(const QString& fPath);
EventData* GetEventData();
bool InitRepo();
git_commit* GitLookUp(const git_oid* id);
bool CreateBranch(const QString& branchName);
bool Checkout(const QString& ref);
//bool CheckoutFile(const QString& ref, const QString& file);
bool AddFile(const QString& file);
bool RemoveFile(const QString& file);
bool RemoveDir(const QString& dir);
bool CommitChanges(const QString& message);
/*bool AddRemote(const QString& url);
bool ChangeRemote(unsigned index, const QString& url);
bool RemoveRemote(unsigned index);
const QStringList& GetRemotes() const;
bool PushChanges();*/

signals:
QStringList FilesEditedExternally();
QStringList ConflictedFilesDetected();

public slots:
void GitError();
bool Save(const QString& fPath);

protected:
std::unique_ptr<buffers::Project> _project;
ResourceChangesModel _resChangeModel;
GitHistoryModel _gitHistoryModel;
QStringList _remoteURLs;
std::unique_ptr<EventData> _event_data;
QString _rootPath;
git_repository* _repo;
git_signature* _git_sig;
git_index* _git_index;
git_oid _git_tree_id, _git_commit_id;
git_tree* _git_tree;
};

#endif // EGMMANAGER_H
18 changes: 18 additions & 0 deletions Components/GitTreeItem.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include "GitTreeItem.h"
#include <QDebug>

GitTreeItem::GitTreeItem() {}

constexpr int scale = 8;

void GitTreeItem::paint(QPainter *painter, const QRect &rect, const QPalette &palette, EditMode mode) const {
painter->save();
painter->setBrush(QBrush(Qt::black));
painter->drawEllipse(rect.left() + (rect.width() - scale)/2, rect.top() + (rect.height() - scale)/2, scale, scale);
painter->drawLine(rect.left() + (rect.width())/2, rect.top(), rect.left() + (rect.width())/2, rect.bottom());
painter->restore();
}

QSize GitTreeItem::sizeHint() const {
return QSize(scale, scale);
}
18 changes: 18 additions & 0 deletions Components/GitTreeItem.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#ifndef GITTREEITEM_H
#define GITTREEITEM_H

#include <QPainter>
#include <QSize>

class GitTreeItem
{
public:
enum class EditMode { ReadOnly };
GitTreeItem();
void paint(QPainter *painter, const QRect &rect, const QPalette &palette, EditMode mode) const;
QSize sizeHint() const;
};

Q_DECLARE_METATYPE(GitTreeItem)

#endif // GITTREEITEM_H
Loading