Skip to content
Snippets Groups Projects
Commit cf85d0fe authored by Michele Alberti's avatar Michele Alberti
Browse files

Merge branch 'feature/ivette/fix-array-sync' into 'master'

[dome] fixed synchronized array API

See merge request frama-c/frama-c!2757
parents bfa4eb3d 36159251
No related branches found
No related tags found
No related merge requests found
......@@ -235,15 +235,21 @@ export abstract class Model<Key, Row> {
// --------------------------------------------------------------------------
/**
For a component to re-render on any updates and reloads.
The returned number can be used to memoise effects and callbacks.
Make the component to synchronize with the model and re-render on
every updates.
@param sync - whether to synchronize on model updates or not, `true`
by default.
@return a number that can be used to memoize other effects
*/
export function useModel(model: Model<any, any>): number {
export function useModel(model: Model<any, any>, sync = true): number {
const [age, setAge] = React.useState(0);
React.useEffect(() => {
const w = model.link(() => setImmediate(() => setAge(age + 1)));
return w.unlink;
if (sync) {
const w = model.link(() => setImmediate(() => setAge(age + 1)));
return w.unlink;
}
return undefined;
});
return age;
}
......
......@@ -3,10 +3,9 @@
// --------------------------------------------------------------------------
/**
@packageDocumentation
@module frama-c/states
@decsription
Manage the current Frama-C project and projectified state values.
* Manage the current Frama-C project and projectified state values.
* @packageDocumentation
* @module frama-c/states
*/
import React from 'react';
......@@ -59,7 +58,8 @@ Server.onShutdown(() => {
// --------------------------------------------------------------------------
/**
Current Project (Custom React Hook).
* Current Project (Custom React Hook).
* @return The current project.
*/
export function useProject() {
Dome.useUpdate(PROJECT);
......@@ -67,10 +67,12 @@ export function useProject() {
}
/**
Update Current Project.
Make all states switching to their projectified value.
Emits `PROJECT`.
@param project - the project identifier
* Update Current Project.
*
* Make all states switching to their projectified value.
*
* Emits `PROJECT`.
* @param project The project identifier.
*/
export async function setProject(project: string) {
if (Server.isRunning()) {
......@@ -101,12 +103,12 @@ export interface UseRequestOptions<A> {
}
/**
Cached GET request (Custom React Hook).
Sends the specified GET request and returns its result.
The request is send asynchronously and cached until any change.
Null values in options mean that the last obtained value is kept.
* Cached GET request (Custom React Hook).
*
* Sends the specified GET request and returns its result. The request is send
* asynchronously and cached until any change.
*
* Null values in options mean that the last obtained value is kept.
*/
export function useRequest<In, Out>(
rq: Server.GetRequest<In, Out>,
......@@ -251,7 +253,7 @@ class SyncState<A> {
Dome.emit(this.UPDATE);
} catch (error) {
PP.error(
`Fail to set value of syncState '${this.handler.name}'.`,
`Fail to set value of SyncState '${this.handler.name}'.`,
`${error.toString()}`,
);
}
......@@ -265,7 +267,7 @@ class SyncState<A> {
Dome.emit(this.UPDATE);
} catch (error) {
PP.error(
`Fail to update syncState '${this.handler.name}'.`,
`Fail to update SyncState '${this.handler.name}'.`,
`${error.toString()}`,
);
}
......@@ -294,9 +296,7 @@ Server.onShutdown(() => syncStates.clear());
// --- Synchronized State Hooks
// --------------------------------------------------------------------------
/**
Synchronization with a (projectified) server state.
*/
/** Synchronization with a (projectified) server state. */
export function useSyncState<A>(
st: State<A>,
): [A | undefined, (value: A) => void] {
......@@ -306,9 +306,7 @@ export function useSyncState<A>(
return [s.getValue(), s.setValue];
}
/**
Synchronization with a (projectified) server value.
*/
/** Synchronization with a (projectified) server value. */
export function useSyncValue<A>(va: Value<A>): A | undefined {
const s = getSyncState(va);
Dome.useUpdate(s.update);
......@@ -413,46 +411,30 @@ Server.onShutdown(() => syncArrays.clear());
// --- Synchronized Array Hooks
// --------------------------------------------------------------------------
/**
Force a Synchronized Array to Reload.
*/
/** Force a Synchronized Array to reload. */
export function reloadArray<K, A>(arr: Array<K, A>) {
getSyncArray(arr).reload();
}
/**
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 useSyncModel<K, A>(
arr: Array<K, A>,
): CompactModel<K, A> {
Dome.useUpdate(PROJECT);
const st = getSyncArray(arr);
React.useEffect(st.update);
Server.useSignal(arr.signal, st.fetch);
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.
Unless specified, the hook makes the component re-render on every
update. Disabling this automatic re-rendering can be an option when
using the model to make a table view, which automatically synchronizes on
model updates.
@param sync Whether the component re-renders on updates (default is `true`).
*/
export function useSyncArray<K, A>(
arr: Array<K, A>,
): A[] {
sync = true,
): CompactModel<K, 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();
useModel(st.model, sync);
return st.model;
}
// --------------------------------------------------------------------------
......@@ -489,7 +471,7 @@ export interface HistorySelection {
* - `HISTORY_NEXT` jumps to next history location
* (first in [[nextSelections]]).
*/
type HistorySelectActions = 'HISTORY_PREV' | 'HISTORY_NEXT';
export type HistorySelectActions = 'HISTORY_PREV' | 'HISTORY_NEXT';
/** A selection of multiple locations. */
export interface MultipleSelection {
......@@ -516,7 +498,7 @@ export interface NthSelect {
* - `MULTIPLE_PREV` jumps to previous location of the multiple selections.
* - `MULTIPLE_NEXT` jumps to next location of the multiple selections.
*/
type MultipleSelectActions =
export type MultipleSelectActions =
MultipleSelect | NthSelect
| 'MULTIPLE_PREV' | 'MULTIPLE_NEXT' | 'MULTIPLE_CLEAR';
......@@ -697,9 +679,7 @@ const emptySelection = {
const GlobalSelection = new GlobalStates.State<Selection>(emptySelection);
Server.onShutdown(() => GlobalSelection.setValue(emptySelection));
/**
Current selection.
*/
/** Current selection. */
export function useSelection(): [Selection, (a: SelectionActions) => void] {
const [selection, setSelection] = GlobalStates.useState(GlobalSelection);
......
......@@ -92,7 +92,7 @@ const ASTview = () => {
const [theme, setTheme] = Dome.useGlobalSetting('ASTview.theme', 'default');
const [fontSize, setFontSize] = Dome.useGlobalSetting('ASTview.fontSize', 12);
const [wrapText, setWrapText] = Dome.useSwitch('ASTview.wrapText', false);
const markersInfo = States.useSyncArray(markerInfo);
const markersInfo = States.useSyncArray(markerInfo).getArray();
const theFunction = selection?.current?.function;
const theMarker = selection?.current?.marker;
......
......@@ -16,7 +16,7 @@ export default () => {
// Hooks
const [selection, updateSelection] = States.useSelection();
const fcts = States.useSyncArray(functions).sort(
const fcts = States.useSyncArray(functions).getArray().sort(
(f, g) => alpha(f.name, g.name),
);
......
......@@ -431,7 +431,7 @@ function FilterRatio({ model }: { model: PropertyModel }) {
const RenderTable = () => {
// Hooks
const model = React.useMemo(() => new PropertyModel(), []);
const data = States.useSyncArray(Properties.status);
const data = States.useSyncArray(Properties.status).getArray();
useEffect(() => {
model.removeAllData();
model.updateData(data);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment