Skip to content

Commit e41d688

Browse files
committed
Merge branch 'gh-pages' of https://github.com/LivelyKernel/lively4-core into gh-pages
2 parents 5ce2310 + fac6230 commit e41d688

File tree

7 files changed

+146
-31
lines changed

7 files changed

+146
-31
lines changed

src/client/reactive/active-expression-rewriting/active-expression-rewriting.js

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,8 @@ class Dependency {
152152
const compKey = CompositeKeyToDependencies.getLeftFor(this);
153153
CompositeKeyToDependencies.removeRight(this);
154154
HooksToDependencies.disconnectAllForDependency(this);
155-
156-
if(!CompositeKeyToDependencies.hasLeft(compKey)) {
155+
156+
if (!CompositeKeyToDependencies.hasLeft(compKey)) {
157157
ContextAndIdentifierCompositeKey.remove(compKey);
158158
}
159159
}
@@ -167,9 +167,9 @@ class Dependency {
167167
return [context, identifier, value];
168168
}
169169

170-
notifyAExprs(location) {
170+
notifyAExprs(location, hook) {
171171
const aexprs = DependenciesToAExprs.getAExprsForDep(this);
172-
DependencyManager.checkAndNotifyAExprs(aexprs, location);
172+
DependencyManager.checkAndNotifyAExprs(aexprs, location, this, hook);
173173
}
174174

175175
isMemberDependency() {
@@ -243,6 +243,16 @@ export class AEDebuggingCache {
243243
triplesCallback((await this.getDependencyTriplesForFile(url)));
244244
}
245245

246+
getTripletsForAE(ae) {
247+
const result = [];
248+
for (const dependency of DependenciesToAExprs.getDepsForAExpr(ae)) {
249+
for (const hook of HooksToDependencies.getHooksForDep(dependency)) {
250+
result.push({ hook, dependency, ae });
251+
}
252+
}
253+
return result;
254+
}
255+
246256
/*MD ## Caching MD*/
247257

248258
/*MD ## Code Change API MD*/
@@ -362,13 +372,9 @@ export class AEDebuggingCache {
362372
}
363373

364374
async getDependencyTriplesForFile(url) {
365-
const result = [];
375+
let result = [];
366376
for (const ae of DependenciesToAExprs.getAEsInFile(url)) {
367-
for (const dependency of DependenciesToAExprs.getDepsForAExpr(ae)) {
368-
for (const hook of HooksToDependencies.getHooksForDep(dependency)) {
369-
result.push({ hook, dependency, ae });
370-
}
371-
}
377+
result = result.concat(this.getTripletsForAE(ae));
372378
}
373379
for (const hook of await HooksToDependencies.getHooksInFile(url)) {
374380
for (const dependency of HooksToDependencies.getDepsForHook(hook)) {
@@ -383,6 +389,7 @@ export class AEDebuggingCache {
383389
}
384390
return result;
385391
}
392+
386393
}
387394

388395
async function relatedFiles(dependencies, aexprs) {}
@@ -436,11 +443,11 @@ const DependenciesToAExprs = {
436443
},
437444

438445
getAExprsForDep(dep) {
439-
if(!this._depsToAExprs.hasLeft(dep)) return [];
446+
if (!this._depsToAExprs.hasLeft(dep)) return [];
440447
return Array.from(this._depsToAExprs.getRightsFor(dep));
441448
},
442449
getDepsForAExpr(aexpr) {
443-
if(!this._depsToAExprs.hasRight(aexpr)) return [];
450+
if (!this._depsToAExprs.hasRight(aexpr)) return [];
444451
return Array.from(this._depsToAExprs.getLeftsFor(aexpr));
445452
},
446453

@@ -510,16 +517,16 @@ const HooksToDependencies = {
510517
DebuggingCache.updateFiles([ae.meta().get("location").file]);
511518
}
512519
}
513-
520+
514521
this._hooksToDeps.removeAllLeftFor(dep);
515522
},
516523

517524
getDepsForHook(hook) {
518-
if(!this._hooksToDeps.hasLeft(hook)) return [];
525+
if (!this._hooksToDeps.hasLeft(hook)) return [];
519526
return Array.from(this._hooksToDeps.getRightsFor(hook));
520527
},
521528
getHooksForDep(dep) {
522-
if(!this._hooksToDeps.hasRight(dep)) return [];
529+
if (!this._hooksToDeps.hasRight(dep)) return [];
523530
return Array.from(this._hooksToDeps.getLeftsFor(dep));
524531
},
525532

@@ -588,13 +595,17 @@ class Hook {
588595
this.locations = this.locations.filter(l => l);
589596
return this.locations;
590597
}
591-
598+
599+
informationString() {
600+
return "Generic Hook";
601+
}
602+
592603
untrack() {}
593604

594-
notifyDependencies(location) {
605+
notifyDependencies(location) {
595606
const loc = location || TracingHandler.findRegistrationLocation();
596607
this.addLocation(loc);
597-
HooksToDependencies.getDepsForHook(this).forEach(dep => dep.notifyAExprs(loc));
608+
HooksToDependencies.getDepsForHook(this).forEach(dep => dep.notifyAExprs(loc, this));
598609

599610
this.getLocations().then(locations => DebuggingCache.updateFiles(locations.map(loc => loc.file)));
600611
for (const dep of HooksToDependencies.getDepsForHook(this)) {
@@ -610,14 +621,18 @@ class Hook {
610621
class SourceCodeHook extends Hook {
611622
static getOrCreateFor(context, identifier) {
612623
const compKey = ContextAndIdentifierCompositeKey.for(context, identifier);
613-
return CompositeKeyToSourceCodeHook.getOrCreateRightFor(compKey, key => new SourceCodeHook());
624+
return CompositeKeyToSourceCodeHook.getOrCreateRightFor(compKey, key => new SourceCodeHook(context, identifier));
614625
}
615626

616627
static get(context, identifier) {
617628
const compKey = ContextAndIdentifierCompositeKey.for(context, identifier);
618629
return CompositeKeyToSourceCodeHook.getRightFor(compKey);
619630
}
620-
631+
632+
informationString() {
633+
return "SourceCodeHook: " + this.context + "." + this.identifier;
634+
}
635+
621636
untrack() {
622637
CompositeKeyToSourceCodeHook.removeRight(this);
623638
}
@@ -912,9 +927,9 @@ class DependencyManager {
912927
}
913928

914929
// #TODO, #REFACTOR: extract into configurable dispatcher class
915-
static checkAndNotifyAExprs(aexprs, location) {
930+
static checkAndNotifyAExprs(aexprs, location, dependency, hook) {
916931
aexprs.forEach(aexpr => aexpr.updateDependencies());
917-
aexprs.forEach(aexpr => aexpr.checkAndNotify(location));
932+
aexprs.forEach(aexpr => aexpr.checkAndNotify(location, dependency, hook));
918933
}
919934

920935
/**

src/client/reactive/active-expression/active-expression.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ export class BaseActiveExpression {
318318
* Mainly for implementation strategies.
319319
* @public
320320
*/
321-
checkAndNotify(location) {
321+
checkAndNotify(location, dependency, hook) {
322322
if (!this._isEnabled) {
323323
return;
324324
}
@@ -330,7 +330,7 @@ export class BaseActiveExpression {
330330
const lastValue = this.lastValue;
331331
this.storeResult(value);
332332
Promise.resolve(location)
333-
.then(trigger => this.logEvent('changed value', { value, trigger, lastValue }));
333+
.then(trigger => this.logEvent('changed value', { value, trigger, dependency, hook, lastValue }));
334334

335335
this.notify(value, {
336336
lastValue,
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<template id="aexpr-graph">
2+
<style data-src="/src/external/font-awesome/css/font-awesome.css"></style>
3+
<style data-src="/templates/livelystyle.css"></style>
4+
<style>
5+
:host {
6+
7+
}
8+
</style>
9+
<div style="width: 100%; height: 100%">
10+
<div id="graph" style="text-align: center; width: 100%; height: 100%;"></div>
11+
</div>
12+
13+
</template>
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import Morph from 'src/components/widgets/lively-morph.js';
2+
import { AExprRegistry } from 'src/client/reactive/active-expression/active-expression.js';
3+
import { DebuggingCache } from 'src/client/reactive/active-expression-rewriting/active-expression-rewriting.js';
4+
//import d3 from "src/external/d3-graphviz.js"
5+
6+
export default class AexprGraph extends Morph {
7+
async initialize() {
8+
this.windowTitle = "Active Expression Graph";
9+
let width = window.innerWidth;
10+
let height = window.innerHeight;
11+
this.graphViz = await (<d3-graphviz style="background:gray; width:1200px; height: 800px"></d3-graphviz>)
12+
this.graph.append(this.graphViz);
13+
this.graphViz.setDotData(this.graphData());
14+
//const graphvizElement = this.shadowRoot.querySelector("svg");
15+
//graphvizElement.setAttribute("height", "400px");
16+
}
17+
18+
graphData() {
19+
20+
const edges = [];
21+
const nodes = [];
22+
23+
const aes = AExprRegistry.allAsArray();
24+
25+
let i = 0;
26+
let j = 0;
27+
for (const ae of aes) {
28+
const aeData = this.extractData(ae);
29+
nodes.push(`AE${i} [shape="record" label="{${aeData.join("|")}}"]`);
30+
for (const { _, dep, hook } of DebuggingCache.getTripletsForAE(ae)) {
31+
nodes.push(`HOOK${j} [shape="record" label="{${this.escapeTextForDOTRecordLabel(hook.informationString())}}"]`);
32+
edges.push(`AE${i} -> HOOK${j}`);
33+
j++;
34+
}
35+
i++;
36+
}
37+
38+
return `digraph {
39+
graph [ splines="true" overlap="false" ];
40+
node [ style="solid" shape="plain" fontname="Arial" fontsize="14" fontcolor="black" ];
41+
edge [ fontname="Arial" fontsize="8" ];
42+
43+
${edges.join(";")}
44+
${nodes.join(";")}
45+
}`;
46+
}
47+
48+
extractData(ae) {
49+
const data = [];
50+
51+
data.push(this.escapeTextForDOTRecordLabel(ae.meta().get("id")));
52+
data.push(this.escapeTextForDOTRecordLabel(ae.meta().get("sourceCode")));
53+
const location = ae.meta().get("location");
54+
const locationText = location.file.substring(location.file.lastIndexOf("/") + 1) + " line " + location.start.line;
55+
data.push(this.escapeTextForDOTRecordLabel(locationText));
56+
return data;
57+
}
58+
59+
escapeTextForDOTRecordLabel(text) {
60+
text = text.replaceAll("\\", "\\\\");
61+
text = text.replaceAll("<", "\\<");
62+
text = text.replaceAll(">", "\\>");
63+
text = text.replaceAll("{", "\\{");
64+
text = text.replaceAll("}", "\\}");
65+
text = text.replaceAll("[", "\\[");
66+
text = text.replaceAll("]", "\\]");
67+
return text;
68+
}
69+
70+
livelyMigrate(other) {}
71+
72+
async livelyExample() {}
73+
74+
get graph() {
75+
return this.get("#graph");
76+
}
77+
78+
}

src/client/reactive/components/basic/aexpr-timeline.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,13 @@ export default class EventDrops extends Morph {
224224
async humanizeEventData(event) {
225225
switch (event.type) {
226226
case 'changed value':
227-
return <div>{this.humanizePosition(event.value.trigger.file, event.value.trigger.start.line)} <br /> <span style="color:#00AAAA">{event.value.lastValue}</span><span style="color:#00AAAA">{event.value.value}</span></div>;
227+
return <div>
228+
{this.humanizePosition(event.value.trigger.file, event.value.trigger.start.line)}
229+
<br />
230+
<span style="color:#00AAAA">{event.value.lastValue}</span><span style="color:#00AAAA">{event.value.value}</span>
231+
<br />
232+
{event.value.hook.informationString()}
233+
</div>;
228234
case 'created':
229235
{
230236
const ae = event.value.ae;
@@ -245,7 +251,7 @@ export default class EventDrops extends Morph {
245251
return (event.value || "").toString();
246252
}
247253
}
248-
254+
249255
get tooltip() {
250256
let existing = document.body.querySelectorAll('#event-drops-tooltip')[0];
251257

@@ -379,7 +385,11 @@ export default class EventDrops extends Morph {
379385
const lineElement = this.shadowRoot.querySelectorAll(".line-label").find(element => {
380386
const dropLineName = element.innerHTML;
381387
const dropLineAEName = dropLineName.substring(0, dropLineName.lastIndexOf(" "));
382-
return (ae.meta().get('id') + " ").includes(dropLineAEName + " ");
388+
let aeID = ae.meta().get('id');
389+
if(this.groupByLine.checked) {
390+
aeID = aeID.substring(0, aeID.lastIndexOf('#'));
391+
}
392+
return (aeID + " ").includes(dropLineAEName + " ");
383393
});
384394
lineElement.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
385395

src/client/reactive/reactive-jsx/ui-aexpr.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ function removeObsoleteListeners() {
1717
// `this` is an ActiveExpression
1818
export function toDOMNode(builder = x => x) {
1919
const { value } = this.evaluateToCurrentValue();
20-
let currentNode = builder(value.value);
20+
let currentNode = builder(value);
2121

2222
function updateDOMNode(val) {
2323
// lively.notify("change aexpr result", val)

test.workspace

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
{
2-
"source": "https://lively-kernel.org/lively4/lively4-tom/test.js",
2+
"source": "https://lively-kernel.org/lively4/aexpr/test.js",
33
"sources": [
4-
"https://lively-kernel.org/lively4/lively4-tom/test.js",
5-
"https://lively-kernel.org/lively4/lively4-tom/test-loader.js"
4+
"https://lively-kernel.org/lively4/aexpr/test.js"
65
],
76
"options": {
87
"systemJS": false,

0 commit comments

Comments
 (0)