pcbjam/tests/apps/standalone/timer/timer_test.cpp
Viktor Vaczi a26b40c063 Reorganize project structure for clarity
- Rename tests/wasm-app/ to tests/apps/ for brevity
- Move lib/gl_immediate_shim.js to wasm/shims/ (consolidates WASM files)
- Delete docs/ directory (outdated Nov 2024 research docs)
- Delete patches/ directory (already applied to fork submodules)
- Delete wasm/patches/ and wasm/config/ (empty/unused)
- Update all file references in scripts, configs, and documentation
- Update .gitignore for new tests/apps/ paths

Verified both build workflows pass:
- wxWidgets tests: 255 passed
- Docker KiCad build: completed successfully

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-27 14:06:23 +01:00

235 lines
6.6 KiB
C++

// wxTimer Test - Tests timer functionality in WASM
// KiCad uses timers for animations, auto-save, and periodic updates
#include "wx/wxprec.h"
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include "wx/timer.h"
#ifdef __EMSCRIPTEN__
#include <emscripten/emscripten.h>
#endif
class TimerTestApp : public wxApp
{
public:
virtual bool OnInit() override;
};
class TimerTestFrame : public wxFrame
{
public:
TimerTestFrame();
~TimerTestFrame();
private:
wxTimer* m_timer;
wxTimer* m_fastTimer;
int m_counter;
int m_fastCounter;
wxStaticText* m_counterDisplay;
wxStaticText* m_fastCounterDisplay;
wxGauge* m_progressGauge;
wxTextCtrl* m_log;
void LogEvent(const wxString& msg);
void OnStartTimer(wxCommandEvent& evt);
void OnStopTimer(wxCommandEvent& evt);
void OnStartFastTimer(wxCommandEvent& evt);
void OnStopFastTimer(wxCommandEvent& evt);
void OnResetCounters(wxCommandEvent& evt);
void OnTimer(wxTimerEvent& evt);
void OnFastTimer(wxTimerEvent& evt);
wxDECLARE_EVENT_TABLE();
};
enum {
ID_START_TIMER = wxID_HIGHEST + 1,
ID_STOP_TIMER,
ID_START_FAST_TIMER,
ID_STOP_FAST_TIMER,
ID_RESET_COUNTERS,
ID_TIMER,
ID_FAST_TIMER
};
wxBEGIN_EVENT_TABLE(TimerTestFrame, wxFrame)
EVT_BUTTON(ID_START_TIMER, TimerTestFrame::OnStartTimer)
EVT_BUTTON(ID_STOP_TIMER, TimerTestFrame::OnStopTimer)
EVT_BUTTON(ID_START_FAST_TIMER, TimerTestFrame::OnStartFastTimer)
EVT_BUTTON(ID_STOP_FAST_TIMER, TimerTestFrame::OnStopFastTimer)
EVT_BUTTON(ID_RESET_COUNTERS, TimerTestFrame::OnResetCounters)
EVT_TIMER(ID_TIMER, TimerTestFrame::OnTimer)
EVT_TIMER(ID_FAST_TIMER, TimerTestFrame::OnFastTimer)
wxEND_EVENT_TABLE()
wxIMPLEMENT_APP(TimerTestApp);
bool TimerTestApp::OnInit()
{
if (!wxApp::OnInit())
return false;
TimerTestFrame* frame = new TimerTestFrame();
frame->Show(true);
return true;
}
TimerTestFrame::TimerTestFrame()
: wxFrame(nullptr, wxID_ANY, "wxTimer WASM Test",
wxDefaultPosition, wxSize(600, 550))
, m_counter(0)
, m_fastCounter(0)
{
m_timer = new wxTimer(this, ID_TIMER);
m_fastTimer = new wxTimer(this, ID_FAST_TIMER);
wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
wxStaticText* desc = new wxStaticText(this, wxID_ANY,
"wxTimer Test\n\n"
"KiCad uses timers for auto-save, animations, and periodic updates.\n"
"Test both slow (1 sec) and fast (100ms) timers.");
mainSizer->Add(desc, 0, wxALL, 10);
// Slow timer section (1 second interval)
wxStaticBoxSizer* timerBox = new wxStaticBoxSizer(wxVERTICAL, this, "Slow Timer (1 second)");
wxBoxSizer* timerBtnSizer = new wxBoxSizer(wxHORIZONTAL);
timerBtnSizer->Add(new wxButton(this, ID_START_TIMER, "Start"), 0, wxALL, 5);
timerBtnSizer->Add(new wxButton(this, ID_STOP_TIMER, "Stop"), 0, wxALL, 5);
timerBox->Add(timerBtnSizer, 0, wxALIGN_CENTER);
m_counterDisplay = new wxStaticText(this, wxID_ANY, "Counter: 0",
wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER);
m_counterDisplay->SetFont(m_counterDisplay->GetFont().Scale(2.0));
timerBox->Add(m_counterDisplay, 0, wxALIGN_CENTER | wxALL, 10);
mainSizer->Add(timerBox, 0, wxEXPAND | wxALL, 10);
// Fast timer section (100ms interval)
wxStaticBoxSizer* fastTimerBox = new wxStaticBoxSizer(wxVERTICAL, this, "Fast Timer (100ms)");
wxBoxSizer* fastBtnSizer = new wxBoxSizer(wxHORIZONTAL);
fastBtnSizer->Add(new wxButton(this, ID_START_FAST_TIMER, "Start Fast"), 0, wxALL, 5);
fastBtnSizer->Add(new wxButton(this, ID_STOP_FAST_TIMER, "Stop Fast"), 0, wxALL, 5);
fastTimerBox->Add(fastBtnSizer, 0, wxALIGN_CENTER);
m_fastCounterDisplay = new wxStaticText(this, wxID_ANY, "Fast Counter: 0");
fastTimerBox->Add(m_fastCounterDisplay, 0, wxALIGN_CENTER | wxALL, 5);
m_progressGauge = new wxGauge(this, wxID_ANY, 100);
fastTimerBox->Add(m_progressGauge, 0, wxEXPAND | wxALL, 5);
mainSizer->Add(fastTimerBox, 0, wxEXPAND | wxALL, 10);
// Reset button
mainSizer->Add(new wxButton(this, ID_RESET_COUNTERS, "Reset All Counters"),
0, wxALIGN_CENTER | wxALL, 5);
// Event log
wxStaticBoxSizer* logBox = new wxStaticBoxSizer(wxVERTICAL, this, "Event Log");
m_log = new wxTextCtrl(this, wxID_ANY, "",
wxDefaultPosition, wxSize(-1, 120), wxTE_MULTILINE | wxTE_READONLY);
logBox->Add(m_log, 1, wxEXPAND | wxALL, 5);
mainSizer->Add(logBox, 1, wxEXPAND | wxALL, 10);
SetSizer(mainSizer);
CreateStatusBar();
SetStatusText("Ready");
LogEvent("Timer test app started");
#ifdef __EMSCRIPTEN__
EM_ASM({
console.log('[TIMER_TEST] wxTimer test app started successfully');
});
#endif
}
TimerTestFrame::~TimerTestFrame()
{
m_timer->Stop();
m_fastTimer->Stop();
delete m_timer;
delete m_fastTimer;
}
void TimerTestFrame::LogEvent(const wxString& msg)
{
m_log->AppendText(msg + "\n");
SetStatusText(msg);
#ifdef __EMSCRIPTEN__
EM_ASM({
console.log('[TIMER_EVENT] ' + UTF8ToString($0));
}, msg.c_str().AsChar());
#endif
}
void TimerTestFrame::OnStartTimer(wxCommandEvent& WXUNUSED(evt))
{
m_timer->Start(1000); // 1 second
LogEvent("Slow timer started (1 second interval)");
}
void TimerTestFrame::OnStopTimer(wxCommandEvent& WXUNUSED(evt))
{
m_timer->Stop();
LogEvent("Slow timer stopped");
}
void TimerTestFrame::OnStartFastTimer(wxCommandEvent& WXUNUSED(evt))
{
m_fastTimer->Start(100); // 100ms
LogEvent("Fast timer started (100ms interval)");
}
void TimerTestFrame::OnStopFastTimer(wxCommandEvent& WXUNUSED(evt))
{
m_fastTimer->Stop();
LogEvent("Fast timer stopped");
}
void TimerTestFrame::OnResetCounters(wxCommandEvent& WXUNUSED(evt))
{
m_counter = 0;
m_fastCounter = 0;
m_counterDisplay->SetLabel("Counter: 0");
m_fastCounterDisplay->SetLabel("Fast Counter: 0");
m_progressGauge->SetValue(0);
LogEvent("Counters reset");
}
void TimerTestFrame::OnTimer(wxTimerEvent& WXUNUSED(evt))
{
m_counter++;
m_counterDisplay->SetLabel(wxString::Format("Counter: %d", m_counter));
#ifdef __EMSCRIPTEN__
EM_ASM({
console.log('[TIMER_TICK] Slow timer tick: ' + $0);
}, m_counter);
#endif
}
void TimerTestFrame::OnFastTimer(wxTimerEvent& WXUNUSED(evt))
{
m_fastCounter++;
m_fastCounterDisplay->SetLabel(wxString::Format("Fast Counter: %d", m_fastCounter));
m_progressGauge->SetValue(m_fastCounter % 101);
// Log every 10 ticks to avoid flooding
if (m_fastCounter % 10 == 0) {
#ifdef __EMSCRIPTEN__
EM_ASM({
console.log('[TIMER_TICK] Fast timer tick: ' + $0);
}, m_fastCounter);
#endif
}
}