diff --git a/Makefile b/Makefile index 2e87512a0..17ad73eb7 100644 --- a/Makefile +++ b/Makefile @@ -527,6 +527,9 @@ install-doxydoc: doxydoc rsync -r -z --progress --delete doxydoc $(SF_WEB) +doc/Ravel/labels.pl: $(wildcard doc/*.tex) + cd doc; sh makedoc.sh + # upload manual to SF install-manual: doc/Ravel/labels.pl rsync -r -z --progress --delete doc/minsky.html doc/Ravel $(SF_WEB)/manual diff --git a/doc/Ravel.pdf b/doc/Ravel.pdf index 36e5b8a02..9b98244a8 100644 Binary files a/doc/Ravel.pdf and b/doc/Ravel.pdf differ diff --git a/engine/equations.cc b/engine/equations.cc index 4e843883c..8ce54e223 100644 --- a/engine/equations.cc +++ b/engine/equations.cc @@ -515,7 +515,7 @@ namespace MathDAG // try again later integralInputs.emplace_back(input,i->ports(1).lock()->wires()[0]); // clear error indicator - minsky::minsky().canvas.itemIndicator=false; + minsky::minsky().canvas.itemIndicator.reset(); } } diff --git a/gui-js/apps/minsky-electron/src/app/managers/CommandsManager.ts b/gui-js/apps/minsky-electron/src/app/managers/CommandsManager.ts index 3df6340a9..eb627d0b1 100644 --- a/gui-js/apps/minsky-electron/src/app/managers/CommandsManager.ts +++ b/gui-js/apps/minsky-electron/src/app/managers/CommandsManager.ts @@ -347,11 +347,10 @@ export class CommandsManager { Math.abs(itemX - 0.5 * canvasWidth) > 0.5 * canvasWidth || Math.abs(itemY - 0.5 * canvasHeight) > 0.5 * canvasHeight ) { - const posX = itemX - (await minsky.canvas.item.x()) + 0.5 * canvasWidth; - const posY = itemY - (await minsky.canvas.item.y()) + 0.5 * canvasHeight; + const posX = itemX - (await minsky.canvas.itemIndicator.x()) + 0.5 * canvasWidth; + const posY = itemY - (await minsky.canvas.itemIndicator.y()) + 0.5 * canvasHeight; minsky.canvas.moveTo(posX,posY); } - minsky.canvas.itemIndicator(true); minsky.canvas.requestRedraw(); WindowManager.getMainWindow()?.webContents?.send(events.RESET_SCROLL); } else { diff --git a/gui-js/libs/shared/src/lib/backend/minsky.ts b/gui-js/libs/shared/src/lib/backend/minsky.ts index 9499f2bc9..219157106 100644 --- a/gui-js/libs/shared/src/lib/backend/minsky.ts +++ b/gui-js/libs/shared/src/lib/backend/minsky.ts @@ -414,6 +414,7 @@ export class Canvas extends RenderNativeWindow { backgroundColour: ecolab__cairo__Colour; item: Item; itemFocus: Item; + itemIndicator: Item; lasso: LassoBox; model: Group; selection: Selection; @@ -428,6 +429,7 @@ export class Canvas extends RenderNativeWindow { this.backgroundColour=new ecolab__cairo__Colour(this.$prefix()+'.backgroundColour'); this.item=new Item(this.$prefix()+'.item'); this.itemFocus=new Item(this.$prefix()+'.itemFocus'); + this.itemIndicator=new Item(this.$prefix()+'.itemIndicator'); this.lasso=new LassoBox(this.$prefix()+'.lasso'); this.model=new Group(this.$prefix()+'.model'); this.selection=new Selection(this.$prefix()+'.selection'); @@ -468,7 +470,6 @@ export class Canvas extends RenderNativeWindow { async hasScrollBars(): Promise {return this.$callMethod('hasScrollBars');} async init(): Promise {return this.$callMethod('init');} async itemAt(a1: number,a2: number): Promise {return this.$callMethod('itemAt',a1,a2);} - async itemIndicator(...args: boolean[]): Promise {return this.$callMethod('itemIndicator',...args);} async keyPress(a1: minsky__EventInterface__KeyPressArgs): Promise {return this.$callMethod('keyPress',a1);} async lassoMode(...args: string[]): Promise {return this.$callMethod('lassoMode',...args);} async lockRavelsInSelection(): Promise {return this.$callMethod('lockRavelsInSelection');} diff --git a/gui-js/package-lock.json b/gui-js/package-lock.json index d7116af3c..7dadfac2f 100644 --- a/gui-js/package-lock.json +++ b/gui-js/package-lock.json @@ -32444,9 +32444,9 @@ } }, "node_modules/ws": { - "version": "8.17.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.0.tgz", - "integrity": "sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "engines": { "node": ">=10.0.0" }, diff --git a/model/canvas.cc b/model/canvas.cc index c1abd1498..c6c9245cb 100644 --- a/model/canvas.cc +++ b/model/canvas.cc @@ -185,7 +185,7 @@ namespace minsky lassoMode=LassoMode::none; - itemIndicator=false; + itemIndicator.reset(); rotatingItem=false; itemFocus.reset(); wireFocus.reset(); @@ -776,7 +776,7 @@ namespace minsky iv->type()==VariableType::parameter || iv->inputWired()) return true; - auto def=model->findAny + itemIndicator=model->findAny (&GroupItems::items, [&](const ItemPtr& i) { if (auto v=i->variableCast()) return v->inputWired() && v->valueId()==iv->valueId(); @@ -790,9 +790,7 @@ namespace minsky return o->intVar->valueId()==iv->valueId(); return false; }); - if (def) - item=def; - return def.get(); + return itemIndicator.get(); } return false; } @@ -852,7 +850,14 @@ namespace minsky const CairoSave cs(cairo); cairo_identity_matrix(cairo); cairo_translate(cairo,it.x(), it.y()); - it.draw(cairo); + try + { + it.draw(cairo); + } + catch (const std::exception& ex) + { + cerr << ex.what() << endl; + } } return false; }); @@ -910,11 +915,11 @@ namespace minsky cairo_stroke(cairo); } - if (itemIndicator && item) // draw a red circle to indicate an error or other marker + if (itemIndicator) // draw a red circle to indicate an error or other marker { const CairoSave cs(surface()->cairo()); cairo_set_source_rgb(surface()->cairo(),1,0,0); - cairo_arc(surface()->cairo(),item->x(),item->y(),15,0,2*M_PI); + cairo_arc(surface()->cairo(),itemIndicator->x(),itemIndicator->y(),15,0,2*M_PI); cairo_stroke(surface()->cairo()); } diff --git a/model/canvas.h b/model/canvas.h index c894a639f..4ee6d620e 100644 --- a/model/canvas.h +++ b/model/canvas.h @@ -116,8 +116,8 @@ namespace minsky rotatingItem=true; } ClickType::Type clickType; - /// for drawing error indicators on the canvas - bool itemIndicator=false; + /// for drawing error indicator on the canvas + ItemPtr itemIndicator; /// lasso mode support struct LassoMode {enum type {none, lasso, itemResize};}; diff --git a/model/minsky.cc b/model/minsky.cc index 3b526ce38..a505c055f 100644 --- a/model/minsky.cc +++ b/model/minsky.cc @@ -888,7 +888,7 @@ namespace minsky auto start=chrono::high_resolution_clock::now(); auto updateResetDuration=onStackExit([&]{resetDuration=chrono::duration_cast(chrono::high_resolution_clock::now()-start);}); - canvas.itemIndicator=false; + canvas.itemIndicator.reset(); const BusyCursor busy(*this); EvalOpBase::t=t=t0; lastT=t0; @@ -1249,26 +1249,24 @@ namespace minsky // this method is logically const, but because of the way // canvas rendering is done, canvas state needs updating auto& canvas=const_cast(this->canvas); - canvas.item=nullptr; if (op.visible()) - canvas.item=canvas.model->findItem(op); + canvas.itemIndicator=canvas.model->findItem(op); else if (auto v=op.variableCast()) if (auto c=v->controller.lock()) displayErrorItem(*c); - if (!canvas.item) + if (!canvas.itemIndicator) if (auto g=op.group.lock()) { while (g && !g->visible()) g=g->group.lock(); if (g && g->visible()) - canvas.item=g; + canvas.itemIndicator=g; } - canvas.itemIndicator=canvas.item.get(); if (canvas.item) { - auto physX=canvas.item->x(); - auto physY=canvas.item->y(); + auto physX=canvas.itemIndicator->x(); + auto physY=canvas.itemIndicator->y(); if (physX<100 || physX>canvas.frameArgs().childWidth-100 || physY<100 || physY>canvas.frameArgs().childHeight-100) { diff --git a/model/variable.cc b/model/variable.cc index e169d058c..bf455075e 100644 --- a/model/variable.cc +++ b/model/variable.cc @@ -168,7 +168,11 @@ shared_ptr VariableBase::vValue() const vector VariableBase::dims() const { - if (auto v=vValue()) return v->hypercube().dims(); + try + { + if (auto v=vValue()) return v->hypercube().dims(); + } + catch (...) {} // ignore any exceptions caused by evaluating RHS. return {}; } @@ -324,8 +328,12 @@ string VariableBase::init(const string& x) double VariableBase::value() const { - if (isValueId(valueId())) - return minsky::cminsky().variableValues[valueId()]->value(); + try + { + if (isValueId(valueId())) + return minsky::cminsky().variableValues[valueId()]->value(); + } + catch (...) {} // ignore any errors in RHS return 0; } @@ -696,6 +704,7 @@ void VariableBase::draw(cairo_t *cairo) const auto vv=vValue(); if (miniPlot && vv && vv->size()==1) + try { if (cachedTime!=cminsky().t) { @@ -707,56 +716,59 @@ void VariableBase::draw(cairo_t *cairo) const cairo_translate(cairo,-w,-h); miniPlot->draw(cairo,2*w,2*h); } - + catch (...) {} // ignore errors in obtaining values + // For feature 47 - if (type()!=constant && !ioVar() && vv && vv->size()==1 && vv->idxInRange()) - try - { - if (!cachedMantissa || cachedMantissa->cairoContext()!=cairo) - { - cachedMantissa=make_shared(cairo); - cachedMantissa->setFontSize(6.0); - cachedExponent=make_shared(cairo); - cachedExponent->setFontSize(6.0); - cachedValue=nan(""); - } - - auto val=engExp(); - if (value()!=cachedValue) - { - cachedValue=value(); - if (!isnan(value())) { - if (sliderBoundsSet && vv->sliderVisible) - cachedMantissa->setMarkup - (mantissa(val, - int(1+ - (sliderStepRel? - -log10(maxSliderSteps()): - log10(value()/maxSliderSteps()) - )))); - else - cachedMantissa->setMarkup(mantissa(val)); + try + { + if (type()!=constant && !ioVar() && vv && vv->size()==1 && vv->idxInRange()) + { + if (!cachedMantissa || cachedMantissa->cairoContext()!=cairo) + { + cachedMantissa=make_shared(cairo); + cachedMantissa->setFontSize(6.0); + cachedExponent=make_shared(cairo); + cachedExponent->setFontSize(6.0); + cachedValue=nan(""); } - else if (isinf(value())) { // Display non-zero divide by zero as infinity. For ticket 1155 - if (signbit(value())) cachedMantissa->setMarkup("-∞"); - else cachedMantissa->setMarkup("∞"); + + auto val=engExp(); + if (value()!=cachedValue) + { + cachedValue=value(); + if (!isnan(value())) { + if (sliderBoundsSet && vv->sliderVisible) + cachedMantissa->setMarkup + (mantissa(val, + int(1+ + (sliderStepRel? + -log10(maxSliderSteps()): + log10(value()/maxSliderSteps()) + )))); + else + cachedMantissa->setMarkup(mantissa(val)); + } + else if (isinf(value())) { // Display non-zero divide by zero as infinity. For ticket 1155 + if (signbit(value())) cachedMantissa->setMarkup("-∞"); + else cachedMantissa->setMarkup("∞"); + } + else // Display all other NaN cases as ???. For ticket 1155 + cachedMantissa->setMarkup("???"); + cachedExponent->setMarkup(expMultiplier(val.engExp)); } - else // Display all other NaN cases as ???. For ticket 1155 - cachedMantissa->setMarkup("???"); - cachedExponent->setMarkup(expMultiplier(val.engExp)); - } - cachedMantissa->angle=angle+(flipped? M_PI:0); + cachedMantissa->angle=angle+(flipped? M_PI:0); - cairo_move_to(cairo,r.x(w-cachedMantissa->width()-2,-h-hoffs+2), - r.y(w-cachedMantissa->width()-2,-h-hoffs+2)); - cachedMantissa->show(); + cairo_move_to(cairo,r.x(w-cachedMantissa->width()-2,-h-hoffs+2), + r.y(w-cachedMantissa->width()-2,-h-hoffs+2)); + cachedMantissa->show(); - if (val.engExp!=0 && !isnan(value())) // Avoid large exponential number in variable value display. For ticket 1155 - { - cairo_move_to(cairo,r.x(w-cachedExponent->width()-2,0),r.y(w-cachedExponent->width()-2,0)); - cachedExponent->show(); - } - } + if (val.engExp!=0 && !isnan(value())) // Avoid large exponential number in variable value display. For ticket 1155 + { + cairo_move_to(cairo,r.x(w-cachedExponent->width()-2,0),r.y(w-cachedExponent->width()-2,0)); + cachedExponent->show(); + } + } + } catch (...) {} // ignore errors in obtaining values { diff --git a/obsCheck/Dockerfile-tumbleweed b/obsCheck/Dockerfile-tumbleweed index 61af3b65e..a8ac1d0cb 100644 --- a/obsCheck/Dockerfile-tumbleweed +++ b/obsCheck/Dockerfile-tumbleweed @@ -3,7 +3,7 @@ ARG project=minsky ADD . /root RUN zypper addrepo https://download.opensuse.org/repositories/home:hpcoder1/openSUSE_Tumbleweed/home:hpcoder1.repo RUN zypper --gpg-auto-import-keys refresh -RUN zypper --non-interactive install $project +RUN zypper --non-interactive install $project python3 RUN useradd -m minsky RUN su - minsky -c minsky --version RUN python3 -c "import pyminsky"