mirror of
https://github.com/cmosher01/Epple-II.git
synced 2025-01-13 06:29:50 +00:00
new cmd line handling; try to fix event thread on mac
This commit is contained in:
parent
3301251d90
commit
e55e3f4c1d
@ -18,8 +18,12 @@
|
||||
Created on December 3, 2022, 3:02 PM
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "E2wxApp.h"
|
||||
#include "E2wxFrame.h"
|
||||
#include "emulator.h"
|
||||
#include "gui.h"
|
||||
#include "configep2.h"
|
||||
#include <wx/app.h>
|
||||
#include <wx/xrc/xmlres.h>
|
||||
#include <wx/fileconf.h>
|
||||
@ -35,6 +39,9 @@
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
#include <wx/debugrpt.h>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
@ -89,7 +96,9 @@ bool E2wxApp::OnInit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef wxUSE_ON_FATAL_EXCEPTION
|
||||
wxHandleFatalExceptions();
|
||||
#endif
|
||||
|
||||
wxStandardPaths& stdpaths = wxStandardPaths::Get();
|
||||
//stdpaths.SetInstallPrefix(".");
|
||||
@ -135,6 +144,10 @@ bool E2wxApp::OnInit() {
|
||||
|
||||
|
||||
|
||||
StartSdlEpple2();
|
||||
|
||||
|
||||
|
||||
E2wxFrame *frame = new E2wxFrame();
|
||||
frame->DoInit();
|
||||
frame->Show();
|
||||
@ -144,6 +157,31 @@ bool E2wxApp::OnInit() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static int run(const std::string config_file) {
|
||||
std::unique_ptr<Emulator> emu(new Emulator());
|
||||
|
||||
Config cfg(config_file);
|
||||
emu->config(cfg);
|
||||
|
||||
emu->init();
|
||||
|
||||
return emu->run();
|
||||
}
|
||||
|
||||
void E2wxApp::StartSdlEpple2() {
|
||||
std::cout << "starting sdl thread..." << std::endl;
|
||||
this->thread_sdl = new std::thread(run, this->arg_configfile);
|
||||
std::cout << "started sdl thread." << std::endl;
|
||||
}
|
||||
|
||||
int E2wxApp::OnExit() {
|
||||
std::cout << "stopping sdl thread..." << std::endl;
|
||||
GUI::queueQuit();
|
||||
this->thread_sdl->join();
|
||||
std::cout << "exiting wx application..." << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void E2wxApp::OnFatalException() {
|
||||
wxDebugReport report;
|
||||
report.AddAll();
|
||||
@ -154,10 +192,33 @@ void E2wxApp::OnFatalException() {
|
||||
}
|
||||
}
|
||||
|
||||
int E2wxApp::OnExit() {
|
||||
return 0;
|
||||
static const wxCmdLineEntryDesc cmdLineDesc[] =
|
||||
{
|
||||
{ wxCMD_LINE_PARAM, NULL, NULL, "config file", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
|
||||
wxCMD_LINE_DESC_END
|
||||
};
|
||||
|
||||
void E2wxApp::OnInitCmdLine(wxCmdLineParser& parser) {
|
||||
wxApp::OnInitCmdLine(parser);
|
||||
parser.SetDesc(cmdLineDesc);
|
||||
}
|
||||
|
||||
bool E2wxApp::OnCmdLineParsed(wxCmdLineParser& parser) {
|
||||
if (!wxApp::OnCmdLineParsed(parser)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const int n = parser.GetParamCount();
|
||||
|
||||
if (n <= 0) {
|
||||
std::cout << "no config file specified on the command line; will use config file specified in user-preferences" << std::endl;
|
||||
} else {
|
||||
this->arg_configfile = parser.GetParam(0);
|
||||
std::cout << "using config file specified on the command line: " << this->arg_configfile << std::endl;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
const std::filesystem::path E2wxApp::GetLogFile() const {
|
||||
|
@ -25,7 +25,10 @@
|
||||
#ifndef WX_PRECOMP
|
||||
#include <wx/wx.h>
|
||||
#endif
|
||||
#include <wx/app.h>
|
||||
#include <wx/cmdline.h>
|
||||
#include <wx/string.h>
|
||||
#include <thread>
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
|
||||
@ -37,9 +40,12 @@ class E2wxApp : public wxApp {
|
||||
std::filesystem::path conffile;
|
||||
std::filesystem::path confdir;
|
||||
std::filesystem::path docsdir;
|
||||
std::string arg_configfile;
|
||||
std::thread *thread_sdl;
|
||||
|
||||
const std::filesystem::path BuildLogFilePath() const;
|
||||
void InitBoostLog();
|
||||
void StartSdlEpple2();
|
||||
|
||||
public:
|
||||
E2wxApp();
|
||||
@ -56,6 +62,8 @@ public:
|
||||
virtual bool OnInit() override;
|
||||
virtual int OnExit() override;
|
||||
virtual void OnFatalException() override;
|
||||
virtual void OnInitCmdLine(wxCmdLineParser& parser) override;
|
||||
virtual bool OnCmdLineParsed(wxCmdLineParser& parser) override;
|
||||
};
|
||||
|
||||
wxDECLARE_APP(E2wxApp);
|
||||
|
@ -21,14 +21,18 @@
|
||||
#include "E2wxFrame.h"
|
||||
#include "E2wxApp.h"
|
||||
#include "PreferencesDialog.h"
|
||||
#include "gui.h"
|
||||
#include <wx/persist/toplevel.h>
|
||||
|
||||
|
||||
enum E2MenuID {
|
||||
ID_MENUITEM_POWER = wxID_HIGHEST+1
|
||||
};
|
||||
|
||||
wxBEGIN_EVENT_TABLE(E2wxFrame, wxFrame)
|
||||
EVT_MENU(wxID_EXIT, E2wxFrame::OnExit)
|
||||
EVT_MENU(wxID_PREFERENCES, E2wxFrame::OnPreferences)
|
||||
EVT_MENU(wxID_ABOUT, E2wxFrame::OnAbout)
|
||||
EVT_MENU(ID_MENUITEM_POWER, E2wxFrame::OnTogglePower)
|
||||
wxEND_EVENT_TABLE()
|
||||
|
||||
|
||||
@ -60,6 +64,10 @@ void E2wxFrame::InitMenuBar() {
|
||||
menuBar->Append(menuEdit, "&Edit");
|
||||
menuEdit->Append(wxID_PREFERENCES);
|
||||
|
||||
wxMenu *menuMachine = new wxMenu();
|
||||
menuBar->Append(menuMachine, "&Machine");
|
||||
menuMachine->Append(ID_MENUITEM_POWER, "Toggle Power");
|
||||
|
||||
wxMenu *menuHelp = new wxMenu();
|
||||
menuBar->Append(menuHelp, "&Help");
|
||||
menuHelp->Append(wxID_ABOUT);
|
||||
@ -94,3 +102,7 @@ void E2wxFrame::OnPreferences(wxCommandEvent& event) {
|
||||
dlg->OnInit();
|
||||
dlg->ShowModal();
|
||||
}
|
||||
|
||||
void E2wxFrame::OnTogglePower(wxCommandEvent& event) {
|
||||
GUI::queueTogglePower();
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ private:
|
||||
void OnExit(wxCommandEvent& event);
|
||||
void OnPreferences(wxCommandEvent& event);
|
||||
void OnAbout(wxCommandEvent& event);
|
||||
void OnTogglePower(wxCommandEvent& event);
|
||||
|
||||
void InitMenuBar();
|
||||
void InitStatusBar();
|
||||
|
@ -204,21 +204,12 @@ void PreferencesDialog::OnTreeSelectionChanged(wxTreeEvent& evt) {
|
||||
|
||||
void PreferencesDialog::PreSelectUserConfigItemName(const std::filesystem::path& n) {
|
||||
CTRL(wxTreeCtrl, treItems);
|
||||
wxTreeItemId id = treItems->GetRootItem();
|
||||
wxTreeItemIdValue ctx;
|
||||
wxTreeItemId i = treItems->GetFirstChild(id, ctx);
|
||||
while (i.IsOk() && treItems->GetItemText(i) != wxT("user")) {
|
||||
i = treItems->GetNextChild(id, ctx);
|
||||
}
|
||||
if (!i.IsOk()) {
|
||||
return;
|
||||
|
||||
wxTreeItemId i = treItems->GetRootItem();
|
||||
while (i.IsOk() && treItems->GetItemText(i) != wxFileName::FileName(n.c_str()).GetName()) {
|
||||
i = treItems->GetNextVisible(i);
|
||||
}
|
||||
|
||||
id = i;
|
||||
i = treItems->GetFirstChild(id, ctx);
|
||||
while (i.IsOk() && treItems->GetItemText(i) != wxFileName::FileName(n.c_str()).GetName()) {
|
||||
i = treItems->GetNextChild(id, ctx);
|
||||
}
|
||||
if (!i.IsOk()) {
|
||||
return;
|
||||
}
|
||||
@ -247,6 +238,7 @@ void PreferencesDialog::OnActive(wxCommandEvent& evt) {
|
||||
const std::filesystem::path p = data->path();
|
||||
wxString name = wxFileName::FileName(p.c_str()).GetName();
|
||||
this->active = name;
|
||||
std::cout << "setting current active config file to: " << this->active << std::endl;
|
||||
wxConfigBase::Get()->Write(wxT("/ActivePreferences/name"), this->active);
|
||||
BuildItemTree(); // invalidates "data" pointer variable
|
||||
PreSelectUserConfigItemName(p);
|
||||
|
@ -15,8 +15,8 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
#ifndef CONFIGEP2_H
|
||||
#define CONFIGEP2_H
|
||||
|
||||
#include <string>
|
||||
class Memory;
|
||||
|
@ -25,9 +25,9 @@ help from John Morris, Tom Greene, Michael Guidero, and Lane Roathe.
|
||||
|
||||
Stepper motor has 2 cans each with a center-tapped coil, allowing
|
||||
for current flow in one of either direction, causing a N/S or S/N
|
||||
polarity fo the top/bottom of the can. Each top/bottom has fingers
|
||||
polarity of the top/bottom of the can. Each top/bottom has fingers
|
||||
bending down/up towards the center, the fingers from alternate surfaces
|
||||
being interlased. These fingers transfer the polarity from the coil.
|
||||
being interlaced. These fingers transfer the polarity from the coil.
|
||||
|
||||
Example of coil-0, controlled by phases 0 and 2,
|
||||
the two possible energized states, N/S and S/N,
|
||||
@ -134,7 +134,7 @@ But 7&1 is a special case (calculation-wise): since it's a circle, they
|
||||
Adjacent fingers within a can are of reverse polarity, and are 4 positions apart.
|
||||
Cans are offset from each other by 2 positions.
|
||||
|
||||
PH = phase 0-4 (on or off)
|
||||
PH = phase 0-3 (on or off)
|
||||
CAN = can 0-1 (north, south, or off)
|
||||
|
||||
CAN0 = PH0+PH2
|
||||
@ -288,6 +288,7 @@ int Disk2StepperMotor::magnetic_position() const {
|
||||
return this->can_1.magnetic_position();
|
||||
}
|
||||
assert(false);
|
||||
return 0; // quell compiler warning "control reaches end of non-void function"
|
||||
}
|
||||
|
||||
void Disk2StepperMotor::tick() {
|
||||
|
38
src/gui.cpp
38
src/gui.cpp
@ -35,7 +35,41 @@ GUI::~GUI() {
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
GUI::NotInitException::NotInitException() :
|
||||
runtime_error("Unable to initialize SDL") {
|
||||
static void pushSdlEvent(SDL_Event *e) {
|
||||
const int r = SDL_PushEvent(e);
|
||||
|
||||
if (r < 0) {
|
||||
std::cerr << "SDL reported error: " << SDL_GetError() << std::endl;
|
||||
} else if (r == 0) {
|
||||
std::cerr << "SDL filtered event, sorry" << std::endl;
|
||||
} else if (r == 1) {
|
||||
std::cerr << "Pushed event to SDL" << std::endl;
|
||||
} else {
|
||||
std::cerr << "SDL reported unexpected error code: " << r << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void GUI::queueTogglePower() {
|
||||
SDL_Event *e = new SDL_Event(); // note: creating struct on the stack doesn't seem to work
|
||||
e->type = SDL_KEYDOWN;
|
||||
e->key.keysym.sym = SDLK_F1;
|
||||
pushSdlEvent(e);
|
||||
delete e;
|
||||
}
|
||||
|
||||
void GUI::queueQuit() {
|
||||
SDL_Event *e = new SDL_Event();
|
||||
e->type = SDL_KEYDOWN;
|
||||
e->key.keysym.sym = SDLK_F9;
|
||||
pushSdlEvent(e);
|
||||
delete e;
|
||||
}
|
||||
|
||||
|
||||
|
||||
GUI::NotInitException::NotInitException() : runtime_error("Unable to initialize SDL") {
|
||||
SDL_GetError();
|
||||
}
|
||||
|
||||
GUI::NotInitException::~NotInitException() {
|
||||
}
|
||||
|
14
src/gui.h
14
src/gui.h
@ -20,19 +20,19 @@
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
class GUI
|
||||
{
|
||||
class GUI {
|
||||
public:
|
||||
GUI();
|
||||
~GUI();
|
||||
virtual ~GUI();
|
||||
|
||||
class NotInitException : public std::runtime_error
|
||||
{
|
||||
static void queueQuit();
|
||||
static void queueTogglePower();
|
||||
|
||||
class NotInitException : public std::runtime_error {
|
||||
public:
|
||||
NotInitException();
|
||||
virtual ~NotInitException() throw () {}
|
||||
virtual ~NotInitException();
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
69
src/main.cpp
69
src/main.cpp
@ -15,81 +15,36 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <SDL.h>
|
||||
#include "emulator.h"
|
||||
#include "configep2.h"
|
||||
#include "gui.h"
|
||||
|
||||
#include "e2const.h"
|
||||
#include "gui.h"
|
||||
|
||||
#include <wx/app.h>
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <thread>
|
||||
#include <ostream>
|
||||
#include <stdexcept>
|
||||
#include <cstdio>
|
||||
#include <cstddef>
|
||||
|
||||
|
||||
static std::string parse_args(int argc, char* argv[]) {
|
||||
if (argc > 2) {
|
||||
throw std::runtime_error("usage: epple2 [config-file]" );
|
||||
}
|
||||
|
||||
if (argc <= 1) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
return std::string(argv[1]);
|
||||
}
|
||||
|
||||
static int run(const std::string config_file) {
|
||||
GUI gui;
|
||||
|
||||
std::unique_ptr<Emulator> emu(new Emulator());
|
||||
|
||||
Config cfg(config_file);
|
||||
emu->config(cfg);
|
||||
|
||||
emu->init();
|
||||
|
||||
return emu->run();
|
||||
}
|
||||
|
||||
static void queueEmuQuit() {
|
||||
SDL_Event f9;
|
||||
f9.type = SDL_KEYDOWN;
|
||||
f9.key.keysym.sym = SDLK_F9;
|
||||
SDL_PushEvent(&f9);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
int main(int argc, char* argv[]) {
|
||||
setbuf(stdout, NULL);
|
||||
setbuf(stderr, NULL);
|
||||
int main(int argc, char *argv[]) {
|
||||
::setbuf(::stdout, nullptr);
|
||||
::setbuf(::stderr, nullptr);
|
||||
|
||||
int x = E2Const::test();
|
||||
const int x = E2Const::test();
|
||||
if (x != -1) {
|
||||
std::cerr << x << std::endl;
|
||||
throw std::runtime_error("bad constant in e2const.h" );
|
||||
}
|
||||
|
||||
const std::string config_file = parse_args(argc, argv);
|
||||
GUI gui;
|
||||
|
||||
|
||||
|
||||
std::thread sdl_thread(run, config_file);
|
||||
|
||||
int none(0);
|
||||
wxEntry(none, (char**)nullptr);
|
||||
// Runs wxWidgets main event loop and waits for user to File/Exit.
|
||||
|
||||
|
||||
|
||||
queueEmuQuit();
|
||||
sdl_thread.join();
|
||||
wxEntry(argc, argv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user