-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGradientEngine.cpp
More file actions
123 lines (99 loc) · 3.77 KB
/
Copy pathGradientEngine.cpp
File metadata and controls
123 lines (99 loc) · 3.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*
* ***
* SPDX-FileCopyrightText: 2026 Stagelab Coop SCCL
* SPDX-License-Identifier: GPL-3.0-or-later
* ***
*/
/**
* @file GradientEngine.cpp
* @brief GradientEngine implementation — wires MtcTickSource, OscServer,
* and MotionRegistry.
*
* This file is compiled into the **daemon binary** (gradient-motiond), NOT
* into libgradient_motion. This allows it to include daemon headers (liblo)
* without polluting the library's public dependency set.
*
* @see src/engine/GradientEngine.h for the public interface.
*/
#include "engine/GradientEngine.h"
#include "daemon/comms/OscServer.h"
#include "logging.h"
namespace gme {
namespace engine {
// ---------------------------------------------------------------------------
// Constructor / Destructor
// ---------------------------------------------------------------------------
GradientEngine::GradientEngine() = default;
GradientEngine::~GradientEngine() {
shutdown();
}
// ---------------------------------------------------------------------------
// initialize
// ---------------------------------------------------------------------------
bool GradientEngine::initialize(const GradientEngineConfig& config) {
if (initialized_) return true;
// --- Build MotionRegistry (status events → logged, no NNG) ---
registry_ = std::make_unique<gme::motion::MotionRegistry>(
tickSource_,
[](gme::signal::StatusKind k,
const std::string& id,
const std::string& reason) {
const char* kind_str = (k == gme::signal::StatusKind::MotionComplete)
? "MotionComplete" : "MotionError";
GME_LOG_INFO(std::string("GradientEngine: ") + kind_str +
" motion_id=" + id +
(reason.empty() ? "" : " reason=" + reason));
});
// --- Build OscServer ---
oscServer_ = std::make_unique<gme::daemon::comms::OscServer>(
config.oscPort, config.nodeName, &queue_);
if (!oscServer_->start()) {
registry_.reset();
oscServer_.reset();
return false;
}
// --- Register MTC tick callback ---
tickSource_.setTickCallback([this](long ms) { onTick(ms); });
// --- Open MIDI port ---
auto mtcErr = tickSource_.start(config.midiPort);
if (mtcErr != gme::time::MtcStartError::kOk) {
tickSource_.setTickCallback({});
oscServer_->stop();
registry_.reset();
oscServer_.reset();
return false;
}
GME_LOG_INFO("GradientEngine initialized: OSC port=" +
std::to_string(config.oscPort) + " node=" + config.nodeName);
initialized_ = true;
return true;
}
// ---------------------------------------------------------------------------
// shutdown
// ---------------------------------------------------------------------------
void GradientEngine::shutdown() {
if (!initialized_) return;
initialized_ = false;
tickSource_.setTickCallback({});
if (registry_) registry_->cancelAll();
if (oscServer_) oscServer_->stop();
registry_.reset();
oscServer_.reset();
}
// ---------------------------------------------------------------------------
// onTick (MTC callback thread — lock-free, non-blocking)
// ---------------------------------------------------------------------------
void GradientEngine::onTick(long mtc_ms) {
gme::signal::FadeCommand cmd;
while (queue_.pop(cmd)) {
using Type = gme::signal::FadeCommand::Type;
if (cmd.type == Type::CANCEL_MOTION)
GME_LOG_DEBUG("GradientEngine: CANCEL_MOTION motion_id=" + cmd.motion_id);
else if (cmd.type == Type::CANCEL_ALL)
GME_LOG_DEBUG("GradientEngine: CANCEL_ALL");
registry_->apply(cmd);
}
registry_->tick(mtc_ms);
}
} // namespace engine
} // namespace gme