Skip to content

Commit 9ad74f7

Browse files
committed
Merge branch '2.1.2-beta.1' of https://github.com/Lord-Grey/hyperion.ng into 2.1.2-beta.1
2 parents e93b380 + 18517d6 commit 9ad74f7

File tree

4 files changed

+115
-80
lines changed

4 files changed

+115
-80
lines changed

assets/webconfig/css/hyperion.css

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -245,20 +245,17 @@ table.first_cell_borderless td:first-child{width: 25px !important;}
245245
.mdi-lead-pencil, .mdi-delete-forever {font-size: 22px;}
246246

247247
/*led preview & led visualisation*/
248-
body {
249-
--background-var: none;
250-
--width-var: 0px;
251-
--height-var: 0px;
252-
}
253-
254248
#leds_canvas {
255249
position:absolute;
256250
margin:15px;
257251
background-repeat:no-repeat;
258252
background-position: center;
253+
--background-var: none;
254+
--width-var: 0px;
255+
--height-var: 0px;
259256
}
260257

261-
#leds_canvas:before {
258+
#leds_canvas::before {
262259
content: "";
263260
position:absolute;
264261

@@ -279,6 +276,10 @@ body {
279276

280277
filter: blur(10px);
281278
background-size: cover;
279+
280+
/* Safari optimization for pseudo-elements */
281+
transform: translateZ(0);
282+
-webkit-transform: translateZ(0);
282283
}
283284

284285
.led { display:inline-block; border: 1px solid black; position:absolute; opacity:0.8; text-align:center; vertical-align:middle; padding:4px; border-radius:2px;}

assets/webconfig/js/ledsim.js

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ $(document).ready(function () {
66
var leds;
77
var grabberConfig;
88
var lC = false;
9-
var imageCanvasNodeCtx = document.getElementById("image_preview_canv").getContext("2d");
10-
var ledsCanvasNodeCtx = document.getElementById("leds_preview_canv").getContext("2d");
11-
var sigDetectAreaCanvasNodeCtx = document.getElementById("grab_preview_canv").getContext("2d");
9+
var imageCanvasNodeCtx = document.getElementById("image_preview_canv").getContext("2d", { willReadFrequently: false});
10+
var ledsCanvasNodeCtx = document.getElementById("leds_preview_canv").getContext("2d", { willReadFrequently: false});
11+
var sigDetectAreaCanvasNodeCtx = document.getElementById("grab_preview_canv").getContext("2d", { willReadFrequently: false});
1212
var canvas_height;
1313
var canvas_width;
1414
var twoDPaths = [];
@@ -205,12 +205,12 @@ $(document).ready(function () {
205205
canvas_width = $('#ledsim_dialog').outerWidth() - 30;
206206

207207
$("[id$=_preview_canv]").prop({ "width": canvas_width, "height": canvas_height });
208-
$("body").get(0).style.setProperty("--width-var", canvas_width + "px");
209-
$("body").get(0).style.setProperty("--height-var", canvas_height + "px");
208+
$('#leds_canvas').css("--width-var", canvas_width + "px");
209+
$('#leds_canvas').css("--height-var", canvas_height + "px");
210210

211211
create2dPaths();
212212
printLedsToCanvas();
213-
$("body").get(0).style.setProperty("--background-var", "none");
213+
$('#leds_canvas').css("--background-var", "none");
214214
resetImage();
215215
}
216216

@@ -227,7 +227,7 @@ $(document).ready(function () {
227227
if (window.ledStreamActive) {
228228
requestLedColorsStop();
229229
ledsCanvasNodeCtx.clear();
230-
$("body").get(0).style.setProperty("--background-var", "none");
230+
$('#leds_canvas').css("--background-var", "none");
231231
} else {
232232
requestLedColorsStart();
233233
}
@@ -263,11 +263,13 @@ $(document).ready(function () {
263263
$(window.hyperion).on("cmd-ledcolors-ledstream-update", function (event) {
264264
if (!modalOpened) {
265265
requestLedColorsStop();
266-
$("body").get(0).style.setProperty("--background-var", "none");
266+
$('#leds_canvas').css("--background-var", "none");
267267
}
268268
else {
269269
printLedsToCanvas(event.response.data.leds)
270-
$("body").get(0).style.setProperty("--background-var", "url(" + ($('#leds_preview_canv')[0]).toDataURL("image/jpg") + ") no-repeat top left");
270+
$('#leds_canvas').css("--background-var", "url(" + ($('#leds_preview_canv')[0]).toDataURL("image/jpg") + ") no-repeat top left");
271+
// Safari workaround (redraw canvas)
272+
$('#leds_canvas').parent().hide().show(0);
271273
}
272274
});
273275

libsrc/effectengine/EffectModule.cpp

Lines changed: 80 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -85,73 +85,78 @@ PyObject* EffectModule::json2python(const QJsonValue& jsonData)
8585
{
8686
switch (jsonData.type())
8787
{
88-
case QJsonValue::Null:
89-
Py_RETURN_NONE;
88+
case QJsonValue::Null:
89+
Py_RETURN_NONE;
9090

91-
case QJsonValue::Undefined:
92-
Py_RETURN_NOTIMPLEMENTED;
91+
case QJsonValue::Undefined:
92+
Py_RETURN_NOTIMPLEMENTED;
9393

94-
case QJsonValue::Double:
95-
{
96-
double value = jsonData.toDouble();
97-
if (value == static_cast<int>(value)) // If no fractional part, value is equal to its integer representation
94+
case QJsonValue::Double:
9895
{
99-
return Py_BuildValue("i", static_cast<int>(value));
96+
double value = jsonData.toDouble();
97+
if (value == static_cast<int>(value)) // If no fractional part, value is equal to its integer representation
98+
{
99+
return Py_BuildValue("i", static_cast<int>(value));
100+
}
101+
return Py_BuildValue("d", value);
100102
}
101-
return Py_BuildValue("d", value);
102-
}
103103

104-
case QJsonValue::Bool:
105-
return PyBool_FromLong(jsonData.toBool() ? 1 : 0);
104+
case QJsonValue::Bool:
105+
return PyBool_FromLong(jsonData.toBool() ? 1 : 0);
106106

107-
case QJsonValue::String:
108-
return PyUnicode_FromString(jsonData.toString().toUtf8().constData());
107+
case QJsonValue::String:
108+
return PyUnicode_FromString(jsonData.toString().toUtf8().constData());
109109

110-
case QJsonValue::Array:
111-
{
112-
QJsonArray arrayData = jsonData.toArray();
113-
PyObject* list = PyList_New(arrayData.size());
114-
int index = 0;
115-
for (QJsonArray::iterator i = arrayData.begin(); i != arrayData.end(); ++i, ++index)
110+
case QJsonValue::Array:
116111
{
117-
PyObject* obj = json2python(*i);
118-
Py_INCREF(obj);
119-
PyList_SetItem(list, index, obj);
120-
Py_XDECREF(obj);
112+
QJsonArray arrayData = jsonData.toArray();
113+
PyObject* list = PyList_New(arrayData.size());
114+
int index = 0;
115+
for (QJsonArray::iterator i = arrayData.begin(); i != arrayData.end(); ++i, ++index)
116+
{
117+
PyObject* obj = json2python(*i);
118+
if (!obj)
119+
{
120+
Py_XDECREF(list);
121+
return nullptr; // Error occurred, return null
122+
}
123+
PyList_SetItem(list, index, obj);
124+
}
125+
return list;
121126
}
122-
return list;
123-
}
124127

125-
case QJsonValue::Object: {
126-
// Python's dict
127-
QJsonObject jsonObject = jsonData.toObject();
128-
PyObject* pyDict = PyDict_New();
129-
for (auto it = jsonObject.begin(); it != jsonObject.end(); ++it) {
130-
// Convert key
131-
PyObject* pyKey = PyUnicode_FromString(it.key().toUtf8().constData());
132-
if (!pyKey) {
133-
Py_XDECREF(pyDict);
134-
return nullptr; // Error occurred, return null
135-
}
136-
// Convert value
137-
PyObject* pyValue = json2python(it.value());
138-
if (!pyValue) {
139-
Py_XDECREF(pyKey);
140-
Py_XDECREF(pyDict);
141-
return nullptr; // Error occurred, return null
128+
case QJsonValue::Object:
129+
{
130+
// Python's dict
131+
QJsonObject jsonObject = jsonData.toObject();
132+
PyObject* pyDict = PyDict_New();
133+
for (auto it = jsonObject.begin(); it != jsonObject.end(); ++it)
134+
{
135+
// Convert key
136+
PyObject* pyKey = PyUnicode_FromString(it.key().toUtf8().constData());
137+
if (!pyKey)
138+
{
139+
Py_XDECREF(pyDict);
140+
return nullptr; // Error occurred, return null
141+
}
142+
// Convert value
143+
PyObject* pyValue = json2python(it.value());
144+
if (!pyValue)
145+
{
146+
Py_XDECREF(pyKey);
147+
Py_XDECREF(pyDict);
148+
return nullptr; // Error occurred, return null
149+
}
150+
// Add to dictionary
151+
PyDict_SetItem(pyDict, pyKey, pyValue);
142152
}
143-
// Add to dictionary
144-
PyDict_SetItem(pyDict, pyKey, pyValue);
145-
Py_XDECREF(pyKey);
146-
Py_XDECREF(pyValue);
153+
return pyDict;
147154
}
148-
return pyDict;
149-
}
150155

151-
default:
152-
// Unsupported type
153-
PyErr_SetString(PyExc_TypeError, "Unsupported QJsonValue type.");
154-
return nullptr;
156+
default:
157+
// Unsupported type
158+
PyErr_SetString(PyExc_TypeError, "Unsupported QJsonValue type.");
159+
return nullptr;
155160
}
156161

157162
assert(false);
@@ -349,6 +354,7 @@ PyObject* EffectModule::wrapGetImage(PyObject* self, PyObject* args)
349354
if (reader.canRead())
350355
{
351356
PyObject* result = PyList_New(reader.imageCount());
357+
if(!result) return nullptr;
352358

353359
for (int i = 0; i < reader.imageCount(); ++i)
354360
{
@@ -363,6 +369,7 @@ PyObject* EffectModule::wrapGetImage(PyObject* self, PyObject* args)
363369
{
364370
if (cropLeft + cropRight >= width || cropTop + cropBottom >= height)
365371
{
372+
Py_DECREF(result);
366373
QString errorStr = QString("Rejecting invalid crop values: left: %1, right: %2, top: %3, bottom: %4, higher than height/width %5/%6").arg(cropLeft).arg(cropRight).arg(cropTop).arg(cropBottom).arg(height).arg(width);
367374
PyErr_SetString(PyExc_RuntimeError, qPrintable(errorStr));
368375
return nullptr;
@@ -386,10 +393,28 @@ PyObject* EffectModule::wrapGetImage(PyObject* self, PyObject* args)
386393
*dest++ = static_cast<char>(!grayscale ? qBlue(pixel) : qGray(pixel));
387394
}
388395
}
389-
PyList_SET_ITEM(result, i, Py_BuildValue("{s:i,s:i,s:O}", "imageWidth", width, "imageHeight", height, "imageData", PyByteArray_FromStringAndSize(binaryImage.constData(), binaryImage.size())));
396+
397+
PyObject* pyBytes = PyByteArray_FromStringAndSize(binaryImage.constData(), binaryImage.size());
398+
if (!pyBytes)
399+
{
400+
Py_DECREF(result);
401+
return nullptr;
402+
}
403+
404+
PyObject* dict = Py_BuildValue("{s:i,s:i,s:O}", "imageWidth", width, "imageHeight", height, "imageData", pyBytes);
405+
Py_DECREF(pyBytes);
406+
407+
if (!dict)
408+
{
409+
Py_DECREF(result);
410+
return nullptr;
411+
}
412+
413+
PyList_SET_ITEM(result, i, dict);
390414
}
391415
else
392416
{
417+
Py_DECREF(result);
393418
PyErr_SetString(PyExc_TypeError, reader.errorString().toUtf8().constData());
394419
return nullptr;
395420
}

libsrc/hyperion/Hyperion.cpp

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ void Hyperion::start()
139139
// listen for suspend/resume, idle requests to perform core activation/deactivation actions
140140
connect(this, &Hyperion::suspendRequest, this, &Hyperion::setSuspend);
141141
connect(this, &Hyperion::idleRequest, this, &Hyperion::setIdle);
142-
142+
143143
_muxer->start();
144144

145145
#if defined(ENABLE_EFFECTENGINE)
@@ -648,13 +648,19 @@ void Hyperion::update()
648648
int const priority = _muxer->getCurrentPriority();
649649
const PriorityMuxer::InputInfo priorityInfo = _muxer->getInputInfo(priority);
650650

651-
std::vector<ColorRgb> ledColors;
651+
const Image<ColorRgb>& image = priorityInfo.image;
652+
const int width = image.width();
653+
const int height = image.height();
654+
652655

653656
// copy image & process OR copy ledColors from muxer
654-
Image<ColorRgb> const image = priorityInfo.image;
655-
if (image.width() > 1 || image.height() > 1)
657+
std::vector<ColorRgb> ledColors;
658+
if (width > 1 || height > 1)
656659
{
657-
_imageEmissionInterval = (image.width() > 1280) ? 2 * DEFAULT_MAX_IMAGE_EMISSION_INTERVAL : DEFAULT_MAX_IMAGE_EMISSION_INTERVAL;
660+
_imageEmissionInterval = (width > 1280)
661+
? 2 * DEFAULT_MAX_IMAGE_EMISSION_INTERVAL
662+
: DEFAULT_MAX_IMAGE_EMISSION_INTERVAL;
663+
658664
// Throttle the emission of currentImage(image) signal
659665
qint64 elapsedImageEmissionTime = _imageTimer.elapsed();
660666
if (elapsedImageEmissionTime - _lastImageEmission >= _imageEmissionInterval.count())
@@ -669,13 +675,14 @@ void Hyperion::update()
669675
ledColors = priorityInfo.ledColors;
670676
if (_ledString.hasBlackListedLeds())
671677
{
672-
for (unsigned long const id : _ledString.blacklistedLedIds())
678+
const std::vector<int>& blacklist = _ledString.blacklistedLedIds();
679+
const size_t size = ledColors.size();
680+
for (unsigned long const id : blacklist)
673681
{
674-
if (id > ledColors.size()-1)
682+
if (id < size)
675683
{
676-
break;
684+
ledColors[id] = ColorRgb::BLACK;
677685
}
678-
ledColors.at(id) = ColorRgb::BLACK;
679686
}
680687
}
681688
}

0 commit comments

Comments
 (0)