...
 
Commits (754)
**/Clean System Files
*-data
*-www
*.abc
*.bc
*.o
*.tcl
*.prj
*.prp
*.exe
*.bc
*.pbc
*.exe
*-data
*-www
.sass-cache
BasicAPIExamples.icl
.ctest-results.json
*-junit.xml
*.bak
BasicAPIExamples.icl
Examples/BasicAPIExamples/EditorsOnBasicAndPredefinedTypes/EnterDateAndTime
Examples/BasicAPIExamples/EditorsOnBasicAndPredefinedTypes/EnterInteger
Examples/BasicAPIExamples/EditorsOnBasicAndPredefinedTypes/EnterListOfInt
Examples/BasicAPIExamples/EditorsOnBasicAndPredefinedTypes/EnterText
Examples/BasicAPIExamples/EditorsOnBasicAndPredefinedTypes/HelloWorld
Examples/BasicAPIExamples/EditorsOnBasicAndPredefinedTypes/Leaflet
Examples/BasicAPIExamples/EditorsOnCustomTypes/EnterFamilyTree
Examples/BasicAPIExamples/EditorsOnCustomTypes/EnterPerson
Examples/BasicAPIExamples/InteractionUsingShares/BrowseAndViewLeafletMap
Examples/BasicAPIExamples/InteractionUsingShares/CurrentDateAndTime
Examples/BasicAPIExamples/InteractionUsingShares/SharedNoteAsList
Examples/BasicAPIExamples/InteractionUsingShares/SharedNotes
Examples/BasicAPIExamples/InteractionUsingShares/UpdateSharedPersonsAndView
Examples/BasicAPIExamples/InteractionWithTheSystem/RunProcess
Examples/BasicAPIExamples/MultiUserExamples/Chat
Examples/BasicAPIExamples/MultiUserExamples/MeetingDate
Examples/BasicAPIExamples/MultiUserExamples/OptionsChat
Examples/BasicAPIExamples/SequentialExamples/CalculateSumInShare
Examples/BasicAPIExamples/SequentialExamples/CalculateSumStepwise
Examples/BasicAPIExamples/SequentialExamples/CalculateSumStepwiseAndBack
Examples/BasicAPIExamples/SequentialExamples/Calculator
Examples/BasicAPIExamples/SequentialExamples/CoffeeMachine
Examples/BasicAPIExamples/SequentialExamples/EditPerson1by1
Examples/BasicAPIExamples/SequentialExamples/Palindrome
Examples/DynamicEditor/TypedTaskEditor
Examples/GIS/LeafletMapExample
Examples/WasmTest
Tests/Interactive/GenericEditors/TestADTMultiCons
Tests/Interactive/GenericEditors/TestADTSingleConsMany
Tests/Interactive/GenericEditors/TestADTSingleConsMulti
Tests/Interactive/GenericEditors/TestADTSingleConsOne
Tests/Interactive/GenericEditors/TestBool
Tests/Interactive/GenericEditors/TestChar
Tests/Interactive/GenericEditors/TestCustomList
Tests/Interactive/GenericEditors/TestInt
Tests/Interactive/GenericEditors/TestIntList
Tests/Interactive/GenericEditors/TestNestedRecord
Tests/Interactive/GenericEditors/TestOptionalRecord
Tests/Interactive/GenericEditors/TestReal
Tests/Interactive/GenericEditors/TestRecordWithADT
Tests/Interactive/GenericEditors/TestSingleRecord
Tests/Interactive/GenericEditors/TestString
Tests/TestAsyncTask
Tests/Unit/iTasks.Extensions.Process.UnitTests
Tests/Unit/iTasks.Internal.IWorld.UnitTests
Tests/Unit/iTasks.Internal.TaskStore.UnitTests
Tests/Unit/iTasks.UI.Editor.Generic.UnitTests
Tests/Unit/iTasks.UI.Layout.UnitTests
Tests/Unit/iTasks.WF.Combinators.Common.UnitTests
Tests/Unit/iTasks.WF.Combinators.Core.UnitTests
Tests/Unit/iTasks.WF.Tasks.Core.UnitTests
Tests/Unit/iTasks.WF.Tasks.IO.UnitTests
Tools/CodeQualityMonitor
Tools/WebResourceCollector
test:
linux-x64:
image: "camilstaps/clean:nightly"
before_script:
- install_clean.sh bundle-complete
- apt-get update -qq
- apt-get install -y -qq build-essential libsqlite3-dev libmariadbclient-dev-compat
script:
- bash ci-tests.bash
- bash Tests/posix.sh
artifacts:
when: always
paths:
- Tests/Unit/*-junit.xml
reports:
junit: Tests/Unit/*-junit.xml
linux-x86:
only:
- master
image: "camilstaps/clean:nightly"
before_script:
- CLEAN_PLATFORM=x86 install_clean.sh bundle-complete
- apt-get update -qq
- apt-get install -y -qq build-essential libsqlite3-dev:i386 libmariadbclient-dev-compat:i386
- sed -i 's/x64/x86/g' Tests/posix.sh
script:
- bash Tests/posix.sh
artifacts:
when: always
paths:
- Tests/Unit/*-junit.xml
reports:
junit: Tests/Unit/*-junit.xml
windows-x64:
only:
- master
tags:
- windows
- x64
before_script:
- wget -UseBasicParsing -o clean.zip https://ftp.cs.ru.nl/Clean/builds/windows-x64/clean-bundle-complete-windows-x64-latest.zip
- 7z x clean.zip
- sed -n -i '/EnvironmentName:\tiTasks/q;p' clean-bundle-complete\Config\IDEEnvs
- $EscapedPwd = $Pwd -replace '\\', '\\\\'
- tail -n +3 Config\windows-x64\iTasks.env | sed "s/\{Application\}.*iTasks/$EscapedPwd\\\\Libraries/" | Out-File -encoding ASCII -Append clean-bundle-complete\Config\IDEEnvs
- $Env:CLEAN_HOME = "$Pwd\\clean-bundle-complete"
- $Env:Path += ";${Env:CLEAN_HOME}"
script:
- bash Tests/windows.sh
artifacts:
when: always
paths:
- Tests/Unit/*-junit.xml
reports:
junit: Tests/Unit/*-junit.xml
Version: 1.5
Global
ProjectRoot: .
Target: iTasks
CodeGen
CheckStacks: False
CheckIndexes: True
OptimiseABC: True
GenerateByteCode: True
Application
HeapSize: 167772160
StackSize: 1048576
ExtraMemory: 81920
IntialHeapSize: 204800
HeapSizeMultiplier: 4096
ShowExecutionTime: False
ShowGC: False
ShowStackSize: False
MarkingCollector: False
DisableRTSFlags: False
StandardRuntimeEnv: True
Profile
Memory: False
MemoryMinimumHeapSize: 0
Time: False
Stack: False
Dynamics: True
GenericFusion: False
DescExL: True
Output
Output: ShowConstructors
Font: Courier
FontSize: 9
WriteStdErr: False
Link
LinkMethod: Static
GenerateRelocations: False
GenerateSymbolTable: True
GenerateLinkMap: False
LinkResources: False
ResourceSource:
GenerateDLL: False
ExportedNames:
StripByteCode: True
KeepByteCodeSymbols: True
PrelinkByteCode: True
Precompile:
Postlink:
Version: 1.0
Environment
EnvironmentName: iTasks-dist
EnvironmentPaths
Path: {Application}/lib/StdEnv
Path: {Application}/lib/Dynamics
Path: {Application}/lib/TCPIP
Path: {Application}/lib/ABCInterpreter
Path: {Application}/lib/GraphCopy
Path: {Application}/lib/Platform
Path: {Application}/lib/Platform/Deprecated/Generics
Path: {Application}/lib/Platform/Deprecated/StdLib
Path: {Application}/Development/iTasks-SDK/Libraries
EnvironmentCompiler: lib/exe/cocl::-dynamics -d
EnvironmentCodeGen: lib/exe/cg
EnvironmentLinker: /usr/bin/gcc::-g|lib/exe/itasks-web-collector
EnvironmentDynLink: lib/exe/cclinker
EnvironmentABCOptimise: lib/exe/abcopt
EnvironmentByteCodeGen: lib/exe/bcgen
EnvironmentByteCodeLink: lib/exe/bclink
EnvironmentByteCodeStrip: lib/exe/bcstrip
EnvironmentByteCodePrelink: lib/exe/bcprelink
EnvironmentVersion: 920
EnvironmentRedirect: False
EnvironmentCompileMethod: Pers
EnvironmentProcessor: I386
Environment64BitProcessor: True
......@@ -12,10 +12,9 @@ Environments
Path: {Application}/lib/ABCInterpreter
Path: {Application}/lib/GraphCopy
Path: {Application}/Development/iTasks-SDK/Libraries
EnvironmentCompiler: lib/exe/cocl:-dynamics
EnvironmentCompiler: lib/exe/cocl-itasks:-dynamics
EnvironmentCodeGen: lib/exe/cg
EnvironmentLinker: lib/exe/linker|lib/exe/itasks-web-collector
EnvironmentDynLink: lib/exe/linker
EnvironmentLinker: /usr/bin/gcc::-Wl,--gc-sections|lib/exe/itasks-web-collector
EnvironmentABCOptimise: lib/exe/abcopt
EnvironmentByteCodeGen: lib/exe/bcgen
EnvironmentByteCodeLink: lib/exe/bclink
......
Version: 1.0
Environments
Environment
EnvironmentName: iTasks Tonic
EnvironmentPaths
Path: {Application}/lib/StdEnv
Path: {Application}/lib/Dynamics
Path: {Application}/lib/TCPIP
Path: {Application}/lib/Platform
Path: {Application}/lib/Platform/Deprecated/Generics
Path: {Application}/lib/Platform/Deprecated/StdLib
Path: {Application}/lib/ABCInterpreter
Path: {Application}/lib/GraphCopy
Path: {Application}/lib/iTasks
EnvironmentCompiler: lib/exe/cocl-tonic:-dynamics -tonic
EnvironmentCodeGen: lib/exe/cg
EnvironmentLinker: lib/exe/linker|lib/exe/itasks-web-collector
EnvironmentDynLink: lib/exe/linker
EnvironmentABCOptimise: lib/exe/abcopt
EnvironmentByteCodeGen: lib/exe/bcgen
EnvironmentByteCodeLink: lib/exe/bclink
EnvironmentByteCodeStrip: lib/exe/bcstrip
EnvironmentByteCodePrelink: lib/exe/bcprelink
EnvironmentVersion: 920
EnvironmentRedirect: False
EnvironmentCompileMethod: Pers
EnvironmentProcessor: I386
Environment64BitProcessor: True
......@@ -12,10 +12,10 @@ Environments
Path: {Application}/lib/ABCInterpreter
Path: {Application}/lib/GraphCopy
Path: {Application}/lib/iTasks
EnvironmentCompiler: lib/exe/cocl::-dynamics
Path: {Application}/lib/Gast
EnvironmentCompiler: lib/exe/cocl-itasks::-dynamics
EnvironmentCodeGen: lib/exe/cg
EnvironmentLinker: lib/exe/linker|lib/exe/itasks-web-collector
EnvironmentDynLink: lib/exe/linker
EnvironmentLinker: /usr/bin/gcc::-Wl,--gc-sections|:linker:lib/exe/itasks-web-collector
EnvironmentABCOptimise: lib/exe/abcopt
EnvironmentByteCodeGen: lib/exe/bcgen
EnvironmentByteCodeLink: lib/exe/bclink
......
Version: 1.0
Environments
Environment
EnvironmentName: iTasks
EnvironmentPaths
......@@ -11,10 +12,9 @@ Version: 1.0
Path: {Application}/lib/ABCInterpreter
Path: {Application}/lib/GraphCopy
Path: {Application}/lib/iTasks
EnvironmentCompiler: lib/exe/cocl:-dynamics -desc -exl -d
EnvironmentCompiler: lib/exe/cocl-itasks::-dynamics
EnvironmentCodeGen: lib/exe/cg
EnvironmentLinker: lib/exe/cclinker|lib/exe/itasks-web-collector
EnvironmentDynLink: lib/exe/cclinker
EnvironmentLinker: /usr/bin/gcc::-Wl,--gc-sections -m32|:linker:lib/exe/itasks-web-collector
EnvironmentABCOptimise: lib/exe/abcopt
EnvironmentByteCodeGen: lib/exe/bcgen
EnvironmentByteCodeLink: lib/exe/bclink
......@@ -24,4 +24,4 @@ Version: 1.0
EnvironmentRedirect: False
EnvironmentCompileMethod: Pers
EnvironmentProcessor: I386
Environment64BitProcessor: True
Environment64BitProcessor: False
......@@ -12,10 +12,9 @@ Environments
Path: {Application}/lib/ABCInterpreter
Path: {Application}/lib/GraphCopy
Path: {Application}/Development/iTasks-SDK/Libraries
EnvironmentCompiler: lib/exe/cocl::-dynamics
EnvironmentCompiler: lib/exe/cocl-itasks::-dynamics
EnvironmentCodeGen: lib/exe/cg
EnvironmentLinker: /usr/bin/gcc|lib/exe/itasks-web-collector
EnvironmentDynLink: /usr/bin/gcc
EnvironmentABCOptimise: lib/exe/abcopt
EnvironmentByteCodeGen: lib/exe/bcgen
EnvironmentByteCodeLink: lib/exe/bclink
......
Version: 1.0
Environments
Environment
EnvironmentName: iTasks Tonic
EnvironmentPaths
Path: {Application}/lib/StdEnv
Path: {Application}/lib/Dynamics
Path: {Application}/lib/TCPIP
Path: {Application}/lib/Platform
Path: {Application}/lib/Platform/Deprecated/Generics
Path: {Application}/lib/Platform/Deprecated/StdLib
Path: {Application}/lib/ABCInterpreter
Path: {Application}/lib/GraphCopy
Path: {Application}/lib/iTasks
EnvironmentCompiler: lib/exe/cocl-tonic::-dynamics -tonic
EnvironmentCodeGen: lib/exe/cg
EnvironmentLinker: /usr/bin/gcc|lib/exe/itasks-web-collector
EnvironmentDynLink: /usr/bin/gcc
EnvironmentABCOptimise: lib/exe/abcopt
EnvironmentByteCodeGen: lib/exe/bcgen
EnvironmentByteCodeLink: lib/exe/bclink
EnvironmentByteCodeStrip: lib/exe/bcstrip
EnvironmentByteCodePrelink: lib/exe/bcprelink
EnvironmentVersion: 920
EnvironmentRedirect: False
EnvironmentCompileMethod: Pers
EnvironmentProcessor: I386
Environment64BitProcessor: True
......@@ -12,10 +12,9 @@ Environments
Path: {Application}/lib/ABCInterpreter
Path: {Application}/lib/GraphCopy
Path: {Application}/lib/iTasks
EnvironmentCompiler: lib/exe/cocl::-dynamics
EnvironmentCompiler: lib/exe/cocl-itasks:-h 400M:-dynamics
EnvironmentCodeGen: lib/exe/cg
EnvironmentLinker: /usr/bin/gcc|lib/exe/itasks-web-collector
EnvironmentDynLink: /usr/bin/gcc
EnvironmentLinker: :gcc:/usr/bin/gcc|:linker:lib/exe/itasks-web-collector
EnvironmentABCOptimise: lib/exe/abcopt
EnvironmentByteCodeGen: lib/exe/bcgen
EnvironmentByteCodeLink: lib/exe/bclink
......
......@@ -16,7 +16,7 @@ Environments
Path: {Application}\Libraries\ABCInterpreter
Path: {Application}\Libraries\GraphCopy
Path: {Application}\Libraries\iTasks
EnvironmentCompiler: Tools\Clean System 64\CleanCompiler64.exe : -h 128M : -dynamics
EnvironmentCompiler: Tools\Clean System 64\CleanCompilerITasks64.exe : -h 256M : -dynamics
EnvironmentCodeGen: Tools\Clean System 64\CodeGenerator64.exe
EnvironmentLinker: Tools\Clean System 64\StaticLinker.exe : -h 64M | Tools\Clean System\WebResourceCollector.exe
EnvironmentDynLink: Tools\Clean System 64\DynamicLinker.exe
......
# Building an iTask project #
iTask programs are just regular Clean programs that happen to use the iTask framework. Compiling an iTask program does require some specific project configuration settings though. Luckily you can easily get started by using a project template.
In this guide we'll walk you through the steps to build your first iTask project. We assume you have already installed Clean and the iTask framework.
## Building on Windows ##
On windows, you can use the Clean IDE to build your iTask programs.
### Step 1: Creating a main module ###
Open the Clean IDE and use `File -> New File` from the main menu to create a new file called `myprogram.icl`.
Write the following code in the new file (the yellow window).
```Clean
module myprogram
import iTasks
Start world = doTasks (Title "Hello" @>> viewInformation [] "Hello, world") world
```
Save the file using `File -> Save myprogram.icl` from the main menu.
### Step 2: Creating a project file ###
You now need to create a project file. A project file contains all search paths and compilation settings for building a Clean program.
The iTask framework provides a template with default settings for an iTask project. You can create your own project file using this template by choosing `File -> New Project Using Template...` from the main menu.
You are then asked to select a project template (.prt) file. You can find the `iTasks.prt` template file in the `Config` subdirectory of your Clean system.
After selecting the template file you are asked to choose a name for the project file. By default it will be `myprogram.prj` (for the module `myprogram.icl`) which you don't have to change.
### Step 3: Building and running your project ###
You can build and run your program by choosing `Project -> Update and Run` from the main menu. After compilation is completed you should see a console window displaying an URL that you can open in your web browser.
## Building on Linux or Mac ##
On Linux and macOS you can use a command line tool called `cpm` to create and build Clean projects.
### Step 1: Creating a main module ###
First create a Clean source module with a minimal program. Write the following code to a file called `myprogram.icl`.
```Clean
module myprogram
import iTasks
Start world = doTasks (Title "Hello" @>> viewInformation [] "Hello, world") world
```
### Step 2: Creating a project file ###
Using the `cpm` tool we can create a new project file. A project file contains all search paths and compilation settings for building a Clean program.
The iTask framework provides a template with default settings for an iTask project. You can create your own project file using this template with the following command:
```
cpm project myprogram create $CLEAN_HOME/etc/iTasks.prt
```
This will create a file called `myprogram.prj` which is the project file for your program.
### Step3: Building your project ###
To build your program, you can again use `cpm`:
```
cpm myprogram.prj
```
This will create a number of output files in your current directory. The most important one is `myprogram`, the executable program. There will also be additional resources that are needed at runtime: A bytecode version of your program: `myprogram.bc`, a version of that bytecode for the browser: `myprogram.pbc` and a directory with all the public web assets your program needs: `myprogram-www`.
### Step 4: Running your program ###
Simply run the `myprogram` executable and use a web browser to open the URL that is displayed.
```
./myprogram
```
# Parallelization #
## Introduction ##
This guide provides insights on how to write iTasks programs that execute on multiple processor cores/processors/machines.
## Parallel primitives ##
### Distributed engine ###
The distributed engine can be enabled using:
- `EngineOptions.distributed :: Maybe Int` (`--distributed PORT`)
This option either disables the distributed engine (`Nothing`) or enables it and offers distributed communication via the given port number.
- `EngineOptions.distributedChild :: Bool`
This option starts the process in child mode.
In child mode, the engine does not start any tasks except for the tasks required to function as a distributed iTasks node.
The command line option `--distributedChild PORT` enables child mode and enables distributed communication via the given port number.
### Shared Data Sources ###
SDSs of different processes can be accessed using the `remoteShare` primitive:
```Clean
:: SDSShareOptions =
{ domain :: !String
, port :: !Int
}
remoteShare :: (sds p r w) SDSShareOptions -> SDSRemoteSource p r w | RWShared sds
```
### Tasks ###
Executing tasks on a different machine can be done using the `asyncTask` primitive:
```Clean
asyncTask :: !String !Int !(Task a) -> Task a | iTask a
```
There are no limitations to what you can execute on a different machine.
Do keep in mind that if you want to access SDSs from the parent, they need to be remote again.
The UI of the task is presented on the parent server.
Also, if you want to do a blocking calculation, make sure it is evaluated on the client and not already on the server.
To make sure this happen you can wrap the task:
```Clean
task = asyncTask
"localhost"
8000
(return () >>- \_->return (somethingBlocking 42))
```
## Troubleshooting ##
When encountering problems ask yourself the following questions first:
- Are the correct project file options set? (`Link.GenerateSymbolTable` and `Application.Profile.DescExL`)
- Are the binaries of the server and the client compiled from the exact same source?
# Performance tips
## General
- When trying to improve performance, use one of the profilers to check that
your change actually improves things.
- Use strict records instead of tuples, especially for `Map` keys and `Set`
elements, to avoid laziness and especially the `<` instance for tuples.
- Avoid chains of `MaybeError` and `Maybe` (e.g.
`MaybeError String (Maybe ...)`); define a local three-way type instead. This
allows the next optimization:
- Think about which guards/patterns are the most common cases and put those
first. For ADTs with two constructors, it does not matter which is matched
first: in either case, one descriptor equality check will be done (if
unequal, it is assumed that the value is of the other constructor).
- Avoid unnecessary pointfree notation (e.g., do not write `const ((===) key)`
but write `\_ k -> k == key`.
- Use boxed records (`:: T = ! { ... }`) where appropriate. Normally, records
are unboxed when they are a strict argument of a function, meaning that each
field gets a space on the stack. With large records of which most fields are
not used by the function, this should be avoided. `IWorld` is an example of a
type that should be boxed.
## Shares
- When defining a share it is good sense to use a CAF (define with `=:`) so
that it is only evaluated once. Otherwise its identity gets recomputed, which
can be heavy for complicated SDS trees.
......@@ -193,7 +193,7 @@ configurableListItem :: String ItemMeta (Task c) (c -> ActionPlan)
* @param Group by incidents
* @param Use 'my actions' group for current user
*/
chooseActionItem :: d Bool Bool (sds () [(InstanceNo,InstanceNo,ActionStatus)] ()) -> Task InstanceNo | toPrompt d & RWShared sds
chooseActionItem :: Bool Bool (sds () [(InstanceNo,InstanceNo,ActionStatus)] ()) -> Task InstanceNo | RWShared sds
workOnActionItem :: InstanceNo -> Task ()
editActionItem :: InstanceNo -> Task (Maybe ActionStatus)
deleteActionItem :: InstanceNo -> Task (Maybe ActionStatus)
......
......@@ -94,7 +94,7 @@ where
eqBounds _ _ = False
gDefault{|ContactMapPerspective|}
= {ContactMapPerspective|center = (52.948300, 4.776007), zoom = 7, cursor = Nothing, bounds = Nothing} //(Full coast centered on Den Helder)
= {ContactMapPerspective|center = (52.948300, 4.776007), zoom = 7, bounds = Nothing, cursor = Nothing} //(Full coast centered on Den Helder)
contactToMapMarker :: Bool Bool Contact -> ContactMapMarker
......@@ -139,11 +139,11 @@ toLeafletMap {ContactMap|perspective,layers}
,objects = []
}
where
tilesUrls layers = [url \\ {ContactMapLayer|def=CMTileLayer url} <- layers]
tilesUrls layers = [{url = url, attribution = Nothing} \\ {ContactMapLayer|def=CMTileLayer url} <- layers]
convMarkers markers = [conv m \\ m=:{ContactMapMarker|position} <- markers | hasLatLng position]
conv {ContactMapMarker|markerId,title,position,heading,type,selected}
= Marker {LeafletMarker|markerId = markerId, title = title, position = pos position, icon = Nothing /* fmap (\t -> iconIndex heading t selected) type */, selected = selected, popup = Nothing}
conv {ContactMapMarker|markerId,title,position,heading,type}
= Marker {LeafletMarker|markerId = markerId, title = title, position = pos position, icon = Nothing /* fmap (\t -> iconIndex heading t selected) type */, popup = Nothing}
pos (PositionLatLng (lat,lng)) = {LeafletLatLng|lat=lat,lng=lng}
pos (PositionDescription _ (Just(lat,lng))) = {LeafletLatLng|lat=lat,lng=lng}
......@@ -183,7 +183,7 @@ where
toLeafletPerspective :: ContactMapPerspective -> LeafletPerspective
toLeafletPerspective {ContactMapPerspective|center,zoom,cursor,bounds}
= {LeafletPerspective|center=toLeafletLatLng center,zoom=zoom,cursor=fmap toLeafletLatLng cursor,bounds=fmap toLeafletBounds bounds}
= {LeafletPerspective|center=toLeafletLatLng center,zoom=zoom,bounds=fmap toLeafletBounds bounds}
toLeafletLatLng :: !(!Real,!Real) -> LeafletLatLng
toLeafletLatLng (lat,lng) = {LeafletLatLng|lat=lat,lng=lng}
......@@ -199,8 +199,8 @@ fromLeafletMap contactMap leafletMap
}
fromLeafletPerspective :: LeafletPerspective -> ContactMapPerspective
fromLeafletPerspective {LeafletPerspective|center,cursor,zoom,bounds}
= {ContactMapPerspective|center=fromLeafletLatLng center,zoom=zoom,cursor=fmap fromLeafletLatLng cursor,bounds=fmap fromLeafletBounds bounds}
fromLeafletPerspective {LeafletPerspective|center,zoom,bounds}
= {ContactMapPerspective|center=fromLeafletLatLng center,zoom=zoom,cursor=Nothing,bounds=fmap fromLeafletBounds bounds}
/*
fromLeafletLayer :: ContactMapLayer LeafletLayer -> ContactMapLayer
......@@ -216,8 +216,8 @@ fromLeafletLayer cl ll = cl
*/
selectionFromLeafletMap :: LeafletMap -> [LeafletObjectID]
selectionFromLeafletMap {LeafletMap|objects} =
[markerId \\ Marker {LeafletMarker|markerId,selected} <- objects | selected]
selectionFromLeafletMap {LeafletMap|objects} = []
//[markerId \\ Marker {LeafletMarker|markerId} <- objects | selected]
fromLeafletLatLng :: !LeafletLatLng -> (!Real,!Real)
fromLeafletLatLng {LeafletLatLng|lat,lng} = (lat,lng)
......
......@@ -11,13 +11,13 @@ selectVideoWallContent
@! ()
where
header
= viewInformation () [] ("REMOTE CONTROL") //<<@ (AfterLayout (uiDefSetHalign AlignRight o uiDefSetBaseCls "wall-header")) //FIXME
= viewInformation [] ("REMOTE CONTROL") //<<@ (AfterLayout (uiDefSetHalign AlignRight o uiDefSetBaseCls "wall-header")) //FIXME
mapContacts = mapRead (\(x,y) -> x++y) (contactsOfOpenIncidentsGeo |*| contactsProvidingHelpGeo)
selectContent
= (switchContent >&> withSelection viewNoSelection configureContent) <<@ (ArrangeWithSideBar 0 LeftSide False)
switchContent = enterChoice (Title "Choose Content") [ChooseFromList bigLabel] contentOptions
switchContent = (Title "Choose Content") @>> enterChoice [ChooseFromList bigLabel] contentOptions
contentOptions
= ["Overview","Incident","Contact","Clock","Countdown"]
......@@ -30,7 +30,7 @@ where
= get (standardMapLayers |*| standardPerspective)
>>- \(baseLayers,perspective) ->
withShared perspective
\p -> updateSharedInformation (Title title) [UpdateAs (toMap baseLayers) fromMap] (p >*| mapContacts) @ fst
\p -> Title title @>> updateSharedInformation [UpdateSharedAs (toMap baseLayers) fromMap (const o Just)] (p >*| mapContacts) @ fst
//<<@ AfterLayout (tweakUI fill) //FIXME
@ WallOverview
where
......@@ -39,18 +39,19 @@ where
fromMap _ {LeafletMap|perspective}
= fromLeafletPerspective perspective
configure "Incident"
= enterChoiceWithSharedAs (Title title) [ChooseFromList bigLabel] allIncidentsShort (\{IncidentShort|incidentNo} -> WallIncidentSummary (Just incidentNo))
= Title title @>> enterChoiceWithSharedAs [ChooseFromList bigLabel] allIncidentsShort (\{IncidentShort|incidentNo} -> WallIncidentSummary (Just incidentNo))
configure "Contact"
= enterChoiceWithSharedAs (Title title) [ChooseFromList bigLabel] allContactsShort (\{ContactShort|contactNo} -> WallContactSummary (Just contactNo))
= Title title @>> enterChoiceWithSharedAs [ChooseFromList bigLabel] allContactsShort (\{ContactShort|contactNo} -> WallContactSummary (Just contactNo))
configure "Clock"
= viewInformation (Title title) [] "No configuration is needed for the clock."
= Title title @>> viewInformation [] "No configuration is needed for the clock."
//<<@ AfterLayout (tweakUI fill) //FIXME
@! WallClock
configure "Countdown"
= get currentDateTime
>>- updateInformation (title,"Set the countdown date and time") []
>>- \datetime ->
Title title @>> Hint "Set the countdown date and time" @>> updateInformation [] datetime
@ WallCountDown
configure _
= viewInformation (title,"This option is not available yet...") [] () @? const NoValue
= Title title @>> Hint "This option is not available yet..." @>> viewInformation [] () @? const NoValue
bigLabel l = SpanTag [StyleAttr "font-size: 24px; font-weight: bold; margin-bottom: 5px;"] [Text (toSingleLineText l)]
......@@ -7,6 +7,8 @@ import Text, Text.HTML, Data.List, iTasks.Internal.HtmlUtil
derive class iTask WallContent
derive gDefault ContactMap, ContactMapLayer, ContactMapLayerDefinition, ContactMapMarker, ContactMapRegion, ContactTrack, ContactMapMarkerType, DateTime
wallContent :: SimpleSDSLens WallContent
wallContent = sharedStore "WallContent" (WallOverview defaultValue)
......@@ -15,18 +17,18 @@ viewVideoWallContent
= (header ||- content) <<@ (ArrangeWithHeader 0) //<<@ AfterLayout plainLayoutFinal //FIXME
where
header
= viewSharedInformation () [ViewAs view] (currentTime |*| currentUTCTime) //<<@ (AfterLayout (uiDefSetHalign AlignRight o uiDefSetBaseCls "wall-header")) //FIXME
= viewSharedInformation [ViewAs view] (currentTime |*| currentUTCTime) //<<@ (AfterLayout (uiDefSetHalign AlignRight o uiDefSetBaseCls "wall-header")) //FIXME
where
view (local,utc) = "LOCAL: " + lpad (toString local.Time.hour) 2 '0' + ":" + lpad (toString local.Time.min) 2 '0' + " "
+ "UTC: " + lpad (toString utc.Time.hour) 2 '0' + ":" + lpad (toString utc.Time.min) 2 '0'
content
= whileUnchanged wallContent \content -> case content of
WallClock = (viewSharedInformation (Title "Local Time") [ViewAs formatTime] currentTime @! content)
WallClock = (Title "Local Time" @>> viewSharedInformation [ViewAs formatTime] currentTime @! content)
// WallCountDown until = (viewSharedInformation (Title "Countdown") [ViewAs (\t -> formatDateTime (until - t))] currentDateTime @! content)
WallOverview perspective = viewWallOverview perspective @! content
WallContactSummary (Just contactNo) = viewWallContactSummary contactNo @! content
WallIncidentSummary (Just incidentNo) = viewWallIncidentSummary incidentNo @! content
_ = viewInformation "Nothing selected..." [] () @! content
_ = Hint "Nothing selected..." @>> viewInformation [] () @! content
formatTime time = DivTag [StyleAttr "font-size: 80pt; text-align: center; padding-top: 200px;"] [Text (toString time)]
formatDateTime time = DivTag [StyleAttr "font-size: 80pt; text-align: center; padding-top: 200px;"] [Text (toString time)]
......@@ -34,11 +36,11 @@ formatDateTime time = DivTag [StyleAttr "font-size: 80pt; text-align: center; pa
mapContacts = mapRead (\(x,y) -> x++y) (contactsOfOpenIncidentsGeo |*| contactsProvidingHelpGeo)
viewWallOverview perspective
= ((viewSharedInformation (Title "Open Incidents") [ViewAs formatIncidents] openIncidentsDetails)
= (((Title "Open Incidents") @>> viewSharedInformation [ViewAs formatIncidents] openIncidentsDetails)
-&&-
(get standardMapLayers
>>- \baseLayers ->
viewSharedInformation () [ViewAs (toMap perspective baseLayers)] mapContacts /* <<@ AfterLayout (tweakUI (setMargins 0 0 0 0 o fill))*/ ) //FIXME
viewSharedInformation [ViewAs (toMap perspective baseLayers)] mapContacts /* <<@ AfterLayout (tweakUI (setMargins 0 0 0 0 o fill))*/ ) //FIXME
) <<@ ArrangeWithSideBar 0 LeftSide False
where
toMap perspective baseLayers contacts
......@@ -61,11 +63,11 @@ where
contact = sdsFocus contactNo contactByNo
viewContactTitle
= viewSharedInformation () [] (mapRead contactTitle contact) /* <<@ AfterLayout (uiDefSetBaseCls "wall-contact-title") */ //FIXME
= viewSharedInformation [] (mapRead contactTitle contact) /* <<@ AfterLayout (uiDefSetBaseCls "wall-contact-title") */ //FIXME
viewDetails
= (viewPhoto -&&- viewTypeDetails) <<@ (Title "Details")
viewPhoto
= viewSharedInformation () [ViewAs formatPhoto] contact
= viewSharedInformation [ViewAs formatPhoto] contact
where
formatPhoto {Contact|photos,type,notes}
= ImgTag [ClassAttr "wall-contact-details",WidthAttr "200",HeightAttr "200",SrcAttr (photoSrc photos)]
......@@ -75,14 +77,14 @@ where
viewTypeDetails = whileUnchanged contact
\{Contact|type} -> case type of
Just Vessel = viewSharedInformation () [] (sdsFocus contactNo vesselDetailsByNo) @! ()
Just Person = viewSharedInformation () [] (sdsFocus contactNo personDetailsByNo) @! ()
_ = viewInformation () [] ()
Just Vessel = viewSharedInformation [] (sdsFocus contactNo vesselDetailsByNo) @! ()
Just Person = viewSharedInformation [] (sdsFocus contactNo personDetailsByNo) @! ()
_ = viewInformation [] ()
viewPosition
= ((viewSharedInformation (Title "Position") [ViewAs formatPosition] contact /* <<@ AfterLayout (uiDefSetBaseCls "wall-contact-position") */) //FIXME
= (((Title "Position") @>> viewSharedInformation [ViewAs formatPosition] contact /* <<@ AfterLayout (uiDefSetBaseCls "wall-contact-position") */) //FIXME
-&&-
(viewSharedInformation (Title "Map") [ViewAs contactMap] contact /*<<@ AfterLayout (tweakUI (setMargins 0 0 0 0 o fill)) */) //FIXME
((Title "Map") @>> viewSharedInformation [ViewAs contactMap] contact /*<<@ AfterLayout (tweakUI (setMargins 0 0 0 0 o fill)) */) //FIXME
)
where
formatPosition {Contact|position=Just pos} = toSingleLineText pos
......@@ -99,7 +101,7 @@ where
markers c _ = []
viewCommunication
= viewSharedInformation (Title "Last communication") [ViewAs (formatComms o take 5)] (sdsFocus contactNo contactCommunications)
= (Title "Last communication") @>> viewSharedInformation [ViewAs (formatComms o take 5)] (sdsFocus contactNo contactCommunications)
where
formatComms items
= DivTag []
......@@ -116,9 +118,9 @@ where
incident = sdsFocus incidentNo incidentByNo
viewIncidentTitle
= viewSharedInformation () [] (sdsFocus incidentNo incidentTitleByNo) //<<@ AfterLayout (uiDefSetBaseCls "wall-contact-title") //FIXME
= viewSharedInformation [] (sdsFocus incidentNo incidentTitleByNo) //<<@ AfterLayout (uiDefSetBaseCls "wall-contact-title") //FIXME
viewIncidentContacts
= viewSharedInformation (Title "Involved Contacts") [ViewAs toView] (sdsFocus incidentNo contactsByIncident)
= (Title "Involved Contacts") @>> viewSharedInformation [ViewAs toView] (sdsFocus incidentNo contactsByIncident)
where
toView contacts = DivTag [ClassAttr "wall-incident-contacts"] (map formatContact contacts)
......@@ -132,14 +134,14 @@ where
photoSrc _ = "/no-photo.jpg"
viewIncidentActions
= viewSharedInformation (Title "Open Actions") [ViewAs toView] (sdsFocus incidentNo actionStatusesByIncident) /* <<@ AfterLayout (tweakUI fill) */ //FIXME
= (Title "Open Actions") @>> viewSharedInformation [ViewAs toView] (sdsFocus incidentNo actionStatusesByIncident) /* <<@ AfterLayout (tweakUI fill) */ //FIXME
where
toView actions = DivTag [] [vizAction a \\ (_,_,a) <- actions]
vizAction {ActionStatus|title}
= DivTag [ClassAttr "wall-action"] [H2Tag [ClassAttr "wall-action-title"] [Text title]]
viewIncidentLog
= viewSharedInformation (Title "Last Log Messages") [ViewAs (toView o take 5)] (sdsFocus incidentNo incidentLog)
= Title "Last Log Messages" @>> viewSharedInformation [ViewAs (toView o take 5)] (sdsFocus incidentNo incidentLog)
where
toView log = DivTag [] (flatten [[vizDate date:map vizEntry entries] \\ (date,entries) <- groupByDate log])
......
......@@ -19,7 +19,7 @@ crewAliasListsStore = indexedStore "crewAliasLists" []
//Manage the crew information for a specific contact
manageContactCrew :: ContactNo -> Task ()
manageContactCrew contactNo
= updateSharedContactRefList "Manage crew" (sdsFocus contactNo crewListsStore)
= Hint "Manage crew" @>> updateSharedContactRefList (sdsFocus contactNo crewListsStore)
//Optional Improvements
// -|| forever (addStandardCrewMembers contactNo)
-|| forever (quickAddStandardCrewMembers contactNo)
......@@ -38,7 +38,7 @@ where
quickAddStandardCrewMembers contactNo
= get (sdsFocus contactNo crewAliasListsStore)
-&&-
(enterInformation "Enter the numbers of the crew numbers you want to set (comma separated)" [] @ (map (toInt o trim) o (split ",")))
(Hint "Enter the numbers of the crew numbers you want to set (comma separated)" @>> enterInformation [] @ (map (toInt o trim) o (split ",")))
>>* [OnAction (Action "Set members") (hasValue (\(aliasList,enteredNos) ->
setCrewMembers contactNo (flatten [[cNo \\ (aNo,cNo) <- aliasList | aNo == eNo] \\ eNo <- enteredNos])))]
......@@ -55,17 +55,17 @@ where
refs = sdsFocus contactNo crewAliasListsStore
manageCurrentItems
= updateSharedInformation "Manage crew list" [UpdateAs toPrj fromPrj] items
= Hint "Manage crew list" @>> updateSharedInformation [UpdateSharedAs toPrj fromPrj (const o Just)] items
where
items = sdsDeref refs snd contactsByNosShort derefAliasList
toPrj l = [(contactIdentity c, aNo, contactTitle c)\\(aNo,c) <-l]
fromPrj _ items = [(aNo,cNo) \\ (cNo,aNo,_) <- items]
addItem
= (enterInformation "Enter a number to use when refering to this contact" []
= (Hint "Enter a number to use when refering to this contact" @>> enterInformation []
-&&-
selectKnownOrDefineNewContact)
>>? (\(aliasNo,def) -> createContactIfNew def >>- \contactNo -> upd (\r -> r++[(aliasNo,contactNo)]) refs)
>?? (\(aliasNo,def) -> createContactIfNew def >>- \contactNo -> upd (\r -> r++[(aliasNo,contactNo)]) refs)
@! ()
derefAliasList :: [(Int,ContactNo)] [ContactShort] -> [(Int,ContactShort)]
......
definition module Incidone.Integration.AIS
import iTasks, Incidone.Util.AIS
import iTasks, Message.Encodings.AIS
//Connect to an external AIS Server that streams AIVDM messages
syncAISStream :: Task ()
......
implementation module Incidone.Integration.AIS
import iTasks
import Incidone.Util.AIS
import Message.Encodings.AIS
import Incidone.Configuration
import Incidone.OP.SDSs, Incidone.OP.Conversions
import Incidone.Util.TaskPatterns
import qualified Data.Map as DM
import Data.Functor
derive gDefault AISContact, DateTime, ContactTrack, Degrees, AIVDM5, AIVDMCNB
syncAISStream :: Task ()
syncAISStream = withShared ([],False,[],False) (\channel -> (sync channel -&&- consume channel) @! ())
where
......
......@@ -19,7 +19,7 @@ where
= get asteriskLinkConfig
>>- \{AsteriskConfig|host,port,username,password} ->
set ([],False,[authEvent username password],False) channel
>>| syncNetworkChannel host port "\r\n\r\n" decodeAsteriskEvent encodeAsteriskEvent channel
>-| syncNetworkChannel host port "\r\n\r\n" decodeAsteriskEvent encodeAsteriskEvent channel
consume channel
= consumeNetworkStream processEvents channel
......
concept module Incidone.OP.Concepts
import iTasks, iTasks.Extensions.Document, iTasks.Extensions.Contact, Database.SQL, Incidone.OP.ConceptsTOP, Incidone.OP.ConceptsSQL, Incidone.ContactPosition, Incidone.Util.AIS
import iTasks, iTasks.Extensions.Document, iTasks.Extensions.Contact, Database.SQL, Incidone.OP.ConceptsTOP, Incidone.OP.ConceptsSQL, Incidone.ContactPosition, Message.Encodings.AIS
//Shared value types
$$ MMSI = Int
......
definition module Incidone.OP.Concepts
//GENERATED BY CCL, DO NOT EDIT
import iTasks, iTasks.Extensions.Document, iTasks.Extensions.Contact, Database.SQL, Incidone.OP.ConceptsTOP, Incidone.OP.ConceptsSQL, Incidone.ContactPosition, Incidone.Util.AIS
import iTasks, iTasks.Extensions.Document, iTasks.Extensions.Contact, Database.SQL, Incidone.OP.ConceptsTOP, Incidone.OP.ConceptsSQL, Incidone.ContactPosition, Message.Encodings.AIS
:: AISStaticInfo :== AIVDM5
......
implementation module Incidone.OP.Concepts
//GENERATED BY CCL, DO NOT EDIT