Skip to content

Commit fb210f3

Browse files
committed
2 parents 5885e6c + 4316121 commit fb210f3

File tree

6 files changed

+91
-44
lines changed

6 files changed

+91
-44
lines changed

CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/$<CONFIGURATION>)
88
option(BUILD_SHARED_LIBS OFF "Build static")
99

1010
if(MSVC)
11-
add_definitions(/MP)
11+
add_compile_options(/MP)
1212
endif()
1313

1414
set(CMAKE_OSX_ARCHITECTURES "x86_64;arm64" CACHE INTERNAL "")
@@ -25,7 +25,7 @@ if (APPLE)
2525
set(OBJCPP "source/AppleUtilities.h" "source/AppleUtilities.mm")
2626
endif()
2727
add_executable("${PROJECT_NAME}" WIN32 ${source} "source/wxmac.icns" "source/windows.rc" ${OBJCPP})
28-
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_17)
28+
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_20)
2929

3030
#wxwidgets
3131
set(wxBUILD_SHARED OFF CACHE INTERNAL "")

source/create_dialog_derived.cpp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <dirent.h>
1212
#endif
1313
#include <wx/msgdlg.h>
14+
#include <fmt/format.h>
1415

1516
using namespace std;
1617

@@ -39,7 +40,7 @@ CreateProjectDialogD::CreateProjectDialogD(wxWindow* parent, const vector<editor
3940
unityVersionChoice->SetSelection(0);
4041

4142
//populate the template chooser
42-
loadTemplates(editors[0]);
43+
loadTemplates(editors[GetSelectedEditorIndex()]);
4344

4445
this->Fit();
4546
}
@@ -69,7 +70,8 @@ void CreateProjectDialogD::OnCreate(wxCommandEvent& event){
6970
string message = validateForm();
7071
if (message == ""){
7172
//assemble the command that will create the project described by the dialog
72-
editor& e = editors[unityVersionChoice->GetSelection()];
73+
74+
editor& e = editors[GetSelectedEditorIndex()];
7375
auto executablePath = e.path / e.name / executable;
7476
auto executableTemplatesPath = e.path / e.name / templatesDir;
7577
string projName = projNameTxt->GetValue().ToStdString();
@@ -84,7 +86,13 @@ void CreateProjectDialogD::OnCreate(wxCommandEvent& event){
8486

8587
//create the command string
8688
#if defined __APPLE__
87-
string command = "\"" + executablePath.string() + "\" -createproject \"" + (filesystem::path(projPath) / projName).string() + "\" -cloneFromTemplate \"" + executableTemplatesPath.string() + templatePrefix + "." + templateName + "\"";
89+
string command = fmt::format("\"{}\" -createProject \"{}\" -cloneFromTemplate \"{}{}.{}\"",
90+
executablePath.string(),
91+
(filesystem::path(projPath) / projName).string(),
92+
executableTemplatesPath.string(),
93+
templatePrefix,
94+
templateName
95+
);
8896
#elif defined _WIN32
8997
auto fullProj = std::filesystem::path("\"") / projPath / projName / "\"";
9098
auto fullTemplate = std::filesystem::path("\"") / executableTemplatesPath / (templatePrefix + "." + templateName + "\"");
@@ -165,7 +173,18 @@ void CreateProjectDialogD::loadTemplates(const editor& e){
165173

166174
void CreateProjectDialogD::OnChoiceChanged(wxCommandEvent& event){
167175
//get the editor struct for the selected id
168-
editor& e = editors[event.GetInt()];
176+
editor& e = editors[GetSelectedEditorIndex()];
169177
//load the templates for this editor
170178
loadTemplates(e);
171179
}
180+
181+
182+
size_t CreateProjectDialogD::GetSelectedEditorIndex(){
183+
auto str = unityVersionChoice->GetStringSelection();
184+
185+
auto itr = std::find_if(editors.begin(), editors.end(), [&str](const editor& e){
186+
return e.name == str;
187+
});
188+
auto idx = std::distance(editors.begin(), itr);
189+
return idx;
190+
}

source/globals.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#include "globals.h"
2+
#include <fmt/format.h>
3+
4+
void launch_process(const std::string& command, int flags) {
5+
#if defined __APPLE__ || defined __linux__
6+
//the '&' runs the command nonblocking, and >/dev/null 2>&1 destroys output
7+
auto fullcmd = fmt::format("{}{} &", command,null_device);
8+
FILE* stream = popen(fullcmd.c_str(), "r");
9+
pclose(stream);
10+
11+
#elif _WIN32
12+
//call wxExecute with the Async flag
13+
wxExecute(wxString(command),flags);
14+
15+
#endif
16+
}

source/globals.h

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,18 @@
1111
#include <filesystem>
1212

1313
//data file names
14-
static const std::string projectsFile = "projects.txt";
15-
static const std::string editorPathsFile = "editorPaths.txt";
16-
static const std::string templatePrefix = "com.unity.template";
17-
static const std::string AppVersion = "v1.5";
14+
static constexpr std::string_view projectsFile = "projects.txt";
15+
static constexpr std::string_view editorPathsFile = "editorPaths.txt";
16+
static constexpr std::string_view templatePrefix = "com.unity.template";
17+
static constexpr std::string_view AppVersion = "v1.51";
1818

1919
#if defined __APPLE__
2020
#include <pwd.h>
2121
//the location to store application data
2222
static const std::filesystem::path datapath = std::filesystem::path(getpwuid(getuid())->pw_dir) / "Library/Application Support/UnityHubNative";
23-
static const char dirsep = '/';
2423

2524
static const std::filesystem::path cachedir = std::filesystem::path(getpwuid(getuid())->pw_dir) / "/Library/Caches/com.ravbug.UnityHubNative/";
26-
static const std::string installerExt = "dmg";
25+
static constexpr std::string_view installerExt = "dmg";
2726

2827
//where to find various Unity things on macOS
2928
static const std::filesystem::path executable = "Unity.app/Contents/MacOS/Unity";
@@ -33,17 +32,19 @@ static const std::string AppVersion = "v1.5";
3332
static const std::filesystem::path templatesDir = "Unity.app/Contents/Resources/PackageManager/ProjectTemplates/";
3433

3534
//for stream redirecting to dev/null
36-
static const std::string null_device = ">/dev/null 2>&1";
35+
static constexpr std::string_view null_device = ">/dev/null 2>&1";
3736

3837
#elif defined _WIN32
3938
//naming conflicts
4039
#define popen _popen
4140
#define pclose _pclose
4241
#define mkdir _mkdir
4342
#include <wx/wx.h>
44-
static const std::filesystem::path homedir = getenv("HOMEPATH");
43+
static const std::filesystem::path homepath = getenv("HOMEPATH");
44+
static const std::filesystem::path homedrive = getenv("HOMEDRIVE");
45+
static const std::filesystem::path homedir = homedrive / homepath;
46+
4547
static const std::filesystem::path datapath = homedir / std::filesystem::path("AppData\\Roaming\\UnityHubNative");
46-
static const char dirsep = '\\';
4748

4849
static const std::filesystem::path cachedir = std::filesystem::temp_directory_path();
4950
static const std::string installerExt = "exe";
@@ -114,7 +115,6 @@ static const std::string AppVersion = "v1.5";
114115
#include <pwd.h>
115116
static const std::filesystem::path datapath = std::filesystem::path(getpwuid(getuid())->pw_dir) / "UnityHubNative";
116117
static const std::string null_device = ">/dev/null 2>&1";
117-
static const char dirsep = '/';
118118

119119
static const std::filesystem::path executable = "Editor/Unity";
120120
static const std::vector<std::filesystem::path> defaultInstall = {std::filesystem::path(getpwuid(getuid())->pw_dir) / "Unity/Hub/Editor"};
@@ -133,6 +133,9 @@ struct project{
133133
std::string version;
134134
std::string modifiedDate;
135135
std::filesystem::path path;
136+
bool operator==(const project& other) const{
137+
return this->path == other.path;
138+
}
136139
};
137140

138141
/**
@@ -141,18 +144,7 @@ struct project{
141144
@param command the shell command to run on the system
142145
@note The command passed to this function must be correct for the system it is running on. If it is not correct, the function will appear to do nothing.
143146
*/
144-
inline void launch_process(const std::string& command, int flags = 0) {
145-
#if defined __APPLE__ || defined __linux__
146-
//the '&' runs the command nonblocking, and >/dev/null 2>&1 destroys output
147-
FILE* stream = popen(std::string(command + null_device + " &").c_str(), "r");
148-
pclose(stream);
149-
150-
#elif _WIN32
151-
//call wxExecute with the Async flag
152-
wxExecute(wxString(command),flags);
153-
154-
#endif
155-
}
147+
void launch_process(const std::string& command, int flags = 0);
156148

157149
inline void reveal_in_explorer(const std::string& path){
158150
#if defined __APPLE__
@@ -202,4 +194,8 @@ struct editor {
202194
decltype(path) executablePath() const{
203195
return path / name / executable;
204196
}
197+
198+
bool operator==(const editor& other){
199+
return this->name == other.name; // many editors can share a root path
200+
}
205201
};

source/interface_derived.cpp

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ MainFrameDerived::MainFrameDerived() : MainFrame(NULL){
102102
//if no projects to load, the interface will be blank
103103

104104
//show current version in titlebar
105-
this->SetLabel("Unity Hub Native " + AppVersion);
105+
this->SetLabel(fmt::format("Unity Hub Native {}",AppVersion));
106106
projSearchCtrl->Bind(wxEVT_KEY_UP, &MainFrameDerived::Filter, this);
107107
projSearchCtrl->SetFocus();
108108
}
@@ -272,15 +272,15 @@ void MainFrameDerived::OnAddProject(wxCommandEvent& event){
272272
//check that the project does not already exist
273273
for(project& p : projects){
274274
if (p.path == path){
275-
wxMessageBox( "This project has already been added.", "Cannot add project", wxOK | wxICON_WARNING );
275+
wxMessageBox( fmt::format("Project \"{}\" has already been added.", p.path.string()), "Cannot add project", wxOK | wxICON_WARNING );
276276
return;
277277
}
278278
}
279279

280280
//add it to the projects list
281281
try{
282282
project p = LoadProject(path);
283-
AddProject(p,"");
283+
AddProject(p,"",true);
284284
}
285285
catch(runtime_error& e){
286286
wxMessageBox(e.what(),"Unable to add project",wxOK | wxICON_ERROR);
@@ -303,6 +303,9 @@ void MainFrameDerived::OnPageChanging(wxBookCtrlEvent& event){
303303
*/
304304
void MainFrameDerived::LoadEditorPath(const std::filesystem::path& path){
305305
//add to internal structure and to file
306+
if (std::find(installPaths.begin(),installPaths.end(),path) != installPaths.end()){
307+
return;
308+
}
306309
installPaths.push_back(path);
307310
SaveEditorVersions();
308311

@@ -340,7 +343,7 @@ void MainFrameDerived::OnCreateProject(wxCommandEvent& event){
340343
if (editors.size() > 0){
341344
DialogCallback d = [&](string str, project p){
342345
//add the project
343-
this->AddProject(p,"");
346+
this->AddProject(p,"",true);
344347

345348
//launch the process
346349
launch_process(str);
@@ -417,9 +420,9 @@ void MainFrameDerived::OpenProject(const long& index){
417420
}
418421
#endif
419422
}
420-
//alert user
421-
wxMessageBox("The editor version " + p.version + " could not be found.\n\nCheck that it is installed, and that the folder where it has been installed is listed in the Editor Versions tab, under Install Search Paths.", "Unable to start Unity", wxOK | wxICON_ERROR);
422-
423+
// prompt the user to choose a new editor because we couldn't locate one
424+
wxCommandEvent evt;
425+
MainFrameDerived::OnOpenWith(evt);
423426
}
424427

425428
/**
@@ -515,8 +518,13 @@ void MainFrameDerived::SaveEditorVersions(){
515518
@param p the project struct to add
516519
@note Ensure all the fields on the struct are initialized
517520
*/
518-
void MainFrameDerived::AddProject(const project& p, const std::string& filter){
521+
void MainFrameDerived::AddProject(const project& p, const std::string& filter, bool select){
519522
//add to the vector backing the UI
523+
if (std::find_if(projects.begin(),projects.end(),[&](const auto& item){
524+
return p == item;
525+
}) != projects.end()){
526+
return;
527+
}
520528
projects.insert(projects.begin(),p);
521529

522530
//save to file
@@ -552,6 +560,10 @@ void MainFrameDerived::AddProject(const project& p, const std::string& filter){
552560
for (int i = 0; i < cols; i++){
553561
projectsList->SetColumnWidth(i, wxLIST_AUTOSIZE);
554562
}
563+
564+
if(select){
565+
projectsList->SetItemState(i, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
566+
}
555567
}
556568

557569
}
@@ -593,21 +605,23 @@ void MainFrameDerived::LoadEditorVersions(){
593605
char buffer[16];
594606
getCFBundleVersionFromPlist(infopath.string().c_str(), buffer, sizeof(buffer));
595607

596-
a.Add(string(buffer) + " - " + path.string());
597608
//add it to the backing datastructure
598609
editor e = {buffer, path};
599-
600-
editors.push_back(e);
610+
if (std::find(editors.begin(), editors.end(), e) == editors.end()){
611+
a.Add(e.name + " - " + e.path.string());
612+
editors.push_back(e);
613+
}
601614
}
602615
}
603616
else
604617
#endif
605618
{
606-
a.Add(string(entry->d_name) + " - " + path.string());
607619
//add it to the backing datastructure
608620
editor e = {entry->d_name, path};
609-
610-
editors.push_back(e);
621+
if (std::find(editors.begin(), editors.end(), e) == editors.end()){
622+
a.Add(e.name + " - " + e.path.string());
623+
editors.push_back(e);
624+
}
611625
}
612626
}
613627
}

source/interface_derived.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class MainFrameDerived : public MainFrame{
2828
static std::string GetPathFromDialog(const std::string& message);
2929

3030
private:
31-
void AddProject(const project& p, const std::string& filter);
31+
void AddProject(const project& p, const std::string& filter, bool select=false);
3232
project LoadProject(const std::filesystem::path& path);
3333
void SaveProjects();
3434
void OpenProject(const long& index);
@@ -75,7 +75,7 @@ class MainFrameDerived : public MainFrame{
7575
};
7676

7777
//will store the list of projects
78-
std::vector<project> projects;
78+
std::deque<project> projects;
7979
std::vector<std::filesystem::path> installPaths;
8080
std::vector<editor> editors;
8181

@@ -178,6 +178,8 @@ class CreateProjectDialogD : public CreateProjectDialog{
178178
void loadTemplates(const editor& e);
179179
DialogCallback callback;
180180
std::vector<editor> editors;
181+
182+
size_t GetSelectedEditorIndex();
181183

182184
//events
183185
void OnCancel(wxCommandEvent& event){

0 commit comments

Comments
 (0)