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
9a390412
Commit
9a390412
authored
2 years ago
by
Loïc Correnson
Committed by
David Bühler
2 years ago
Browse files
Options
Downloads
Patches
Plain Diff
[states] refactor states with global states
parent
cde633c4
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
ivette/src/dome/renderer/data/states.ts
+3
-1
3 additions, 1 deletion
ivette/src/dome/renderer/data/states.ts
ivette/src/frama-c/states.ts
+66
-98
66 additions, 98 deletions
ivette/src/frama-c/states.ts
with
69 additions
and
99 deletions
ivette/src/dome/renderer/data/states.ts
+
3
−
1
View file @
9a390412
...
@@ -100,6 +100,7 @@ export class GlobalState<A> {
...
@@ -100,6 +100,7 @@ export class GlobalState<A> {
constructor
(
initValue
:
A
)
{
constructor
(
initValue
:
A
)
{
this
.
value
=
initValue
;
this
.
value
=
initValue
;
this
.
emitter
=
new
Emitter
();
this
.
emitter
=
new
Emitter
();
this
.
emitter
.
setMaxListeners
(
200
);
this
.
getValue
=
this
.
getValue
.
bind
(
this
);
this
.
getValue
=
this
.
getValue
.
bind
(
this
);
this
.
setValue
=
this
.
setValue
.
bind
(
this
);
this
.
setValue
=
this
.
setValue
.
bind
(
this
);
}
}
...
@@ -108,7 +109,8 @@ export class GlobalState<A> {
...
@@ -108,7 +109,8 @@ export class GlobalState<A> {
getValue
():
A
{
return
this
.
value
;
}
getValue
():
A
{
return
this
.
value
;
}
/** Notify callbacks on change. By default, changed are detected
/** Notify callbacks on change. By default, changed are detected
by using _deep_ structural comparison, using `react-fast-compare` comparison.
by using _deep_ structural comparison, using `react-fast-compare`
comparison.
@param value the new value of the state
@param value the new value of the state
@param forced when set to `true`, notify callbacks without comparison.
@param forced when set to `true`, notify callbacks without comparison.
*/
*/
...
...
This diff is collapsed.
Click to expand it.
ivette/src/frama-c/states.ts
+
66
−
98
View file @
9a390412
...
@@ -32,20 +32,15 @@
...
@@ -32,20 +32,15 @@
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
{
Order
}
from
'
dome/data/compare
'
;
import
{
Order
}
from
'
dome/data/compare
'
;
import
{
GlobalState
,
useGlobalState
}
from
'
dome/data/states
'
;
import
{
GlobalState
,
useGlobalState
}
from
'
dome/data/states
'
;
import
{
Client
,
useModel
}
from
'
dome/table/models
'
;
import
{
Client
,
useModel
}
from
'
dome/table/models
'
;
import
{
CompactModel
}
from
'
dome/table/arrays
'
;
import
{
CompactModel
}
from
'
dome/table/arrays
'
;
import
{
getCurrent
,
setCurrent
}
from
'
frama-c/kernel/api/project
'
;
import
*
as
Ast
from
'
frama-c/kernel/api/ast
'
;
import
*
as
Ast
from
'
frama-c/kernel/api/ast
'
;
import
*
as
Server
from
'
./server
'
;
import
*
as
Server
from
'
./server
'
;
const
PROJECT
=
new
Dome
.
Event
(
'
frama-c.project
'
);
const
CurrentProject
=
new
GlobalState
<
string
>
(
'
default
'
);
class
STATE
extends
Dome
.
Event
{
constructor
(
id
:
string
)
{
super
(
`frama-c.state.
${
id
}
`
);
}
}
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// --- Pretty Printing (Browser Console)
// --- Pretty Printing (Browser Console)
...
@@ -57,28 +52,18 @@ const D = new Dome.Debug('States');
...
@@ -57,28 +52,18 @@ const D = new Dome.Debug('States');
// --- Synchronized Current Project
// --- Synchronized Current Project
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
let
currentProject
:
string
|
undefined
;
Server
.
onReady
(
async
()
=>
{
Server
.
onReady
(
async
()
=>
{
try
{
try
{
const
sr
:
Server
.
GetRequest
<
null
,
{
id
?:
string
}
>
=
{
CurrentProject
.
setValue
(
'
default
'
);
kind
:
Server
.
RqKind
.
GET
,
const
{
id
}
=
await
Server
.
send
(
getCurrent
,
null
);
name
:
'
kernel.project.getCurrent
'
,
CurrentProject
.
setValue
(
id
);
input
:
Json
.
jNull
,
output
:
Json
.
jObject
({
id
:
Json
.
jString
}),
signals
:
[],
};
const
current
:
{
id
?:
string
}
=
await
Server
.
send
(
sr
,
null
);
currentProject
=
current
.
id
;
PROJECT
.
emit
();
}
catch
(
error
)
{
}
catch
(
error
)
{
D
.
error
(
`Fail to retrieve the current project.
${
error
}
`
);
D
.
error
(
`Fail to retrieve the current project.
${
error
}
`
);
}
}
});
});
Server
.
onShutdown
(()
=>
{
Server
.
onShutdown
(()
=>
{
currentProject
=
''
;
CurrentProject
.
setValue
(
'
default
'
);
PROJECT
.
emit
();
});
});
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
...
@@ -89,9 +74,9 @@ Server.onShutdown(() => {
...
@@ -89,9 +74,9 @@ Server.onShutdown(() => {
* Current Project (Custom React Hook).
* Current Project (Custom React Hook).
* @return The current project.
* @return The current project.
*/
*/
export
function
useProject
():
string
|
undefined
{
export
function
useProject
():
string
{
Dome
.
useUpdate
(
PROJECT
);
const
[
s
]
=
useGlobalState
(
CurrentProject
);
return
currentProject
;
return
s
;
}
}
/**
/**
...
@@ -105,16 +90,9 @@ export function useProject(): string | undefined {
...
@@ -105,16 +90,9 @@ export function useProject(): string | undefined {
export
async
function
setProject
(
project
:
string
):
Promise
<
void
>
{
export
async
function
setProject
(
project
:
string
):
Promise
<
void
>
{
if
(
Server
.
isRunning
())
{
if
(
Server
.
isRunning
())
{
try
{
try
{
const
sr
:
Server
.
SetRequest
<
string
,
null
>
=
{
await
Server
.
send
(
setCurrent
,
project
);
kind
:
Server
.
RqKind
.
SET
,
const
{
id
}
=
await
Server
.
send
(
getCurrent
,
null
);
name
:
'
kernel.project.setCurrent
'
,
CurrentProject
.
setValue
(
id
);
input
:
Json
.
jString
,
output
:
Json
.
jNull
,
signals
:
[],
};
await
Server
.
send
(
sr
,
project
);
currentProject
=
project
;
PROJECT
.
emit
();
}
catch
(
error
)
{
}
catch
(
error
)
{
D
.
error
(
`Fail to set the current project.
${
error
}
`
);
D
.
error
(
`Fail to set the current project.
${
error
}
`
);
}
}
...
@@ -222,7 +200,7 @@ export function useTags(rq: GetTags): Map<string, Tag> {
...
@@ -222,7 +200,7 @@ export function useTags(rq: GetTags): Map<string, Tag> {
}
}
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// --- Synchronized States
// --- Synchronized States
from API
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
export
interface
Value
<
A
>
{
export
interface
Value
<
A
>
{
...
@@ -255,7 +233,7 @@ export interface Array<K, A> {
...
@@ -255,7 +233,7 @@ export interface Array<K, A> {
}
}
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// --- Handler for Synchronized St
by
ates
// --- Handler for Synchronized States
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
interface
Handler
<
A
>
{
interface
Handler
<
A
>
{
...
@@ -265,68 +243,50 @@ interface Handler<A> {
...
@@ -265,68 +243,50 @@ interface Handler<A> {
setter
?:
Server
.
SetRequest
<
A
,
null
>
;
setter
?:
Server
.
SetRequest
<
A
,
null
>
;
}
}
// shared for all projects
enum
SyncStatus
{
OffLine
,
Loading
,
Loaded
}
class
SyncState
<
A
>
{
UPDATE
:
Dome
.
Event
;
class
SyncState
<
A
>
extends
GlobalState
<
A
|
undefined
>
{
handler
:
Handler
<
A
>
;
handler
:
Handler
<
A
>
;
upToDate
:
boolean
;
status
=
SyncStatus
.
OffLine
;
value
?:
A
;
constructor
(
h
:
Handler
<
A
>
)
{
constructor
(
h
:
Handler
<
A
>
)
{
super
(
undefined
);
this
.
handler
=
h
;
this
.
handler
=
h
;
this
.
UPDATE
=
new
STATE
(
h
.
name
);
this
.
load
=
this
.
load
.
bind
(
this
);
this
.
upToDate
=
false
;
this
.
fetch
=
this
.
fetch
.
bind
(
this
);
this
.
value
=
undefined
;
this
.
offline
=
this
.
offline
.
bind
(
this
);
this
.
update
=
this
.
update
.
bind
(
this
);
Server
.
onReady
(
this
.
load
);
this
.
getValue
=
this
.
getValue
.
bind
(
this
);
Server
.
onShutdown
(
this
.
offline
);
this
.
setValue
=
this
.
setValue
.
bind
(
this
);
PROJECT
.
on
(
this
.
update
);
}
}
getValue
():
A
|
undefined
{
signal
():
Server
.
Signal
{
return
this
.
handler
.
signal
;
}
const
running
=
Server
.
isRunning
();
if
(
!
this
.
upToDate
&&
running
)
{
load
():
void
{
this
.
update
();
if
(
this
.
status
===
SyncStatus
.
OffLine
)
this
.
fetch
();
}
return
running
?
this
.
value
:
undefined
;
}
}
async
setValue
(
v
:
A
):
Promise
<
void
>
{
offline
():
void
{
try
{
this
.
status
=
SyncStatus
.
OffLine
;
this
.
upToDate
=
true
;
this
.
setValue
(
undefined
);
this
.
value
=
v
;
const
setter
=
this
.
handler
.
getter
;
if
(
setter
)
await
Server
.
send
(
setter
,
v
);
this
.
UPDATE
.
emit
();
}
catch
(
error
)
{
D
.
error
(
`Fail to set value of SyncState '
${
this
.
handler
.
name
}
'.`
,
`
${
error
}
`
,
);
this
.
UPDATE
.
emit
();
}
}
}
async
update
():
Promise
<
void
>
{
async
fetch
():
Promise
<
void
>
{
try
{
try
{
this
.
upToDate
=
true
;
if
(
Server
.
isRunning
())
{
if
(
Server
.
isRunning
())
{
this
.
status
=
SyncStatus
.
Loading
;
const
v
=
await
Server
.
send
(
this
.
handler
.
getter
,
null
);
const
v
=
await
Server
.
send
(
this
.
handler
.
getter
,
null
);
this
.
value
=
v
;
this
.
status
=
SyncStatus
.
Loaded
;
this
.
UPDATE
.
emit
();
this
.
setValue
(
v
);
}
else
if
(
this
.
value
!==
undefined
)
{
this
.
value
=
undefined
;
this
.
UPDATE
.
emit
();
}
}
}
catch
(
error
)
{
}
catch
(
error
)
{
D
.
error
(
D
.
error
(
`Fail to update SyncState '
${
this
.
handler
.
name
}
'.`
,
`Fail to update SyncState '
${
this
.
handler
.
name
}
'.`
,
`
${
error
}
`
,
`
${
error
}
`
,
);
);
this
.
value
=
undefined
;
this
.
setValue
(
undefined
);
this
.
UPDATE
.
emit
();
}
}
}
}
}
}
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
...
@@ -337,7 +297,10 @@ const syncStates = new Map<string, SyncState<unknown>>();
...
@@ -337,7 +297,10 @@ const syncStates = new Map<string, SyncState<unknown>>();
// Remark: use current project state
// Remark: use current project state
function
currentSyncState
<
A
>
(
h
:
Handler
<
A
>
):
SyncState
<
A
>
{
function
lookupSyncState
<
A
>
(
currentProject
:
string
,
h
:
Handler
<
A
>
):
SyncState
<
A
>
{
const
id
=
`
${
currentProject
}
@
${
h
.
name
}
`
;
const
id
=
`
${
currentProject
}
@
${
h
.
name
}
`
;
let
s
=
syncStates
.
get
(
id
)
as
SyncState
<
A
>
|
undefined
;
let
s
=
syncStates
.
get
(
id
)
as
SyncState
<
A
>
|
undefined
;
if
(
!
s
)
{
if
(
!
s
)
{
...
@@ -355,20 +318,25 @@ Server.onShutdown(() => syncStates.clear());
...
@@ -355,20 +318,25 @@ Server.onShutdown(() => syncStates.clear());
/** Synchronization with a (projectified) server state. */
/** Synchronization with a (projectified) server state. */
export
function
useSyncState
<
A
>
(
export
function
useSyncState
<
A
>
(
st
:
State
<
A
>
,
st
ate
:
State
<
A
>
,
):
[
A
|
undefined
,
(
value
:
A
)
=>
void
]
{
):
[
A
|
undefined
,
(
value
:
A
)
=>
void
]
{
const
s
=
currentSyncState
(
st
);
Server
.
useStatus
();
Dome
.
useUpdate
(
PROJECT
,
s
.
UPDATE
);
const
pr
=
useProject
();
Server
.
useSignal
(
s
.
handler
.
signal
,
s
.
update
);
const
st
=
lookupSyncState
(
pr
,
state
);
return
[
s
.
getValue
(),
s
.
setValue
];
Server
.
useSignal
(
st
.
signal
(),
st
.
fetch
);
st
.
load
();
return
useGlobalState
(
st
);
}
}
/** Synchronization with a (projectified) server value. */
/** Synchronization with a (projectified) server value. */
export
function
useSyncValue
<
A
>
(
va
:
Value
<
A
>
):
A
|
undefined
{
export
function
useSyncValue
<
A
>
(
value
:
Value
<
A
>
):
A
|
undefined
{
const
s
=
currentSyncState
(
va
);
Server
.
useStatus
();
Dome
.
useUpdate
(
PROJECT
,
s
.
UPDATE
);
const
pr
=
useProject
();
Server
.
useSignal
(
s
.
handler
.
signal
,
s
.
update
);
const
st
=
lookupSyncState
(
pr
,
value
);
return
s
.
getValue
();
Server
.
useSignal
(
st
.
signal
(),
st
.
fetch
);
st
.
load
();
const
[
v
]
=
useGlobalState
(
st
);
return
v
;
}
}
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
...
@@ -395,7 +363,6 @@ class SyncArray<K, A> {
...
@@ -395,7 +363,6 @@ class SyncArray<K, A> {
update
():
void
{
update
():
void
{
if
(
if
(
!
this
.
upToDate
&&
!
this
.
upToDate
&&
currentProject
!==
undefined
&&
Server
.
isRunning
()
Server
.
isRunning
()
)
this
.
fetch
();
)
this
.
fetch
();
}
}
...
@@ -403,7 +370,6 @@ class SyncArray<K, A> {
...
@@ -403,7 +370,6 @@ class SyncArray<K, A> {
async
fetch
():
Promise
<
void
>
{
async
fetch
():
Promise
<
void
>
{
if
(
if
(
this
.
fetching
||
this
.
fetching
||
currentProject
===
undefined
||
!
Server
.
isRunning
()
!
Server
.
isRunning
()
)
return
;
)
return
;
try
{
try
{
...
@@ -460,6 +426,7 @@ const syncArrays = new Map<string, SyncArray<unknown, unknown>>();
...
@@ -460,6 +426,7 @@ const syncArrays = new Map<string, SyncArray<unknown, unknown>>();
// Remark: lookup for current project
// Remark: lookup for current project
function
currentSyncArray
<
K
,
A
>
(
function
currentSyncArray
<
K
,
A
>
(
currentProject
:
string
,
array
:
Array
<
K
,
A
>
,
array
:
Array
<
K
,
A
>
,
):
SyncArray
<
K
,
A
>
{
):
SyncArray
<
K
,
A
>
{
const
id
=
`
${
currentProject
}
@
${
array
.
name
}
`
;
const
id
=
`
${
currentProject
}
@
${
array
.
name
}
`
;
...
@@ -479,7 +446,7 @@ Server.onShutdown(() => syncArrays.clear());
...
@@ -479,7 +446,7 @@ Server.onShutdown(() => syncArrays.clear());
/** Force a Synchronized Array to reload. */
/** Force a Synchronized Array to reload. */
export
function
reloadArray
<
K
,
A
>
(
arr
:
Array
<
K
,
A
>
):
void
{
export
function
reloadArray
<
K
,
A
>
(
arr
:
Array
<
K
,
A
>
):
void
{
currentSyncArray
(
arr
).
reload
();
currentSyncArray
(
CurrentProject
.
getValue
(),
arr
).
reload
();
}
}
/**
/**
...
@@ -495,8 +462,9 @@ export function useSyncArray<K, A>(
...
@@ -495,8 +462,9 @@ export function useSyncArray<K, A>(
arr
:
Array
<
K
,
A
>
,
arr
:
Array
<
K
,
A
>
,
sync
=
true
,
sync
=
true
,
):
CompactModel
<
K
,
A
>
{
):
CompactModel
<
K
,
A
>
{
Dome
.
useUpdate
(
PROJECT
);
Server
.
useStatus
();
const
st
=
currentSyncArray
(
arr
);
const
pr
=
useProject
();
const
st
=
currentSyncArray
(
pr
,
arr
);
Server
.
useSignal
(
arr
.
signal
,
st
.
fetch
);
Server
.
useSignal
(
arr
.
signal
,
st
.
fetch
);
st
.
update
();
st
.
update
();
useModel
(
st
.
model
,
sync
);
useModel
(
st
.
model
,
sync
);
...
@@ -509,7 +477,8 @@ export function useSyncArray<K, A>(
...
@@ -509,7 +477,8 @@ export function useSyncArray<K, A>(
export
function
getSyncArray
<
K
,
A
>
(
export
function
getSyncArray
<
K
,
A
>
(
arr
:
Array
<
K
,
A
>
,
arr
:
Array
<
K
,
A
>
,
):
CompactModel
<
K
,
A
>
{
):
CompactModel
<
K
,
A
>
{
const
st
=
currentSyncArray
(
arr
);
const
pr
=
CurrentProject
.
getValue
();
const
st
=
currentSyncArray
(
pr
,
arr
);
return
st
.
model
;
return
st
.
model
;
}
}
...
@@ -523,7 +492,8 @@ export function onSyncArray<K, A>(
...
@@ -523,7 +492,8 @@ export function onSyncArray<K, A>(
onReload
?:
()
=>
void
,
onReload
?:
()
=>
void
,
onUpdate
?:
()
=>
void
,
onUpdate
?:
()
=>
void
,
):
Client
{
):
Client
{
const
st
=
currentSyncArray
(
arr
);
const
pr
=
CurrentProject
.
getValue
();
const
st
=
currentSyncArray
(
pr
,
arr
);
return
st
.
model
.
link
(
onReload
,
onUpdate
);
return
st
.
model
.
link
(
onReload
,
onUpdate
);
}
}
...
@@ -822,9 +792,7 @@ export async function resetSelection(): Promise<void> {
...
@@ -822,9 +792,7 @@ export async function resetSelection(): Promise<void> {
}
}
}
}
/* Select the main function when the current project changes and the selection
Server
.
onReady
(()
=>
{
is still empty (which happens at the start of the GUI). */
PROJECT
.
on
(
async
()
=>
{
if
(
GlobalSelection
.
getValue
()
===
emptySelection
)
if
(
GlobalSelection
.
getValue
()
===
emptySelection
)
resetSelection
();
resetSelection
();
});
});
...
...
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