Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
M
Molstar
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Michal Malý
Molstar
Commits
408bf48a
Commit
408bf48a
authored
6 years ago
by
David Sehnal
Browse files
Options
Downloads
Patches
Plain Diff
mol-state: updated transformer model
parent
5ad983e9
No related branches found
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
src/mol-state/state.ts
+22
-13
22 additions, 13 deletions
src/mol-state/state.ts
src/mol-state/transformer.ts
+20
-13
20 additions, 13 deletions
src/mol-state/transformer.ts
src/perf-tests/state.ts
+12
-20
12 additions, 20 deletions
src/perf-tests/state.ts
with
54 additions
and
46 deletions
src/mol-state/state.ts
+
22
−
13
View file @
408bf48a
...
...
@@ -115,22 +115,32 @@ export namespace State {
}
}
async
function
updateNode
(
oldTree
:
TransformTree
,
tree
:
TransformTree
,
objects
:
Objects
,
root
:
Transform
.
Ref
)
{
const
transform
=
tree
.
getValue
(
root
)
!
;
const
parent
=
findParent
(
tree
,
objects
,
root
,
transform
.
transformer
.
definition
.
from
);
async
function
updateNode
(
oldTree
:
TransformTree
,
tree
:
TransformTree
,
objects
:
Objects
,
currentRef
:
Transform
.
Ref
)
{
const
transform
=
tree
.
getValue
(
currentRef
)
!
;
const
parent
=
findParent
(
tree
,
objects
,
currentRef
,
transform
.
transformer
.
definition
.
from
);
console
.
log
(
'
parent
'
,
parent
?
parent
.
ref
:
'
undefined
'
)
if
(
!
oldTree
.
nodes
.
has
(
transform
.
ref
)
||
!
objects
.
has
(
transform
.
ref
))
{
console
.
log
(
'
creating...
'
,
transform
.
transformer
.
id
,
oldTree
.
nodes
.
has
(
transform
.
ref
),
objects
.
has
(
transform
.
ref
));
const
obj
=
await
createObject
(
transform
.
transformer
,
parent
,
transform
.
params
);
obj
.
ref
=
transform
.
ref
;
objects
.
set
(
root
,
{
obj
,
state
:
StateObject
.
StateType
.
Ok
,
version
:
transform
.
version
});
objects
.
set
(
currentRef
,
{
obj
,
state
:
StateObject
.
StateType
.
Ok
,
version
:
transform
.
version
});
}
else
{
console
.
log
(
'
updating...
'
,
transform
.
transformer
.
id
);
const
current
=
objects
.
get
(
transform
.
ref
)
!
.
obj
;
const
oldParams
=
oldTree
.
getValue
(
transform
.
ref
)
!
.
params
;
await
updateObject
(
transform
.
transformer
,
parent
,
current
,
oldParams
,
transform
.
params
);
const
obj
=
objects
.
get
(
root
)
!
;
obj
.
version
=
transform
.
version
;
switch
(
await
updateObject
(
transform
.
transformer
,
parent
,
current
,
oldParams
,
transform
.
params
))
{
case
Transformer
.
UpdateResult
.
Recreate
:
{
const
obj
=
await
createObject
(
transform
.
transformer
,
parent
,
transform
.
params
);
obj
.
ref
=
transform
.
ref
;
objects
.
set
(
currentRef
,
{
obj
,
state
:
StateObject
.
StateType
.
Ok
,
version
:
transform
.
version
});
break
;
}
case
Transformer
.
UpdateResult
.
Updated
:
{
const
obj
=
objects
.
get
(
currentRef
)
!
;
obj
.
version
=
transform
.
version
;
break
;
}
}
}
}
...
...
@@ -139,15 +149,14 @@ export namespace State {
return
t
as
A
;
}
function
createObject
(
transformer
:
Transformer
,
parent
:
StateObject
,
params
:
any
)
{
return
runTask
(
transformer
.
definition
.
apply
(
parent
,
params
,
0
as
any
));
function
createObject
(
transformer
:
Transformer
,
a
:
StateObject
,
params
:
any
)
{
return
runTask
(
transformer
.
definition
.
apply
(
{
a
,
params
}
));
}
async
function
updateObject
(
transformer
:
Transformer
,
parent
:
StateObject
,
obj
:
StateObject
,
oldParams
:
any
,
p
arams
:
any
)
{
async
function
updateObject
(
transformer
:
Transformer
,
a
:
StateObject
,
b
:
StateObject
,
oldParams
:
any
,
newP
arams
:
any
)
{
if
(
!
transformer
.
definition
.
update
)
{
// TODO
throw
'
nyi
'
;
return
Transformer
.
UpdateResult
.
Recreate
;
}
return
transformer
.
definition
.
update
!
(
parent
,
oldParams
,
obj
,
params
,
0
as
any
);
return
runTask
(
transformer
.
definition
.
update
({
a
,
oldParams
,
b
,
newParams
})
);
}
}
This diff is collapsed.
Click to expand it.
src/mol-state/transformer.ts
+
20
−
13
View file @
408bf48a
...
...
@@ -11,6 +11,7 @@ import { Transform } from './tree/transform';
export
interface
Transformer
<
A
extends
StateObject
=
StateObject
,
B
extends
StateObject
=
StateObject
,
P
=
unknown
>
{
apply
(
params
?:
P
,
props
?:
Partial
<
Transform
.
Props
>
):
Transform
<
A
,
B
,
P
>
,
readonly
namespace
:
string
,
readonly
id
:
Transformer
.
Id
,
readonly
definition
:
Transformer
.
Definition
<
A
,
B
,
P
>
}
...
...
@@ -21,9 +22,22 @@ export namespace Transformer {
export
type
To
<
T
extends
Transformer
<
any
,
any
,
any
>>
=
T
extends
Transformer
<
any
,
infer
B
,
any
>
?
B
:
unknown
;
export
type
ControlsFor
<
Props
>
=
{
[
P
in
keyof
Props
]?:
any
}
export
interface
ApplyParams
<
A
extends
StateObject
=
StateObject
,
P
=
unknown
>
{
a
:
A
,
params
:
P
}
export
interface
UpdateParams
<
A
extends
StateObject
=
StateObject
,
B
extends
StateObject
=
StateObject
,
P
=
unknown
>
{
a
:
A
,
b
:
B
,
oldParams
:
P
,
newParams
:
P
}
export
enum
UpdateResult
{
Unchanged
,
Updated
,
Recreate
}
export
interface
Definition
<
A
extends
StateObject
=
StateObject
,
B
extends
StateObject
=
StateObject
,
P
=
unknown
>
{
readonly
name
:
string
,
readonly
namespace
?:
string
,
readonly
from
:
{
type
:
StateObject
.
Type
}[],
readonly
to
:
{
type
:
StateObject
.
Type
}[],
...
...
@@ -31,16 +45,14 @@ export namespace Transformer {
* Apply the actual transformation. It must be pure (i.e. with no side effects).
* Returns a task that produces the result of the result directly.
*/
apply
(
a
:
A
,
params
:
P
,
context
:
TransformContext
):
Task
<
B
>
|
B
,
apply
(
params
:
ApplyParams
<
A
,
P
>
):
Task
<
B
>
|
B
,
/**
* Attempts to update the entity in a non-destructive way.
* For example changing a color scheme of a visual does not require computing new geometry.
* Return/resolve to undefined if the update is not possible.
*
* The ability to resolve the task to undefined is present for "async updates" (i.e. containing an ajax call).
*/
update
?(
a
:
A
,
oldParams
:
P
,
b
:
B
,
newParams
:
P
,
context
:
TransformContext
):
Task
<
B
|
undefined
>
|
B
|
undefined
,
update
?(
params
:
UpdateParams
<
A
,
B
,
P
>
):
Task
<
UpdateResult
>
|
UpdateResult
,
/** Check the parameters and return a list of errors if the are not valid. */
defaultParams
?(
a
:
A
,
context
:
TransformContext
):
P
,
...
...
@@ -66,12 +78,6 @@ export namespace Transformer {
const
registry
=
new
Map
<
Id
,
Transformer
>
();
function
typeToString
(
a
:
{
type
:
StateObject
.
Type
}[])
{
if
(
!
a
.
length
)
return
'
()
'
;
if
(
a
.
length
===
1
)
return
a
[
0
].
type
.
kind
;
return
`(
${
a
.
map
(
t
=>
t
.
type
.
kind
).
join
(
'
|
'
)}
)`
;
}
export
function
get
(
id
:
string
):
Transformer
{
const
t
=
registry
.
get
(
id
as
Id
);
if
(
!
t
)
{
...
...
@@ -81,8 +87,8 @@ export namespace Transformer {
}
export
function
create
<
A
extends
StateObject
,
B
extends
StateObject
,
P
>
(
namespace
:
string
,
definition
:
Definition
<
A
,
B
,
P
>
)
{
const
{
from
,
to
,
name
}
=
definition
;
const
id
=
`
${
namespace
}
.
${
name
}
::
${
typeToString
(
from
)}
->
${
typeToString
(
to
)}
`
as
Id
;
const
{
name
}
=
definition
;
const
id
=
`
${
namespace
}
.
${
name
}
`
as
Id
;
if
(
registry
.
has
(
id
))
{
throw
new
Error
(
`A transform with id '
${
name
}
' is already registered. Please pick a unique identifier for your transforms and/or register them only once. This is to ensure that transforms can be serialized and replayed.`
);
...
...
@@ -90,6 +96,7 @@ export namespace Transformer {
const
t
:
Transformer
<
A
,
B
,
P
>
=
{
apply
(
params
,
props
)
{
return
Transform
.
create
<
A
,
B
,
P
>
(
t
as
any
,
params
,
props
);
},
namespace
,
id
,
definition
};
...
...
This diff is collapsed.
Click to expand it.
src/perf-tests/state.ts
+
12
−
20
View file @
408bf48a
...
...
@@ -18,19 +18,17 @@ export class Square extends _obj<{ a: number }>('square', { name: 'Square', clas
export
class
Circle
extends
_obj
<
{
r
:
number
}
>
(
'
circle
'
,
{
name
:
'
Circle
'
,
class
:
'
shape
'
})
{
}
export
class
Area
extends
_obj
<
{
volume
:
number
}
>
(
'
volume
'
,
{
name
:
'
Volume
'
,
class
:
'
prop
'
})
{
}
const
root
=
new
Root
({
label
:
'
Root
'
},
{});
export
const
CreateSquare
=
_transform
<
Root
,
Square
,
{
a
:
number
}
>
({
name
:
'
create-square
'
,
from
:
[
Root
],
to
:
[
Square
],
apply
(
a
,
p
)
{
apply
(
{
params
:
p
}
)
{
return
new
Square
({
label
:
`Square a=
${
p
.
a
}
`
},
p
);
},
update
(
a
,
_
,
b
,
p
)
{
update
(
{
b
,
newParams
:
p
}
)
{
b
.
props
.
label
=
`Square a=
${
p
.
a
}
`
b
.
data
.
a
=
p
.
a
;
return
b
;
return
Transformer
.
UpdateResult
.
Updated
;
}
});
...
...
@@ -38,13 +36,13 @@ export const CreateCircle = _transform<Root, Circle, { r: number }>({
name
:
'
create-circle
'
,
from
:
[
Root
],
to
:
[
Square
],
apply
(
a
,
p
)
{
apply
(
{
params
:
p
}
)
{
return
new
Circle
({
label
:
`Circle r=
${
p
.
r
}
`
},
p
);
},
update
(
a
,
_
,
b
,
p
)
{
update
(
{
b
,
newParams
:
p
}
)
{
b
.
props
.
label
=
`Circle r=
${
p
.
r
}
`
b
.
data
.
r
=
p
.
r
;
return
b
;
return
Transformer
.
UpdateResult
.
Updated
;
}
});
...
...
@@ -52,30 +50,24 @@ export const CaclArea = _transform<Square | Circle, Area, {}>({
name
:
'
calc-area
'
,
from
:
[
Square
,
Circle
],
to
:
[
Area
],
apply
(
a
)
{
apply
(
{
a
}
)
{
if
(
a
instanceof
Square
)
return
new
Area
({
label
:
'
Area
'
},
{
volume
:
a
.
data
.
a
*
a
.
data
.
a
});
else
if
(
a
instanceof
Circle
)
return
new
Area
({
label
:
'
Area
'
},
{
volume
:
a
.
data
.
r
*
a
.
data
.
r
*
Math
.
PI
});
throw
new
Error
(
'
Unknown object type.
'
);
},
update
(
a
,
_
,
b
)
{
update
(
{
a
,
b
}
)
{
if
(
a
instanceof
Square
)
b
.
data
.
volume
=
a
.
data
.
a
*
a
.
data
.
a
;
else
if
(
a
instanceof
Circle
)
b
.
data
.
volume
=
a
.
data
.
r
*
a
.
data
.
r
*
Math
.
PI
;
else
throw
new
Error
(
'
Unknown object type.
'
);
return
b
;
return
Transformer
.
UpdateResult
.
Updated
;
}
});
async
function
runTask
<
A
>
(
t
:
A
|
Task
<
A
>
):
Promise
<
A
>
{
export
async
function
runTask
<
A
>
(
t
:
A
|
Task
<
A
>
):
Promise
<
A
>
{
if
((
t
as
any
).
run
)
return
await
(
t
as
Task
<
A
>
).
run
();
return
t
as
A
;
}
export
async
function
test
()
{
const
sq
=
await
runTask
(
CreateSquare
.
definition
.
apply
(
root
,
{
a
:
10
},
0
as
any
));
const
area
=
await
runTask
(
CaclArea
.
definition
.
apply
(
sq
,
{},
0
as
any
));
console
.
log
(
area
);
}
export
async
function
testState
()
{
const
state
=
State
.
create
();
...
...
@@ -117,8 +109,8 @@ testState();
export
function
printTTree
(
tree
:
TransformTree
)
{
let
lines
:
string
[]
=
[];
function
print
(
offset
:
string
,
ref
:
any
)
{
le
t
t
=
tree
.
nodes
.
get
(
ref
)
!
;
le
t
tr
=
t
.
value
;
cons
t
t
=
tree
.
nodes
.
get
(
ref
)
!
;
cons
t
tr
=
t
.
value
;
const
name
=
tr
.
transformer
.
id
;
lines
.
push
(
`
${
offset
}
|_ (
${
ref
}
)
${
name
}
${
tr
.
params
?
JSON
.
stringify
(
tr
.
params
)
:
''
}
, v
${
t
.
value
.
version
}
`
);
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment