Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
F
frama-c
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Container Registry
Model registry
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
pub
frama-c
Commits
fabff1ff
Commit
fabff1ff
authored
4 years ago
by
Loïc Correnson
Browse files
Options
Downloads
Patches
Plain Diff
[ivette] better types for states
parent
520387c2
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
ivette/src/frama-c/states.ts
+53
-43
53 additions, 43 deletions
ivette/src/frama-c/states.ts
with
53 additions
and
43 deletions
ivette/src/frama-c/states.ts
+
53
−
43
View file @
fabff1ff
...
@@ -12,27 +12,14 @@
...
@@ -12,27 +12,14 @@
import
React
from
'
react
'
;
import
React
from
'
react
'
;
import
*
as
Dome
from
'
dome
'
;
import
*
as
Dome
from
'
dome
'
;
import
*
as
Json
from
'
dome/data/json
'
;
import
*
as
Json
from
'
dome/data/json
'
;
import
{
ArrayModel
}
from
'
dome/table/arrays
'
;
import
{
Order
}
from
'
dome/data/compare
'
;
import
*
as
GlobalStates
from
'
dome/data/states
'
;
import
{
useModel
}
from
'
dome/table/models
'
;
import
{
CompactModel
}
from
'
dome/table/arrays
'
;
import
*
as
Server
from
'
./server
'
;
import
*
as
Server
from
'
./server
'
;
/**
const
PROJECT
=
'
frama-c.project
'
;
* @event
const
STATE_PREFIX
=
'
frama-c.state.
'
;
* @name 'frama-c.project'
* @summary Current Project Updates
* @description
* Exported as `State.PROJECT` in public API.
*/
export
const
PROJECT
=
'
frama-c.project
'
;
/**
* @event
* @name 'frama-c.state.*'
* @summary State Notification Events.
* @description
* Event `'frama-c.state.<id>'` for project `<id>`.
* The prefix `'frama-c.state.'` is exported as `States.STATE` in public API.
*/
export
const
STATE
=
'
frama-c.state.
'
;
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// --- Pretty Printing (Browser Console)
// --- Pretty Printing (Browser Console)
...
@@ -207,15 +194,16 @@ export interface Fetches<K, A> {
...
@@ -207,15 +194,16 @@ export interface Fetches<K, A> {
reload
:
boolean
;
reload
:
boolean
;
pending
:
number
;
pending
:
number
;
updated
:
A
[];
updated
:
A
[];
removed
:
Json
.
key
<
K
>
[];
removed
:
K
[];
}
}
export
interface
Array
<
K
,
A
>
{
export
interface
Array
<
K
,
A
>
{
name
:
string
;
name
:
string
;
key
:
keyof
A
;
order
:
Order
<
A
>
;
getkey
:
(
row
:
A
)
=>
K
;
signal
:
Server
.
Signal
;
signal
:
Server
.
Signal
;
fetch
:
Server
.
GetRequest
<
number
,
Fetches
<
K
,
A
>>
;
reload
:
Server
.
GetRequest
<
null
,
null
>
;
reload
:
Server
.
GetRequest
<
null
,
null
>
;
fetch
:
Server
.
GetRequest
<
number
,
Fetches
<
K
,
A
>>
;
}
}
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
...
@@ -238,7 +226,7 @@ class SyncState<A> {
...
@@ -238,7 +226,7 @@ class SyncState<A> {
constructor
(
h
:
Handler
<
A
>
)
{
constructor
(
h
:
Handler
<
A
>
)
{
this
.
handler
=
h
;
this
.
handler
=
h
;
this
.
UPDATE
=
STATE
+
h
.
name
;
this
.
UPDATE
=
STATE
_PREFIX
+
h
.
name
;
this
.
upToDate
=
false
;
this
.
upToDate
=
false
;
this
.
value
=
undefined
;
this
.
value
=
undefined
;
this
.
update
=
this
.
update
.
bind
(
this
);
this
.
update
=
this
.
update
.
bind
(
this
);
...
@@ -291,7 +279,7 @@ class SyncState<A> {
...
@@ -291,7 +279,7 @@ class SyncState<A> {
const
syncStates
=
new
Map
<
string
,
SyncState
<
any
>>
();
const
syncStates
=
new
Map
<
string
,
SyncState
<
any
>>
();
function
getSyncState
<
A
>
(
h
:
Handler
<
A
>
):
SyncState
<
A
>
{
function
getSyncState
<
A
>
(
h
:
Handler
<
A
>
):
SyncState
<
A
>
{
const
id
=
currentProject
+
'
@
'
+
h
.
name
;
const
id
=
`
${
currentProject
}
@
${
h
.
name
}
`
;
let
s
=
syncStates
.
get
(
id
);
let
s
=
syncStates
.
get
(
id
);
if
(
!
s
)
{
if
(
!
s
)
{
s
=
new
SyncState
(
h
);
s
=
new
SyncState
(
h
);
...
@@ -335,15 +323,16 @@ export function useSyncValue<A>(va: Value<A>): A | undefined {
...
@@ -335,15 +323,16 @@ export function useSyncValue<A>(va: Value<A>): A | undefined {
// one per project
// one per project
class
SyncArray
<
K
,
A
>
{
class
SyncArray
<
K
,
A
>
{
handler
:
Array
<
K
,
A
>
;
handler
:
Array
<
K
,
A
>
;
model
:
ArrayModel
<
A
>
;
upToDate
:
boolean
;
upToDate
:
boolean
;
fetching
:
boolean
;
fetching
:
boolean
;
model
:
CompactModel
<
K
,
A
>
;
constructor
(
h
:
Array
<
K
,
A
>
,
m
?:
ArrayModel
<
A
>
)
{
constructor
(
h
:
Array
<
K
,
A
>
)
{
this
.
handler
=
h
;
this
.
handler
=
h
;
this
.
fetching
=
false
;
this
.
fetching
=
false
;
this
.
upToDate
=
false
;
this
.
upToDate
=
false
;
this
.
model
=
m
??
new
ArrayModel
<
A
>
(
h
.
key
);
this
.
model
=
new
CompactModel
(
h
.
getkey
);
this
.
model
.
setNaturalOrder
(
h
.
order
);
this
.
fetch
=
this
.
fetch
.
bind
(
this
);
this
.
fetch
=
this
.
fetch
.
bind
(
this
);
this
.
reload
=
this
.
reload
.
bind
(
this
);
this
.
reload
=
this
.
reload
.
bind
(
this
);
this
.
update
=
this
.
update
.
bind
(
this
);
this
.
update
=
this
.
update
.
bind
(
this
);
...
@@ -358,15 +347,19 @@ class SyncArray<K, A> {
...
@@ -358,15 +347,19 @@ class SyncArray<K, A> {
try
{
try
{
this
.
fetching
=
true
;
this
.
fetching
=
true
;
let
pending
;
let
pending
;
/* eslint-disable no-await-in-loop */
do
{
do
{
const
data
=
await
Server
.
send
(
this
.
handler
.
fetch
,
50
);
const
data
=
await
Server
.
send
(
this
.
handler
.
fetch
,
50
);
const
{
reload
=
false
,
removed
=
[],
updated
=
[]
}
=
data
;
const
{
reload
=
false
,
removed
=
[],
updated
=
[]
}
=
data
;
const
{
model
}
=
this
;
const
{
model
}
=
this
;
if
(
reload
)
model
.
clear
();
if
(
reload
)
model
.
removeAllData
();
removed
.
forEach
((
k
)
=>
model
.
remove
(
k
));
model
.
updateData
(
updated
);
updated
.
forEach
((
d
)
=>
model
.
add
(
d
));
model
.
removeData
(
removed
);
if
(
reload
||
updated
.
length
>
0
||
removed
.
length
>
0
)
model
.
reload
();
pending
=
data
.
pending
??
0
;
pending
=
data
.
pending
??
0
;
}
while
(
pending
>
0
);
}
while
(
pending
>
0
);
/* eslint-enable no-await-in-loop */
}
catch
(
error
)
{
}
catch
(
error
)
{
PP
.
error
(
PP
.
error
(
`Fail to retrieve the value of syncArray '
${
this
.
handler
.
name
}
.`
,
`Fail to retrieve the value of syncArray '
${
this
.
handler
.
name
}
.`
,
...
@@ -404,16 +397,12 @@ const syncArrays = new Map<string, SyncArray<any, any>>();
...
@@ -404,16 +397,12 @@ const syncArrays = new Map<string, SyncArray<any, any>>();
function
getSyncArray
<
K
,
A
>
(
function
getSyncArray
<
K
,
A
>
(
array
:
Array
<
K
,
A
>
,
array
:
Array
<
K
,
A
>
,
model
?:
ArrayModel
<
A
>
,
):
SyncArray
<
K
,
A
>
{
):
SyncArray
<
K
,
A
>
{
const
id
=
currentProject
+
'
@
'
+
array
.
name
;
const
id
=
`
${
currentProject
}
@
${
array
.
name
}
`
;
let
st
=
syncArrays
.
get
(
id
);
let
st
=
syncArrays
.
get
(
id
);
if
(
!
st
)
{
if
(
!
st
)
{
st
=
new
SyncArray
(
array
,
model
);
st
=
new
SyncArray
(
array
);
syncArrays
.
set
(
id
,
st
);
syncArrays
.
set
(
id
,
st
);
}
else
if
(
model
&&
st
.
model
!==
model
)
{
st
.
model
=
model
;
st
.
reload
();
}
}
return
st
;
return
st
;
}
}
...
@@ -433,18 +422,39 @@ export function reloadArray<K, A>(arr: Array<K, A>) {
...
@@ -433,18 +422,39 @@ export function reloadArray<K, A>(arr: Array<K, A>) {
/**
/**
Use Synchronized Array (Custom React Hook).
Use Synchronized Array (Custom React Hook).
This React Hook is _not_ responsive to model updates, it only
returns the array model.
To listen to array updates, use `Models.useModel(model)` or `useSyncArray()`.
Array views automatically listen to model updates.
*/
*/
export
function
useSync
Array
<
K
,
A
>
(
export
function
useSync
Model
<
K
,
A
>
(
arr
:
Array
<
K
,
A
>
,
arr
:
Array
<
K
,
A
>
,
model
?:
ArrayModel
<
A
>
,
):
CompactModel
<
K
,
A
>
{
):
ArrayModel
<
A
>
{
Dome
.
useUpdate
(
PROJECT
);
Dome
.
useUpdate
(
PROJECT
);
const
st
=
getSyncArray
(
arr
,
model
);
const
st
=
getSyncArray
(
arr
);
React
.
useEffect
(
st
.
update
);
React
.
useEffect
(
st
.
update
);
Server
.
useSignal
(
arr
.
signal
,
st
.
fetch
);
Server
.
useSignal
(
arr
.
signal
,
st
.
fetch
);
return
st
.
model
;
return
st
.
model
;
}
}
/**
Use Synchronized Array (Custom React Hook).
This React Hook is _not_ responsive to model updates, it only
returns the array model.
To listen to array updates, use `Models.useModel(model)` or `useSyncArray()`.
Array views automatically listen to model updates.
*/
export
function
useSyncArray
<
K
,
A
>
(
arr
:
Array
<
K
,
A
>
,
):
A
[]
{
Dome
.
useUpdate
(
PROJECT
);
const
st
=
getSyncArray
(
arr
);
React
.
useEffect
(
st
.
update
);
Server
.
useSignal
(
arr
.
signal
,
st
.
fetch
);
useModel
(
st
.
model
);
return
st
.
model
.
getArray
();
}
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// --- Selection
// --- Selection
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
...
@@ -524,17 +534,17 @@ function reducer(s: Selection, action: SelectionActions): Selection {
...
@@ -524,17 +534,17 @@ function reducer(s: Selection, action: SelectionActions): Selection {
}
}
}
}
const
initi
alSelection
:
Selection
=
{
const
Glob
alSelection
=
new
GlobalStates
.
State
<
Selection
>
(
{
current
:
undefined
,
current
:
undefined
,
prevSelections
:
[],
prevSelections
:
[],
nextSelections
:
[],
nextSelections
:
[],
};
}
)
;
/**
/**
Current selection.
Current selection.
*/
*/
export
function
useSelection
():
[
Selection
,
(
a
:
SelectionActions
)
=>
void
]
{
export
function
useSelection
():
[
Selection
,
(
a
:
SelectionActions
)
=>
void
]
{
const
[
selection
,
setSelection
]
=
React
.
useState
(
initi
alSelection
);
const
[
selection
,
setSelection
]
=
GlobalStates
.
useState
(
Glob
alSelection
);
function
update
(
action
:
SelectionActions
)
{
function
update
(
action
:
SelectionActions
)
{
const
nextSelection
=
reducer
(
selection
,
action
);
const
nextSelection
=
reducer
(
selection
,
action
);
...
...
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