Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Share #181

Merged
merged 2 commits into from
Nov 14, 2024
Merged

Share #181

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pon2.nimble
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Package

version = "0.23.13"
version = "0.23.14"
author = "Keisuke Izumiya"
description = "Application for Puyo Puyo and Nazo Puyo"
license = "Apache-2.0"
Expand Down
2 changes: 1 addition & 1 deletion src/pon2.nim
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
## | `-d:pon2.avx2=<bool>` | Use AVX2 instructions. | `true` |
## | `-d:pon2.bmi2=<bool>` | Use BMI2 instructions. | `true` |
## | `-d:pon2.fqdn=<str>` | FQDN of the web IDE. | `24ik.github.io` |
## | `-d:pon2.path=<str>` | URI path of the web IDE. | `/pon2/` |
## | `-d:pon2.path=<str>` | URI path of the web simulator. | `/pon2/` |
## | `-d:pon2.workerfilename=<str>` | File name of the web worker. | `worker.min.js` |
## | `-d:pon2.assets.native=<str>` | Assets directory for native app. | `<Pon2Root>/assets` |
## | `-d:pon2.assets.web=<str>` | Assets directory for web app. | `./assets` |
Expand Down
4 changes: 2 additions & 2 deletions src/pon2/app.nim
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
## Compile Options:
## | Option | Description | Default |
## | ------------------------------ | -------------------------------- | ------------------- |
## | `-d:pon2.path=<str>` | URI path of the web IDE. | `/pon2/` |
## | `-d:pon2.path=<str>` | URI path of the web simulator. | `/pon2/` |
## | `-d:pon2.workerfilename=<str>` | File name of the web worker. | `worker.min.js` |
## | `-d:pon2.assets.native=<str>` | Assets directory for native app. | `<Pon2Root>/assets` |
## | `-d:pon2.assets.web=<str>` | Assets directory for web app. | `./assets` |
Expand Down Expand Up @@ -70,7 +70,7 @@ export
simulator.moveOperatingPositionRight, simulator.moveOperatingPositionLeft,
simulator.rotateOperatingPositionRight, simulator.rotateOperatingPositionLeft,
simulator.forward, simulator.backward, simulator.reset, simulator.toUriQuery,
simulator.parseSimulator, simulator.operate
simulator.toUri, simulator.parseSimulator, simulator.operate
export solve.SolveAnswer, solve.solve

when defined(js):
Expand Down
89 changes: 3 additions & 86 deletions src/pon2/app/ide.nim
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
## This module implements the IDE.
##
## Compile Options:
## | Option | Description | Default |
## | -------------------- | ------------------------ | -------- |
## | `-d:pon2.path=<str>` | URI path of the web IDE. | `/pon2/` |
##
when defined(js):
## See also the [backend-specific documentation](./ide/web.html).
##
Expand All @@ -21,7 +16,7 @@ else:
{.experimental: "strictFuncs".}
{.experimental: "views".}

import std/[deques, sequtils, strformat, strutils, sugar, uri]
import std/[deques, sequtils, sugar, uri]
import ./[key, nazopuyo, simulator]
import ../core/[field, fqdn, nazopuyo, pairposition, puyopuyo, requirement]
import ../private/[misc]
Expand Down Expand Up @@ -58,11 +53,6 @@ type

progressBarData: tuple[now: Natural, total: Natural]

const IdeUriPath* {.define: "pon2.path".} = "/pon2/"

static:
doAssert IdeUriPath.startsWith '/'

# ------------------------------------------------
# Constructor
# ------------------------------------------------
Expand Down Expand Up @@ -312,85 +302,12 @@ proc prevAnswer*(self: Ide) {.inline.} =

func toUri*(self: Ide, withPositions = true, fqdn = Pon2): Uri {.inline.} =
## Returns the URI converted from the IDE.
result = initUri()
result.scheme =
case fqdn
of Pon2, Ishikawa: "https"
of Ips: "http"
result.hostname = $fqdn
result.query = self.simulator.toUriQuery(withPositions, fqdn)

# path
case fqdn
of Pon2:
result.path = IdeUriPath
of Ishikawa, Ips:
let modeChar =
case self.simulator.kind
of Regular:
case self.simulator.mode
of Play, PlayEditor: 's'
of Edit: 'e'
of View: 'v'
of Nazo:
'n'
result.path = &"/simu/p{modeChar}.html"

func allowedUriPaths(path: string): seq[string] {.inline.} =
## Returns the allowed paths.
result = @[path]

if path.endsWith "/index.html":
result.add path.dup(removeSuffix("index.html"))
elif path.endsWith '/':
result.add &"{path}index.html"

const AllowedSimulatorUriPaths = IdeUriPath.allowedUriPaths
self.simulator.toUri(withPositions, fqdn)

proc parseIde*(uri: Uri): Ide {.inline.} =
## Returns the IDE converted from the URI.
## If the URI is invalid, `ValueError` is raised.
var
kind = SimulatorKind.low
mode = SimulatorMode.low
let fqdn: IdeFqdn
case uri.hostname
of $Pon2:
if uri.path notin AllowedSimulatorUriPaths:
raise newException(ValueError, "Invalid IDE: " & $uri)

