diff --git a/Makefile b/Makefile index 510a2936a..f02b9bd40 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ TK_LIB=$(dir $(shell find $(TCL_PREFIX) -name tk.tcl -path "*/tk$(TCL_VERSION)*" # root directory for ecolab include files and libraries ECOLAB_HOME=$(shell pwd)/ecolab -export LD_LIBRARY_PATH:=$(ECOLAB_HOME)/lib:$(LD_LIBRARY_PATH) +export LD_LIBRARY_PATH:=$(ECOLAB_HOME)/lib:$(LD_LIBRARY_PATH):/usr/local/lib64 ARCH=$(shell arch) HAVE_CLANG=$(shell if which clang++>/dev/null; then echo 1; fi) diff --git a/RavelCAPI b/RavelCAPI index be1837d64..94e0e7e6b 160000 --- a/RavelCAPI +++ b/RavelCAPI @@ -1 +1 @@ -Subproject commit be1837d64c34df8febb425520dd962ee4bee9cbe +Subproject commit 94e0e7e6bf98ad975740c1440d3920be73346f3a diff --git a/ecolab b/ecolab index d0fde1555..696284281 160000 --- a/ecolab +++ b/ecolab @@ -1 +1 @@ -Subproject commit d0fde1555fc6fff1ad27b9e02d42144573beaea6 +Subproject commit 69628428104f0ff14ab39fbfb84b5f9e7acd060d diff --git a/gui-js/apps/minsky-electron/src/app/events/electron.events.ts b/gui-js/apps/minsky-electron/src/app/events/electron.events.ts index 74a64d139..3bcb1f178 100644 --- a/gui-js/apps/minsky-electron/src/app/events/electron.events.ts +++ b/gui-js/apps/minsky-electron/src/app/events/electron.events.ts @@ -150,6 +150,12 @@ ipcMain.handle( } ); +ipcMain.on( + events.REFRESH_ALL_GODLEY_POPUPS, async () => { + WindowManager.refreshAllGodleyPopups(); + } +); + ipcMain.on(events.ADD_RECENT_FILE, (event, filePath: string) => { RecentFilesManager.addFileToRecentFiles(filePath); }); diff --git a/gui-js/apps/minsky-electron/src/app/managers/WindowManager.ts b/gui-js/apps/minsky-electron/src/app/managers/WindowManager.ts index d4add7a30..f97f76e31 100644 --- a/gui-js/apps/minsky-electron/src/app/managers/WindowManager.ts +++ b/gui-js/apps/minsky-electron/src/app/managers/WindowManager.ts @@ -2,6 +2,7 @@ import { ActiveWindow, AppLayoutPayload, CreateWindowPayload, + events, Functions, minsky, OPEN_DEV_TOOLS_IN_DEV_BUILD, @@ -370,4 +371,14 @@ export class WindowManager { type: 'info', }); } + + static refreshAllGodleyPopups() { + for (const win of WindowManager.activeWindows.values()) + if (win.context!=WindowManager.getMainWindow()) { + try { + win.context?.webContents?.send(events.GODLEY_POPUP_REFRESH); + } + catch (err) {} // absorb any exceptions due to windows disappearing + } + } } diff --git a/gui-js/libs/shared/src/lib/backend/minsky.ts b/gui-js/libs/shared/src/lib/backend/minsky.ts index 3e3468055..49c4621be 100644 --- a/gui-js/libs/shared/src/lib/backend/minsky.ts +++ b/gui-js/libs/shared/src/lib/backend/minsky.ts @@ -1576,7 +1576,6 @@ export class PlotWidget extends Item { this.yvars=new Sequence>(this.$prefix()+'.yvars',Sequence); } async AssignSide(a1: number,a2: string): Promise {return this.$callMethod('AssignSide',a1,a2);} - async Image(...args: any[]): Promise {return this.$callMethod('Image',...args);} async LabelPen(a1: number,a2: ecolab__cairo__Surface): Promise {return this.$callMethod('LabelPen',a1,a2);} async addConstantCurves(): Promise {return this.$callMethod('addConstantCurves');} async addPlotPt(a1: number): Promise {return this.$callMethod('addPlotPt',a1);} diff --git a/gui-js/libs/shared/src/lib/constants/constants.ts b/gui-js/libs/shared/src/lib/constants/constants.ts index 795aa5d15..f83e7ac6b 100644 --- a/gui-js/libs/shared/src/lib/constants/constants.ts +++ b/gui-js/libs/shared/src/lib/constants/constants.ts @@ -52,6 +52,7 @@ export const events = { RECORD: 'record', RECORDING_REPLAY: 'recording-replay', RECORDING_STATUS_CHANGED: 'recording-status-changed', + REFRESH_ALL_GODLEY_POPUPS: 'refresh-all-godley-popups', REFRESH_CSV_IMPORT: 'refresh-csv-import', REPLAY_RECORDING: 'replay-recording', RESET_ZOOM: 'reset-zoom', diff --git a/gui-js/libs/ui-components/src/lib/godley-widget-view/godley-widget-view.component.ts b/gui-js/libs/ui-components/src/lib/godley-widget-view/godley-widget-view.component.ts index 48ebb05e1..c37714693 100644 --- a/gui-js/libs/ui-components/src/lib/godley-widget-view/godley-widget-view.component.ts +++ b/gui-js/libs/ui-components/src/lib/godley-widget-view/godley-widget-view.component.ts @@ -290,10 +290,10 @@ export class GodleyWidgetViewComponent implements OnDestroy, OnInit, AfterViewIn await this.hardRefresh(); } - async hardRefresh(update = true) { + async hardRefresh() { this.multiEquityAllowed = await this.electronService.minsky.multipleEquities(); - if(update) this.godleyIcon.update(); + this.godleyIcon.update(); const allData: string[][] = await this.godleyIcon.table.getData(); @@ -378,7 +378,7 @@ export class GodleyWidgetViewComponent implements OnDestroy, OnInit, AfterViewIn this.cellEditing[1] = undefined; } - await this.hardRefresh(); + this.electronService.send(events.REFRESH_ALL_GODLEY_POPUPS); } } diff --git a/model/godleyIcon.cc b/model/godleyIcon.cc index ad4def455..20df647c3 100644 --- a/model/godleyIcon.cc +++ b/model/godleyIcon.cc @@ -632,6 +632,7 @@ namespace minsky if (m_editorMode) { editor.mouseMove(-1,-1); + minsky().balanceDuplicateColumns(*this, editor.selectedCol); // May be a bit overzealous, but it solves bug 1273, which is caused by a flow which has not yet fully come into existence.... editor.selectedCol=-1; editor.selectedRow=-1; diff --git a/test/testTensorOps.cc b/test/testTensorOps.cc index daa02e614..758eb6da0 100644 --- a/test/testTensorOps.cc +++ b/test/testTensorOps.cc @@ -1195,32 +1195,45 @@ TEST_F(TensorValFixture, reduction2dswapped) EXPECT_TRUE(chc.xvectors[1]==ahc.xvectors[0]); EXPECT_EQ(9,chain.back()->size()); vector expected={3,15,27,5,17,29,7,19,31}; - for (size_t _i=0; _i<9; ++_i) EXPECT_EQ(expected[_i], (*chain.back())[_i]); + // above expected was in sorted index order + auto index=chain.back()->index(); + vector sortedIdx(index.begin(),index.end()); sort(sortedIdx.begin(),sortedIdx.end()); + for (size_t _i=0; _i<9; ++_i) EXPECT_EQ(expected[_i], chain.back()->atHCIndex(sortedIdx[_i])); sex->reductionOp=ravel::Op::prod; chain=createRavelChain(state, arg); expected={0,54,180,4,70,208,10,88,238}; - for (size_t _i=0; _i<9; ++_i) EXPECT_EQ(expected[_i], (*chain.back())[_i]); + index=chain.back()->index(); + sortedIdx=vector(index.begin(),index.end()); sort(sortedIdx.begin(),sortedIdx.end()); + for (size_t _i=0; _i<9; ++_i) EXPECT_EQ(expected[_i], chain.back()->atHCIndex(sortedIdx[_i])); sex->reductionOp=ravel::Op::av; chain=createRavelChain(state, arg); expected={1.5,7.5,13.5,2.5,8.5,14.5,3.5,9.5,15.5}; - for (size_t _i=0; _i<9; ++_i) EXPECT_EQ(expected[_i], (*chain.back())[_i]); + index=chain.back()->index(); + sortedIdx=vector(index.begin(),index.end()); sort(sortedIdx.begin(),sortedIdx.end()); + for (size_t _i=0; _i<9; ++_i) EXPECT_EQ(expected[_i], chain.back()->atHCIndex(sortedIdx[_i])); sex->reductionOp=ravel::Op::stddev; chain=createRavelChain(state, arg); expected={2.12132, 2.12132, 2.12132, 2.12132, 2.12132, 2.12132, 2.12132, 2.12132, 2.12132}; - for (size_t _i=0; _i<9; ++_i) EXPECT_NEAR(expected[_i], (*chain.back())[_i], 1e-4); + index=chain.back()->index(); + sortedIdx=vector(index.begin(),index.end()); sort(sortedIdx.begin(),sortedIdx.end()); + for (size_t _i=0; _i<9; ++_i) EXPECT_NEAR(expected[_i], chain.back()->atHCIndex(sortedIdx[_i]), 1e-4); sex->reductionOp=ravel::Op::min; chain=createRavelChain(state, arg); expected={0,6,12,1,7,13,2,8,14}; - for (size_t _i=0; _i<9; ++_i) EXPECT_EQ(expected[_i], (*chain.back())[_i]); + index=chain.back()->index(); + sortedIdx=vector(index.begin(),index.end()); sort(sortedIdx.begin(),sortedIdx.end()); + for (size_t _i=0; _i<9; ++_i) EXPECT_EQ(expected[_i], chain.back()->atHCIndex(sortedIdx[_i])); sex->reductionOp=ravel::Op::max; chain=createRavelChain(state, arg); expected={3,9,15,4,10,16,5,11,17}; - for (size_t _i=0; _i<9; ++_i) EXPECT_EQ(expected[_i], (*chain.back())[_i]); + index=chain.back()->index(); + sortedIdx=vector(index.begin(),index.end()); sort(sortedIdx.begin(),sortedIdx.end()); + for (size_t _i=0; _i<9; ++_i) EXPECT_EQ(expected[_i], chain.back()->atHCIndex(sortedIdx[_i])); } @@ -1234,28 +1247,42 @@ TEST_F(TensorValFixture, sparseSlicedRavel) auto chain=createRavelChain(state, arg); EXPECT_EQ(2, chain.back()->rank()); EXPECT_EQ(3, chain.back()->size()); - vector expectedi{0,5,6}; - for (size_t _i=0; _i<3; ++_i) EXPECT_EQ(expectedi[_i], chain[1]->index()[_i]); + set expectedi{0,5,6}; + set idx(chain[1]->index().begin(), chain[1]->index().end()); + EXPECT_TRUE(idx==expectedi); expectedi={0,2,7}; - for (size_t _i=0; _i<3; ++_i) EXPECT_EQ(expectedi[_i], chain.back()->index()[_i]); + idx=set(chain.back()->index().begin(),chain.back()->index().end()); + EXPECT_TRUE(idx==expectedi); + vector expectedf{0,1,2,3,4}; for (size_t _i=0; _i<3; ++_i) EXPECT_EQ(expectedf[_i], (*arg)[_i]); expectedf={0,2,3}; - for (size_t _i=0; _i<3; ++_i) EXPECT_EQ(expectedf[_i], (*chain[1])[_i]); + auto index=chain[1]->index(); + vector sortedIdx(index.begin(),index.end()); sort(sortedIdx.begin(),sortedIdx.end()); + for (size_t _i=0; _i<3; ++_i) EXPECT_EQ(expectedf[_i], chain[1]->atHCIndex(sortedIdx[_i])); expectedf={0,3,2}; - for (size_t _i=0; _i<3; ++_i) EXPECT_EQ(expectedf[_i], (*chain.back())[_i]); + index=chain.back()->index(); + sortedIdx=vector(index.begin(),index.end()); sort(sortedIdx.begin(),sortedIdx.end()); + for (size_t _i=0; _i<3; ++_i) EXPECT_EQ(expectedf[_i], chain.back()->atHCIndex(sortedIdx[_i])); sex->collapsed=true; chain=createRavelChain(state, arg); EXPECT_EQ(5, chain.back()->size()); expectedi={0,1,5,6,7}; - for (size_t _i=0; _i<3; ++_i) EXPECT_EQ(expectedi[_i], chain[1]->index()[_i]); + idx=set(chain[1]->index().begin(),chain[1]->index().end()); + EXPECT_TRUE(idx==expectedi); + expectedi={0,2,3,5,7}; - for (size_t _i=0; _i<3; ++_i) EXPECT_EQ(expectedi[_i], chain.back()->index()[_i]); + idx=set(chain.back()->index().begin(),chain.back()->index().end()); + EXPECT_TRUE(idx==expectedi); expectedf={0,1,2,3,4}; - for (size_t _i=0; _i<5; ++_i) EXPECT_EQ(expectedf[_i], (*chain[1])[_i]); + index=chain[1]->index(); + sortedIdx=vector(index.begin(),index.end()); sort(sortedIdx.begin(),sortedIdx.end()); + for (size_t _i=0; _i<5; ++_i) EXPECT_EQ(expectedf[_i], chain[1]->atHCIndex(sortedIdx[_i])); expectedf={0,3,1,4,2}; - for (size_t _i=0; _i<5; ++_i) EXPECT_EQ(expectedf[_i], (*chain.back())[_i]); + index=chain.back()->index(); + sortedIdx=vector(index.begin(),index.end()); sort(sortedIdx.begin(),sortedIdx.end()); + for (size_t _i=0; _i<5; ++_i) EXPECT_EQ(expectedf[_i], chain.back()->atHCIndex(sortedIdx[_i])); } TEST_F(TensorValFixture, calipered)