Skip to content
This repository was archived by the owner on Aug 6, 2022. It is now read-only.

Commit 61dab51

Browse files
committed
Move to svg
1 parent c7c1213 commit 61dab51

File tree

5 files changed

+184
-92
lines changed

5 files changed

+184
-92
lines changed

src/lib/components/Arrow.svelte

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<script lang="ts">
2+
import { Shape } from "$lib/Canvas";
3+
4+
export let from: Shape;
5+
export let to: Shape;
6+
7+
let fromDir, toDir;
8+
$: {
9+
const dx = to.x - from.x;
10+
const dy = to.y - from.y;
11+
if (dx >= Math.abs(dy)) fromDir = "right";
12+
else if (dy >= Math.abs(dx)) fromDir = "bottom";
13+
else if (dx <= -Math.abs(dy)) fromDir = "left";
14+
else fromDir = "top";
15+
16+
if (-dx >= Math.abs(dy)) toDir = "right";
17+
else if (-dy >= Math.abs(dx)) toDir = "bottom";
18+
else if (-dx <= -Math.abs(dy)) toDir = "left";
19+
else toDir = "top";
20+
}
21+
22+
function getPoint(x: number, y: number, dir) {
23+
if (dir == "right") return `${x + Shape.unit / 2} ${y}`;
24+
if (dir == "top") return `${x} ${y - Shape.unit / 2}`;
25+
if (dir == "left") return `${x - Shape.unit / 2} ${y}`;
26+
if (dir == "bottom") return `${x} ${y + Shape.unit / 2}`;
27+
}
28+
</script>
29+
30+
<path
31+
d="M{getPoint(from.x, from.y, fromDir)} L{getPoint(to.x, to.y, toDir)}"
32+
marker-end="url(#triangle)"
33+
/>
34+
35+
<style lang="postcss">
36+
path {
37+
@apply stroke-blue-500;
38+
}
39+
</style>

src/lib/components/Place.svelte

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<script lang="ts">
2+
import type Place from "$lib/Place";
3+
import { Shape } from "$lib/Canvas";
4+
5+
export let place: Place;
6+
</script>
7+
8+
<circle cx={place.shape.x} cy={place.shape.y} r={Shape.unit / 2} />
9+
10+
<style lang="postcss">
11+
circle {
12+
@apply stroke-black fill-white stroke-2;
13+
}
14+
</style>

src/lib/components/Transition.svelte

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<script lang="ts">
2+
import type Transition from "$lib/Transition";
3+
import { Shape } from "$lib/Canvas";
4+
5+
export let transition: Transition;
6+
$: enable = transition.isEnabled();
7+
</script>
8+
9+
<rect
10+
x={transition.shape.x - Shape.unit / 2}
11+
y={transition.shape.y - Shape.unit / 2}
12+
width={Shape.unit}
13+
height={Shape.unit}
14+
class:enable
15+
filter="url(#shadow)"
16+
/>
17+
18+
<style lang="postcss">
19+
rect {
20+
@apply drop-shadow-md fill-white stroke-2;
21+
}
22+
23+
.enable {
24+
@apply stroke-red-500;
25+
}
26+
</style>