fqdn = Pon2
of $Ishikawa, $Ips:
fqdn = if uri.hostname == $Ishikawa: Ishikawa else: Ips

# kind, mode
case uri.path
of "/simu/pe.html":
kind = Regular
mode = Edit
of "/simu/ps.html":
kind = Regular
mode = Play
of "/simu/pv.html":
kind = Regular
mode = View
of "/simu/pn.html":
kind = Nazo
mode = Play
else:
result = newIde() # HACK: dummy to suppress warning
raise newException(ValueError, "Invalid IDE: " & $uri)
else:
fqdn = Pon2 # HACK: dummy to compile
result = newIde() # HACK: dummy to suppress warning
raise newException(ValueError, "Invalid IDE: " & $uri)

let simulator = uri.query.parseSimulator fqdn
if fqdn in {Ishikawa, Ips}:
simulator.kind = kind
simulator.mode = mode

result = simulator.newIde
uri.parseSimulator.newIde

# ------------------------------------------------
# Keyboard Operation
Expand Down
22 changes: 5 additions & 17 deletions src/pon2/app/ide/web.nim
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ import std/[strformat, sugar]
import karax/[karax, karaxdsl, kdom, vdom]
import ../[ide, key, simulator]
import ../simulator/[web]
import
../../private/app/ide/web/[answer, controller, pagination, settings, share, progress]
import ../../private/app/ide/web/[answer, controller, pagination, settings, progress]

# ------------------------------------------------
# Keyboard Handler
Expand Down Expand Up @@ -48,23 +47,16 @@ const
MainSimulatorIdPrefix = "pon2-ide-mainsimulator-"
AnswerSimulatorIdPrefix = "pon2-ide-answersimulator-"
SettingsIdPrefix = "pon2-ide-settings-"
ShareIdPrefix = "pon2-ide-share-"
AnswerShareIdPrefix = "pon2-ide-share-answer-"

proc newIdeNode(self: Ide, id: string): VNode {.inline.} =
## Returns the IDE node without the external section.
let
simulatorNode = self.simulator.newSimulatorNode(
wrapSection = false, id = &"{MainSimulatorIdPrefix}{id}"
)
settingsId = &"{SettingsIdPrefix}{id}"
let settingsId = &"{SettingsIdPrefix}{id}"

result = buildHtml(tdiv(class = "columns is-mobile is-variable is-1")):
tdiv(class = "column is-narrow"):
tdiv(class = "block"):
simulatorNode
tdiv(class = "block"):
self.newShareNode(&"{ShareIdPrefix}{id}", false)
self.simulator.newSimulatorNode(
wrapSection = false, id = &"{MainSimulatorIdPrefix}{id}"
)
if self.simulator.mode != Play and self.simulator.kind == Nazo:
tdiv(class = "column is-narrow"):
section(class = "section"):
Expand All @@ -80,10 +72,6 @@ proc newIdeNode(self: Ide, id: string): VNode {.inline.} =
if self.answerData.pairsPositionsSeq.len > 0:
tdiv(class = "block"):
self.newAnswerSimulatorNode &"{AnswerSimulatorIdPrefix}{id}"
tdiv(class = "block"):
self.newShareNode(&"{AnswerShareIdPrefix}{id}", true)
tdiv(class = "column is-narrow"):
self.newDisplayNode &"{ShareIdPrefix}{id}"

