Skip to content
This repository was archived by the owner on May 5, 2021. It is now read-only.

Commit 4adf1b4

Browse files
committed
memory devtools
1 parent ddc85d3 commit 4adf1b4

File tree

4 files changed

+591
-3
lines changed

4 files changed

+591
-3
lines changed

packages/core/src/JWEditor.ts

+38-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import { ContainerNode } from './VNodes/ContainerNode';
1515
import { AtomicNode } from './VNodes/AtomicNode';
1616
import { SeparatorNode } from './VNodes/SeparatorNode';
1717
import { Memory } from './Memory/Memory';
18+
import { MemoryOrigin } from '../../plugin-devtools/src/components/MemoryComponent';
19+
import { makeVersionable, markNotVersionable } from './Memory/Versionable';
1820

1921
export enum Mode {
2022
CONFIGURATION = 'configuration',
@@ -66,6 +68,7 @@ export class JWEditor {
6668
loadables: {},
6769
};
6870
memory: Memory;
71+
origin: MemoryOrigin;
6972
private memoryID = 0;
7073
vDocument: VDocument;
7174
selection = new VSelection();
@@ -112,6 +115,16 @@ export class JWEditor {
112115
// create memory
113116
this.memory = new Memory();
114117
this.memory.linkToMemory(this.vDocument);
118+
this.origin = makeVersionable({
119+
// for dev tools and plugin's values merge
120+
layers: new Set([]),
121+
actionID: '' as CommandIdentifier,
122+
actionArgs: {} as object,
123+
base: '',
124+
isMaster: true,
125+
});
126+
this.memory.linkToMemory(this.origin);
127+
115128
// create the next memory slice (and freeze the current memory)
116129
this.memoryID++;
117130
this.memory.create(this.memoryID.toString());
@@ -312,15 +325,38 @@ export class JWEditor {
312325
commandName: C,
313326
params?: CommandParams<P, C>,
314327
): Promise<void> {
315-
// switch to the next memory slice (unfreeze the memory)
316-
this.memory.switchTo(this.memoryID.toString());
328+
const oldMasterSliceKey = (this.memoryID - 1).toString();
329+
const newMasterSliceKey = this.memoryID.toString();
330+
const intermediateSliceKey = oldMasterSliceKey + '<>' + newMasterSliceKey;
331+
332+
this.memory.create(intermediateSliceKey).switchTo(intermediateSliceKey);
333+
this.origin.isMaster = false;
334+
335+
const intermediate = {};
336+
markNotVersionable(intermediate);
337+
this.origin.actionID = 'intentName ' + this.memoryID;
338+
this.origin.actionArgs = intermediate;
339+
340+
// in dispatcher: eg:
341+
const winnerSliceKey = intermediateSliceKey + ':pluginA';
342+
this.memory.create(winnerSliceKey).switchTo(winnerSliceKey);
317343

318344
// TODO:
319345
// create an intermediate slice and switch on it
320346
// create memory for each plugin who use the command then
321347
// use squashInto(winnerSliceKey, winnerSliceKey, newMasterSliceKey)
322348
await this.dispatcher.dispatch(commandName, params);
323349

350+
this.origin.layers.clear();
351+
this.origin.layers.add(winnerSliceKey);
352+
if (params) {
353+
markNotVersionable(params);
354+
}
355+
this.origin.actionID = commandName;
356+
this.origin.actionArgs = params;
357+
this.origin.base = intermediateSliceKey;
358+
this.origin.isMaster = true;
359+
324360
// create the next memory slice (and freeze the current memory)
325361
this.memoryID++;
326362
this.memory.create(this.memoryID.toString());

packages/plugin-devtools/assets/DevTools.xml

+128
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,129 @@
357357
</devtools-table>
358358
</t>
359359

360+
<!-- MEMORY SVG COMPONENT -->
361+
<g t-name="MemoryIntermediateLayout" t-attf-transform="translate(0, {{props.intermediate.offsetY * props.heigth}})" class="MemoryIntermediateLayout">
362+
<g t-if="props.intermediate.nexts.length" t-attf-transform="translate({{props.width}}, 0)">
363+
<MemoryIntermediateLayout
364+
t-foreach="props.intermediate.nexts" t-as="next"
365+
activeSlice="props.activeSlice"
366+
selectedSlice="props.selectedSlice"
367+
intermediate="next"
368+
width="props.width"
369+
heigth="props.heigth"/>
370+
<line x1="0" t-att-y1="props.heigth" x2="0" t-att-y2="props.intermediate.height * props.heigth" stroke="black"/>
371+
</g>
372+
<g>
373+
<text t-on-click="selectAction" x="6" y="28" fill="red" stroke="none"
374+
style="font-size: 10px;font-family: arial; cursor: pointer;"><t t-esc="props.intermediate.origin.actionID"/></text>
375+
<line x1="0" t-att-y1="props.heigth" t-att-x2="props.width" t-att-y2="props.heigth" stroke="black"/>
376+
<circle
377+
t-on-click="selectMemory"
378+
t-att-cx="props.width" t-att-cy="props.heigth" r="5"
379+
stroke-width="1"
380+
t-att-fill="props.activeSlice === props.intermediate.key ? 'green' : (props.selectedSlice === props.intermediate.key ? 'yellow' : '#dddddd')"
381+
style="cursor: pointer;"/>
382+
</g>
383+
</g>
384+
385+
<g t-name="MemoryIntermediateFluxLayout" class="MemoryIntermediateFluxLayout" transform="translate(12, 0)">
386+
<!-- <rect t-att-width="props.flux.width * props.width - 24" t-att-height="props.flux.height * props.heigth" fill="transparent" stroke="#dddddd" stroke-width="1"/> -->
387+
<line t-foreach="props.flux.origins" t-as="origin"
388+
t-att-x1="origin.offsetX * props.width" t-att-y1="origin.offsetY * props.heigth"
389+
t-att-x2="flux.width * props.width - 24" t-att-y2="origin.offsetY * props.heigth" stroke="green"/>
390+
<line t-if="props.flux.origins.length"
391+
t-att-x1="flux.width * props.width - 24" t-att-y1="flux.origins[flux.origins.length - 1].offsetY * props.heigth"
392+
t-att-x2="flux.width * props.width - 24" y2="0" stroke="green"/>
393+
<MemoryIntermediateLayout
394+
t-foreach="flux.intermediates" t-as="intermediate"
395+
activeSlice="props.activeSlice"
396+
selectedSlice="props.selectedSlice"
397+
intermediate="intermediate"
398+
width="props.width"
399+
heigth="props.heigth"/>
400+
<line x1="0" y1="0" x2="0" t-att-y2="props.flux.height * props.heigth" stroke="black"/>
401+
</g>
402+
403+
<g t-name="MemoryMasterLayout" class="MemoryMasterLayout" t-attf-transform="translate(0, {{props.master.offsetY * props.heigth}})">
404+
<MemoryIntermediateFluxLayout
405+
activeSlice="props.activeSlice"
406+
selectedSlice="props.selectedSlice"
407+
flux="props.master.flux"
408+
width="props.width"
409+
heigth="props.heigth"/>
410+
<g t-if="!props.master.finished &amp;&amp; props.master.nexts.length" t-attf-transform="translate({{props.master.flux.width * props.width}},0)">
411+
<MemoryMasterLayout
412+
t-foreach="props.master.nexts" t-as="next"
413+
activeSlice="props.activeSlice"
414+
selectedSlice="props.selectedSlice"
415+
master="next"
416+
width="props.width"
417+
heigth="props.heigth"/>
418+
<line t-if="props.master.nexts.length > 1" x1="0" y1="0" x2="0" t-att-y2="props.master.nexts[props.master.nexts.length - 1].offsetY * props.heigth" stroke="black" stroke-width="2"/>
419+
</g>
420+
<line t-if="!props.master.finished &amp;&amp; !props.master.nexts.length"
421+
t-attf-x1="{{props.master.flux.width * props.width}}" y1="0" y2="0" t-attf-x2="{{(props.master.flux.width + 1) * props.width}}" stroke="black" stroke-width="2"/>
422+
<g>
423+
<text t-if="!props.firstItem"
424+
t-on-click="selectAction" x="16" y="-2" fill="red" stroke="none"
425+
style="font-size: 10px;font-family: arial; cursor: pointer;"><t t-esc="props.master.origin.actionID"/></text>
426+
<line x1="0" y1="0" y2="0" t-attf-x2="{{props.master.flux.width * props.width}}" stroke="black" stroke-width="2"/>
427+
<circle
428+
t-on-click="selectMemory"
429+
t-on-dblclick="switchMemory"
430+
t-att-cx="props.master.flux.width * props.width" cy="0" r="8"
431+
stroke-width="1"
432+
t-att-fill="props.activeSlice === props.master.key ? 'green' : (props.selectedSlice === props.master.key ? 'yellow' : '#dddddd')"
433+
style="cursor: pointer;"/>
434+
</g>
435+
</g>
436+
437+
<svg t-name="MemoryFluxLayout" t-att-width="props.flux.width * 60 + 40" t-att-height="(props.flux.height + 1) * 30 + 20">
438+
<g t-attf-transform="translate(0, 20)">
439+
<MemoryMasterLayout
440+
activeSlice="props.activeSlice"
441+
selectedSlice="props.selectedSlice"
442+
master="props.flux.first"
443+
firstItem="true"
444+
width="55"
445+
heigth="30"/>
446+
</g>
447+
</svg>
448+
449+
<!-- MEMORY -->
450+
<devtools-panel t-name="MemoryComponent"
451+
t-on-memory-selected="onSelectMemory"
452+
t-on-memory-switch="onSwitchMemory"
453+
class="active" tabindex="2">
454+
<devtools-contents>
455+
<devtools-mainpane>
456+
<MemoryFluxLayout t-if="state.flux" flux="state.flux" activeSlice="state.activeSlice" selectedSlice="state.selectedSlice"/>
457+
<MemoryFluxLayout t-if="state.flux2" flux="state.flux2" activeSlice="state.activeSlice" selectedSlice="state.selectedSlice"/>
458+
</devtools-mainpane>
459+
<devtools-sidepane>
460+
<div class="about">
461+
<span class="type">Memory Slice</span> <t t-esc="state.selectedSlice.split('-').pop()"/>
462+
</div>
463+
<div class="properties">
464+
<div class="divider">👤 Parent</div>
465+
<span style="cursor: pointer;"
466+
t-if="memory._slicesReference[state.selectedSlice].parent"
467+
t-on-click="selectMemory(memory._slicesReference[state.selectedSlice].parent.name)">
468+
<t t-esc="memory._slicesReference[state.selectedSlice].parent.name"/>
469+
</span>
470+
<div class="divider">👪 Children</div>
471+
<table>
472+
<tbody>
473+
<tr t-foreach="memory._slicesReference[state.selectedSlice].children" t-as="ref">
474+
<td style="cursor: pointer;" t-on-click="selectMemory(ref.name)"><t t-esc="ref.name.split('-').pop()"/></td>
475+
</tr>
476+
</tbody>
477+
</table>
478+
</div>
479+
</devtools-sidepane>
480+
</devtools-contents>
481+
</devtools-panel>
482+
360483
<!-- MAIN -->
361484
<jw-devtools t-name="devtools"
362485
t-att-class="{
@@ -374,11 +497,16 @@
374497
<devtools-button t-on-click="openTab('commands')" t-att-class="{
375498
selected: state.currentTab == 'commands',
376499
}">Commands</devtools-button>
500+
<devtools-button t-on-click="openTab('memory')" t-att-class="{
501+
selected: state.currentTab == 'memory',
502+
}">Memory</devtools-button>
377503
</devtools-navbar>
378504
<t t-if="!state.closed">
379505
<InspectorComponent isOpen="state.currentTab == 'inspector'"/>
380506
<CommandsComponent isOpen="state.currentTab == 'commands'"
381507
commands="state.commands"/>
508+
<MemoryComponent t-if="state.currentTab == 'memory'"
509+
actions="state.actions"/>
382510
</t>
383511
</jw-devtools>
384512

packages/plugin-devtools/src/components/DevToolsComponent.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { CommandsComponent } from './CommandsComponent';
22
import { InspectorComponent } from './InspectorComponent';
33
import { OwlUIComponent } from '../../../owl-ui/src/OwlUIComponent';
44
import { CommandIdentifier, CommandParams } from '../../../core/src/Dispatcher';
5+
import { MemoryComponent } from './MemoryComponent';
56

67
////////////////////////////// todo: use API ///////////////////////////////////
78

@@ -13,7 +14,7 @@ interface DevToolsState {
1314
}
1415

1516
export class DevToolsComponent extends OwlUIComponent<{}> {
16-
static components = { CommandsComponent: CommandsComponent, InspectorComponent };
17+
static components = { CommandsComponent, InspectorComponent, MemoryComponent };
1718
static template = 'devtools';
1819
state: DevToolsState = {
1920
closed: true,

0 commit comments

Comments
 (0)