src/routes/ex-3.svelte

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
<script lang="ts">
2+
import Place from "$lib/Place";
3+
import Transition from "$lib/Transition";
4+
import TransitionComponent from "$lib/components/Transition.svelte";
5+
import PlaceComponent from "$lib/components/Place.svelte";
6+
import { CanvasManager } from "$lib/Canvas";
7+
import PetriNet, * as PN from "$lib/PetriNet";
8+
import { onMount } from "svelte";
9+
import Marking from "$lib/components/Marking.svelte";
10+
import Arrow from "$lib/components/Arrow.svelte";
11+
12+
const initialMarking = {
13+
free: 1,
14+
wait: 3,
15+
};
16+
17+
let prevMarkings: PN.Marking[] = [initialMarking];
18+
19+
const free = new Place(4, 2, 1, "free", "above");
20+
const busy = new Place(6, 4, 0, "busy", "below");
21+
const docu = new Place(8, 2, 0, "docu", "above");
22+
const wait = new Place(2, 4, 3, "wait", "below");
23+
const end = new Place(10, 4, 0, "end", "below");
24+
25+
const start = new Transition(4, 4, [wait, free], [busy], "start", "below");
26+
const change = new Transition(8, 4, [busy], [docu, end], "change", "below");
27+
const done = new Transition(6, 2, [docu], [free], "done", "above");
28+
29+
let petriNet = new PetriNet(
30+
[free, busy, docu, wait, end],
31+
[start, change, done]
32+
);
33+
34+
function fire(transition: Transition) {
35+
transition.fire();
36+
prevMarkings.push(petriNet.getMarking());
37+
prevMarkings = prevMarkings;
38+
petriNet = petriNet;
39+
}
40+
function reset(marking) {
41+
petriNet.setMarking(marking);
42+
petriNet = petriNet;
43+
}
44+
</script>
45+
46+
<main class="min-h-screen w-screen flex items-stretch">
47+
<svg class="w-full">
48+
<defs>
49+
<!-- prettier-ignore -->
50+
<marker id="triangle" viewBox="0 0 10 10"
51+
refX="10" refY="5"
52+
markerUnits="strokeWidth"
53+
markerWidth="10" markerHeight="10"
54+
orient="auto">
55+
<path d="M 0 0 L 10 5 L 0 10 z" class="fill-blue-500"/>
56+
</marker>
57+
<!-- prettier-ignore -->
58+
<filter id="shadow" x="0" y="0" width="100%" height="120%">
59+
<feOffset result="offOut" in="SourceAlpha" dx="0" dy="5" />
60+
<feGaussianBlur result="blurOut" in="offOut" stdDeviation="10" />
61+
<feBlend in="SourceGraphic" in2="blurOut" mode="normal" />
62+
</filter>
63+
</defs>
64+
{#each petriNet.transitions as transition}
65+
<TransitionComponent {transition} />
66+
{#each transition.preset as pre}
67+
<Arrow from={pre.shape} to={transition.shape} />
68+
{/each}
69+
{#each transition.postset as post}
70+
<Arrow from={transition.shape} to={post.shape} />
71+
{/each}
72+
{/each}
73+
{#each petriNet.places as place}
74+
<PlaceComponent {place} />
75+
{/each}
76+
</svg>
77+
<aside class="w-1/3 bg-slate-800 text-white">
78+
<p>Chọn transition muốn fire:</p>
79+
80+
{#each petriNet.getEnabledTransitions() as transition}
81+
<button on:click={() => fire(transition)}>
82+
{transition.label.content}
83+
</button>
84+
{:else}
85+
<p>Không còn enabled transition.</p>
86+
{/each}
87+
88+
<div>
89+
Markings:
90+
<p>
91+
{#each prevMarkings as marking}
92+
<Marking {marking} />
93+
{/each}
94+
</p>
95+
</div>
96+
97+
<button on:click={() => reset(initialMarking)}>Reset</button>
98+
</aside>
99+
</main>
100+
101+
<style lang="postcss">
102+
button {
103+
@apply bg-green-200 text-green-900 px-2 py-1;
104+
}
105+
</style>

src/routes/index.svelte

Lines changed: 0 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,92 +0,0 @@
1-
<script lang="ts">
2-
import Place from "$lib/Place";
3-
import Transition from "$lib/Transition";
4-
import { CanvasManager } from "$lib/Canvas";
5-
import PetriNet, * as PN from "$lib/PetriNet";
6-
import { onMount } from "svelte";
7-
import Marking from "$lib/components/Marking.svelte";
8-
9-
const initialMarking = {
10-
free: 1,
11-
wait: 3,
12-
};
13-
14-
let prevMarkings: PN.Marking[] = [initialMarking];
15-
16-
const free = new Place(4, 2, 1, "free", "above");
17-
const busy = new Place(6, 4, 0, "busy", "below");
18-
const docu = new Place(8, 2, 0, "docu", "above");
19-
const wait = new Place(2, 4, 3, "wait", "below");
20-
const end = new Place(10, 4, 0, "end", "below");
21-
22-
const start = new Transition(4, 4, [wait, free], [busy], "start", "below");
23-
const change = new Transition(8, 4, [busy], [docu, end], "change", "below");
24-
const done = new Transition(6, 2, [docu], [free], "done", "above");
25-
26-
let petriNet = new PetriNet(
27-
[free, busy, docu, wait, end],
28-
[start, change, done]
29-
);
30-
31-
let canvas;
32-
let canvasManager: CanvasManager;
33-
onMount(() => {
34-
canvasManager = new CanvasManager(canvas);
35-
draw();
36-
});
37-
38-
function draw() {
39-
canvasManager.clear();
40-
canvasManager.drawPlaces(petriNet.places);
41-
canvasManager.drawTransitions(petriNet.transitions);
42-
}
43-
function fire(transition: Transition) {
44-
transition.fire();
45-
draw();
46-
prevMarkings.push(petriNet.getMarking());
47-
prevMarkings = prevMarkings;
48-
petriNet = petriNet;
49-
}
50-
function reset(marking) {
51-
petriNet.setMarking(marking);
52-
draw();
53-
petriNet = petriNet;
54-
}
55-
</script>
56-
57-
<main class="h-screen w-screen flex items-stretch">
58-
<canvas
59-
bind:this={canvas}
60-
width="900"
61-
height="600"
62-
class="w-full border"
63-
/>
64-
<aside class="w-1/3 bg-slate-800 text-white">
65-
<p>Chọn transition muốn fire:</p>
66-
67-
{#each petriNet.getEnabledTransitions() as transition}
68-
<button on:click={() => fire(transition)}>
69-
{transition.label.content}
70-
</button>
71-
{:else}
72-
<p>Không còn enabled transition.</p>
73-
{/each}
74-
75-
<div>
76-
Markings:
77-
<p>
78-
{#each prevMarkings as marking}
79-
<Marking {marking} />
80-
{/each}
81-
</p>
82-
</div>
83-
84-
<button on:click={() => reset(initialMarking)}>Reset</button>
85-
</aside>
86-
</main>
87-
88-
<style lang="postcss">
89-
button {
90-
@apply bg-green-200 text-green-900 px-2 py-1;
91-
}
92-
</style>

0 commit comments

Comments
 (0)