proc newIdeNode*(
self: Ide, setKeyHandler = true, wrapSection = true, id = ""
Expand Down
87 changes: 87 additions & 0 deletions src/pon2/app/simulator.nim
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
## This module implements Puyo Puyo simulators.
##
## Compile Options:
## | Option | Description | Default |
## | -------------------- | ------------------------------ | -------- |
## | `-d:pon2.path=<str>` | URI path of the web simulator. | `/pon2/` |
##
when defined(js):
## See also the [backend-specific documentation](./simulator/web.html).
##
Expand Down Expand Up @@ -75,6 +80,11 @@ type
operatingPos: Position
editing: SimulatorEditing

const SimulatorUriPath* {.define: "pon2.path".} = "/pon2/"

static:
doAssert SimulatorUriPath.startsWith '/'

# ------------------------------------------------
# Constructor
# ------------------------------------------------
Expand Down Expand Up @@ -662,6 +672,29 @@ func toUriQuery*(
of Ishikawa, Ips:
result = mainQuery

func toUri*(self: Simulator, withPositions = true, fqdn = Pon2): Uri {.inline.} =
## Returns the URI converted from the simulator.
result = initUri()
result.scheme = "https"
result.hostname = $fqdn
result.query = self.toUriQuery(withPositions, fqdn)

# path
case fqdn
of Pon2:
result.path = SimulatorUriPath
of Ishikawa, Ips:
let modeChar =
case self.kind
of Regular:
case self.mode
of Play, PlayEditor: 's'
of Edit: 'e'
of View: 'v'
of Nazo:
'n'
result.path = &"/simu/p{modeChar}.html"

func parseSimulator*(query: string, fqdn: IdeFqdn): Simulator {.inline.} =
## Returns the simulator converted from the URI query.
## If the URI is invalid, `ValueError` is raised.
Expand Down Expand Up @@ -716,6 +749,60 @@ func parseSimulator*(query: string, fqdn: IdeFqdn): Simulator {.inline.} =
of Ishikawa, Ips:
result = parsePuyoPuyo[TsuField](query, fqdn).newSimulator Play

func allowedUriPaths(path: string): seq[string] {.inline.} =
## Returns the allowed paths.
result = @[path]

if path.endsWith "/index.html":
result.add path.dup(removeSuffix("index.html"))
elif path.endsWith '/':
result.add &"{path}index.html"

const AllowedSimulatorUriPaths = SimulatorUriPath.allowedUriPaths

proc parseSimulator*(uri: Uri): Simulator {.inline.} =
## Returns the simulator converted from the URI.
## If the URI is invalid, `ValueError` is raised.
var
kind = SimulatorKind.low
mode = SimulatorMode.low
let fqdn: IdeFqdn
case uri.hostname
of $Pon2:
if uri.path notin AllowedSimulatorUriPaths:
raise newException(ValueError, "Invalid simulator: " & $uri)

fqdn = Pon2
of $Ishikawa, $Ips:
fqdn = if uri.hostname == $Ishikawa: Ishikawa else: Ips

# kind, mode
case uri.path
of "/simu/pe.html":
kind = Regular
mode = Edit
of "/simu/ps.html":
kind = Regular
mode = Play
of "/simu/pv.html":
kind = Regular
mode = View
of "/simu/pn.html":
kind = Nazo
mode = Play
else:
result = newSimulator[TsuField]() # HACK: dummy to suppress warning
raise newException(ValueError, "Invalid simulator: " & $uri)
else:
fqdn = Pon2 # HACK: dummy to compile
result = newSimulator[TsuField]() # HACK: dummy to suppress warning
raise newException(ValueError, "Invalid simulator: " & $uri)

result = uri.query.parseSimulator fqdn
if fqdn in {Ishikawa, Ips}:
result.kind = kind
result.mode = mode

# ------------------------------------------------
# Keyboard Operation
# ------------------------------------------------
Expand Down
25 changes: 17 additions & 8 deletions src/pon2/app/simulator/web.nim
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,25 @@ import
palette,
requirement,
select,
share,
]

# ------------------------------------------------
# Node
# ------------------------------------------------

const ReqIdPrefix = "pon2-simulator-req-"
const
ReqIdPrefix = "pon2-simulator-req-"
ShareIdPrefix = "pon2-simulator-share-"

proc newSimulatorNode(self: Simulator, id: string, hideSelect: bool): VNode {.inline.} =
proc newSimulatorNode(self: Simulator, id: string, isAnswer: bool): VNode {.inline.} =
## Returns the node without the external section.
buildHtml(tdiv):
tdiv(class = "block"):
self.newRequirementNode(id = &"{ReqIdPrefix}{id}")
let shareId = &"{ShareIdPrefix}{id}"

result = buildHtml(tdiv):
if self.kind == Nazo:
tdiv(class = "block"):
self.newRequirementNode &"{ReqIdPrefix}{id}"
tdiv(class = "block"):
tdiv(class = "columns is-mobile is-variable is-1"):
tdiv(class = "column is-narrow"):
Expand All @@ -46,9 +52,11 @@ proc newSimulatorNode(self: Simulator, id: string, hideSelect: bool): VNode {.in
if self.mode != Edit:
tdiv(class = "block"):
self.newMessagesNode
if not hideSelect and self.mode != Play:
if not isAnswer and self.mode != Play:
tdiv(class = "block"):
self.newSelectNode
tdiv(class = "block"):
self.newShareNode(shareId, isAnswer)
if self.mode != Edit:
tdiv(class = "column is-narrow"):
tdiv(class = "block"):
Expand All @@ -61,12 +69,13 @@ proc newSimulatorNode(self: Simulator, id: string, hideSelect: bool): VNode {.in
self.newPaletteNode
tdiv(class = "block"):
self.newPairsNode
self.newDisplayNode shareId

proc newSimulatorNode*(
self: Simulator, wrapSection = true, id = "", hideSelect = false
self: Simulator, wrapSection = true, id = "", isAnswer = false
): VNode {.inline.} =
## Returns the simulator node.
let node = self.newSimulatorNode(id, hideSelect)
let node = self.newSimulatorNode(id, isAnswer)

if wrapSection:
result = buildHtml(section(class = "section")):
Expand Down
2 changes: 1 addition & 1 deletion src/pon2/private/app/ide/web/answer.nim
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ import ../../../../app/simulator/[web]

proc newAnswerSimulatorNode*(ide: Ide, id: string): VNode {.inline.} =
## Returns the answer simulator node.
ide.answerSimulator.newSimulatorNode(wrapSection = false, id = id, hideSelect = true)
ide.answerSimulator.newSimulatorNode(wrapSection = false, id = id, isAnswer = true)
Loading