Compare commits
535 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f85bde5dee | |||
| 05e7472051 | |||
| 006691db7e | |||
| a663881368 | |||
| c8cc8576b0 | |||
| 31df7e77ba | |||
| 67d4862f6b | |||
| 6a16327c30 | |||
| 060b1b8f41 | |||
| da2e228293 | |||
| ab7397bf55 | |||
| f79547f781 | |||
| 2152f1c90e | |||
| 503fb4d246 | |||
| 2befefa752 | |||
| 85e64c5076 | |||
| 60523dc994 | |||
| 6d780bf350 | |||
| eec02a1f84 | |||
| ace2fe6fe3 | |||
| 188794af8d | |||
| 92a941a944 | |||
| 0e1ddf2b11 | |||
| b57fa010d1 | |||
| f816452b78 | |||
| 120083bb31 | |||
| a5bb5c4686 | |||
| e5e2729f0a | |||
| ba8b902f48 | |||
| 2d67815ae6 | |||
| ec0c9066d2 | |||
| f9473f558a | |||
| 58ae858077 | |||
| 613e7938b3 | |||
| e07ff1a445 | |||
| de7dd34ea2 | |||
| 0552f695f9 | |||
| b8d4f3d946 | |||
| fa112a70b1 | |||
| 88078bad4c | |||
| 1a3d6ec800 | |||
| 9b5fc2cd74 | |||
| 97309ebb88 | |||
| c26398a13f | |||
| fdb874b616 | |||
| dfd06544ec | |||
| 69c10ed1e7 | |||
| 00df9800ed | |||
| 6494fd6b41 | |||
| e9cb673f3a | |||
| 4e5cb64710 | |||
| aaa6ff9938 | |||
| 099cb6b13b | |||
| 75c4065d27 | |||
| f3ce5c8993 | |||
| 9760d3f0d5 | |||
| dab851f3d4 | |||
| 81b3d4d6d7 | |||
| 5b09566c49 | |||
| 70dcc23b25 | |||
| 4c90b3fb16 | |||
| 87931df9b6 | |||
| 5d03229d35 | |||
| fb31d662cc | |||
| 489ec8701f | |||
| e1afe66c7e | |||
| b920d822ef | |||
| 0908763d33 | |||
| 847ad87b23 | |||
| 90cf165dcf | |||
| 8b0307bc72 | |||
| a645e2829a | |||
| 33d8644dd6 | |||
| de713a848c | |||
| e9aa91fe7f | |||
| 9661c79bd6 | |||
| 91fab4dcd4 | |||
| 29488a2d87 | |||
| a3f1dd2459 | |||
| ab12145e4d | |||
| 442ea7e6ab | |||
| 04f0024734 | |||
| 831cc60ab2 | |||
| 7fc4c55362 | |||
| 78e8202d1c | |||
| f35e953531 | |||
| f5796bdec8 | |||
| 9f87c22424 | |||
| 88ba11a836 | |||
| 53f370d24e | |||
| 9e0998f054 | |||
| 0dce0cb88c | |||
| a61097bdcd | |||
| ec073bd544 | |||
| 1c23da6fb2 | |||
| 7e6b993b06 | |||
| 792251dfb9 | |||
| 1c4ebb5380 | |||
| 4ac76d23ca | |||
| 556ddc0b6f | |||
| a0dde690ea | |||
| a76dab5be6 | |||
| 2d10bc5bbf | |||
| 4042632e0b | |||
| 7ccf83e1a4 | |||
| 019cd0756f | |||
| 0e5f9f80be | |||
| fc6767860a | |||
| 5b5b4be7b2 | |||
| 45351d082e | |||
| 22ccd07491 | |||
| 2cf9ee647b | |||
| efb567824b | |||
| f0aac39486 | |||
| f278055805 | |||
| 6f2e36fd11 | |||
| 119d80ffc8 | |||
| 771c3df864 | |||
| 7d1963e458 | |||
| dde85972b3 | |||
| 5e061da910 | |||
| 46bea345de | |||
| bc53462ad6 | |||
| 884df40a1d | |||
| b23168c067 | |||
| 5568212f15 | |||
| 79db79d799 | |||
| 18a4008efd | |||
| 83e4abd1ee | |||
| 243bcfba72 | |||
| af2c8c560f | |||
| 6a37f3871c | |||
| 759a388448 | |||
| 360e89d7ce | |||
| 64655a3284 | |||
| c58356bde8 | |||
| f74117632d | |||
| 5f2b8b8e2b | |||
| f0ce7481fd | |||
| 6e7a5c6140 | |||
| 079c18ee19 | |||
| 26ef6a3815 | |||
| cf6dcefe6c | |||
| 35590eb979 | |||
| 583a8b8a76 | |||
| c6e8a664de | |||
| 24a5e0a579 | |||
| a242c197fb | |||
| 08bdd23149 | |||
| c5b35b2d98 | |||
| 5407fecd1f | |||
| 12d2821d26 | |||
| 2e6d58e6a3 | |||
| 0f0c0fd5ae | |||
| ef9ec1c223 | |||
| f4387bae30 | |||
| 49b238a23a | |||
| 4b75c01b28 | |||
| e7f641046b | |||
| 9aaabe0fab | |||
| b6e4b711bf | |||
| 58fcfd210b | |||
| 5868b9c234 | |||
| 0dc6d9cf9d | |||
| 67f50cf2fd | |||
| 8b26a4d49a | |||
| a1d0bb0aa1 | |||
| bfe08560b1 | |||
| ac3ac24272 | |||
| 03e7191d0e | |||
| b3a42f8723 | |||
| 9c4b740300 | |||
| 2a12bdadf2 | |||
| c90e8ad4d2 | |||
| 4a52c51c86 | |||
| 0efc817ddc | |||
| fee54fc98c | |||
| 210f751396 | |||
| 2e2bc3fe29 | |||
| a6f05f86d1 | |||
| fc144e4848 | |||
| cef9531428 | |||
| abd4faefbf | |||
| 966f7aaed5 | |||
| 51b59fa995 | |||
| 0b713736bd | |||
| 9e33581c66 | |||
| b97792b596 | |||
| c0746f8eff | |||
| a826a9d692 | |||
| 6d04203d37 | |||
| 33b2ed8a94 | |||
| 4f16da7ad0 | |||
| 36f92c7655 | |||
| 1d4f5a759e | |||
| 28af9bc811 | |||
| cf04cd4094 | |||
| 23e9efb28a | |||
| 57322df29c | |||
| fff82d34c6 | |||
| 7211860c21 | |||
| 9fc69044f8 | |||
| 76467c3e81 | |||
| 4cfc04e2f3 | |||
| 6bfc7771d0 | |||
| 7055135257 | |||
| 85312cf20d | |||
| 4051cae5b0 | |||
| c64bb6dedf | |||
| 7bb17ae0db | |||
| 3244eb9b15 | |||
| 6e173847ba | |||
| 8cbc1f763d | |||
| 2d45abeb28 | |||
| 2fd0ad77bc | |||
| 53c1167831 | |||
| 48d4a1d7bb | |||
| 4bbbba6e89 | |||
| 0a13575325 | |||
| d6075209df | |||
| 9d1b39422b | |||
| 38e297d32b | |||
| 459ef3c9f1 | |||
| 3bb12487ba | |||
| 8b2428c60d | |||
| f9befd9051 | |||
| 1020a9bd5d | |||
| 2844c4ea86 | |||
| 3344188fee | |||
| 67138c2f78 | |||
| f59d19ef21 | |||
| d0fa7e638f | |||
| 63011e466e | |||
| 92d1976300 | |||
| a0cdc9fa07 | |||
| 60f0006597 | |||
| 67a3c62a08 | |||
| 21d5dc1e0b | |||
| 0d810f59f9 | |||
| dba60b700f | |||
| ad9a56bd20 | |||
| 82585e9104 | |||
| dfbb241b0b | |||
| f69ea91f45 | |||
| 768d916092 | |||
| c0acecae10 | |||
| f741d1c7e4 | |||
| d25c70f1d1 | |||
| 6f954467ef | |||
| 867987a5f5 | |||
| 61e0a6351c | |||
| 558264c23b | |||
| cf7aa371af | |||
| ffedaf6a73 | |||
| d9ae272b36 | |||
| 3c5d1f5c9e | |||
| b69b8b7585 | |||
| 8c7e498fb2 | |||
| 359413a296 | |||
| cef7d894c4 | |||
| 7d9cc1aacc | |||
| a6780a756b | |||
| 4e37d17b42 | |||
| 793923348f | |||
| 700db1788d | |||
| 68a5a44702 | |||
| 464891f5a1 | |||
| d2e5db2680 | |||
| a9c41d0545 | |||
| 0bc458d307 | |||
| 36c7cc285e | |||
| f9fbd31a0f | |||
| 8789c1f855 | |||
| f65073480a | |||
| 157ed831a7 | |||
| 0799a59a15 | |||
| 60ea3e83e1 | |||
| 4b874deb50 | |||
| 6726b9ad50 | |||
| 75e6fe609e | |||
| b40d1ccf7d | |||
| 4f7ba23904 | |||
| 49084706f2 | |||
| 1852e5f6bf | |||
| be0ed5428a | |||
| f428efde6a | |||
| e79f04f33e | |||
| 04db8c281f | |||
| 2681698186 | |||
| 1682c66da6 | |||
| 38bc1032d8 | |||
| ba37eef9ca | |||
| 3db179882a | |||
| ba8f25a807 | |||
| eac3d3089b | |||
| 0454a9e147 | |||
| f390cd1c68 | |||
| aaa1ba5aa9 | |||
| fb9556abd9 | |||
| 3cfb3b1f84 | |||
| b071bab137 | |||
| 5dbc68ea76 | |||
| e76fbc3b77 | |||
| 09ca0514d1 | |||
| faec32a5bb | |||
| 1f5793ab79 | |||
| df22bd1cec | |||
| 61dba4e78d | |||
| bb678117f8 | |||
| 2dc08e71b7 | |||
| df2f844e74 | |||
| 621c602fc0 | |||
| f809169757 | |||
| 848b135612 | |||
| db6af66705 | |||
| 728e1f5a86 | |||
| d02d95bc9e | |||
| c1180c5373 | |||
| 4e01fb64e6 | |||
| d0fcb1da34 | |||
| 48352d06b3 | |||
| d995652569 | |||
| 5a958fa51c | |||
| cfb9e2cacd | |||
| 7932fc1cab | |||
| e0fc1715b5 | |||
| 1cfd6caa64 | |||
| 54bf18888d | |||
| 6b60fc4259 | |||
| 216af8697c | |||
| d97e7314d0 | |||
| 67d9dda143 | |||
| 5c60e303cb | |||
| e36b8f3a56 | |||
| 1e7a19b463 | |||
| 8004249a29 | |||
| 6cd800e4ef | |||
| e182bc7ed2 | |||
| c338d51c9d | |||
| c1912250df | |||
| 994c41980e | |||
| 385b7a514d | |||
| 3aaade9228 | |||
| b4dd19b711 | |||
| 9e9b83b4ba | |||
| 5ff5114669 | |||
| f63039f3fb | |||
| b39399463d | |||
| 8217ef7fbb | |||
| b4851c34e1 | |||
| 8e39832d3e | |||
| ce7ac6da16 | |||
| 57879a57cd | |||
| 6f5b367028 | |||
| 291948c1ef | |||
| 0ca6888fb1 | |||
| 5e92236396 | |||
| 28db40112b | |||
| b2153883ef | |||
| 807cbeb75d | |||
| 4730aebdc6 | |||
| c2279eec87 | |||
| f5567ae9ad | |||
| 2fcba04cf5 | |||
| 0eefd1605f | |||
| 7b88ea022d | |||
| 7a922114ab | |||
| f717c270fd | |||
| ee5ed468c3 | |||
| a9ded445a7 | |||
| 9ecad52df2 | |||
| 8c500985bf | |||
| 3567f9ba5d | |||
| 852bfb716c | |||
| 473956aa3c | |||
| b22fc19400 | |||
| f6a8ece992 | |||
| afc0c21aae | |||
| 08e6106c1f | |||
| 1f9f654e3d | |||
| 501e923760 | |||
| 37b716cfc5 | |||
| 8584db0ab5 | |||
| 5aff3e9692 | |||
| 5d8f03cbc3 | |||
| b6c85ac15a | |||
| c2af757f4e | |||
| 26252c55ac | |||
| 3ce547bcea | |||
| e0492f589e | |||
| 4931288ffd | |||
| 52e0f77a3c | |||
| 20c016f1bf | |||
| 00a271cbba | |||
| 3a6b69634d | |||
| 78cf7f42e3 | |||
| 2b52454c00 | |||
| e032e4561b | |||
| 23ce1e0476 | |||
| 825b7b98d7 | |||
| 3de3128a2a | |||
| 92d70ccc8b | |||
| f8c5154457 | |||
| 3a3874e9f1 | |||
| 61b94c519b | |||
| ac0f46ca66 | |||
| e538cdb509 | |||
| df8a63c5f5 | |||
| 6827a61bf8 | |||
| 20e56c05b3 | |||
| 5494139319 | |||
| c491ba087a | |||
| 5cf045c941 | |||
| 55fea5f077 | |||
| 3a9cb73950 | |||
| d99f613b79 | |||
| 68db8ddff3 | |||
| c7490b264b | |||
| a8e84cfad3 | |||
| 5ec4f7e4e8 | |||
| b019ce2f2e | |||
| dd90e41610 | |||
| bdf78e374d | |||
| 163197f583 | |||
| 8e13bba44a | |||
| e4478b86a5 | |||
| 1b1ae59ed7 | |||
| a54f44d22a | |||
| d2394274eb | |||
| 0eedb0b397 | |||
| 782e9db1f6 | |||
| 2977472c56 | |||
| 8f3a8bfa91 | |||
| 914f6e9516 | |||
| fa6f65cb7c | |||
| dafbe6f995 | |||
| 4a8ac6377b | |||
| c91fac4ec4 | |||
| 00d23b084e | |||
| e0a3b82cea | |||
| e49036d8c4 | |||
| 4a8356692b | |||
| adfb7bc63a | |||
| 3f41cefa88 | |||
| 2074ff1987 | |||
| 65fe189421 | |||
| bb7590eab4 | |||
| 6a04457219 | |||
| 7f8b1d9586 | |||
| 4362cc53bb | |||
| 959e6b2a12 | |||
| 2d91070e5a | |||
| cc038ece32 | |||
| 7af1292f29 | |||
| 2c3fd7a84f | |||
| d36f70dbc7 | |||
| 77f5f29c90 | |||
| ead45ed843 | |||
| a6259bb7eb | |||
| 0249ebeb95 | |||
| 1c3a35a137 | |||
| c12319b417 | |||
| 90ac00a628 | |||
| e5c71cb3a4 | |||
| ebf0681574 | |||
| 642643f412 | |||
| 8dd65ac255 | |||
| 8df58f226b | |||
| 58b4f2ce14 | |||
| 65f0c836fe | |||
| 2aa16085a5 | |||
| 25f05a69c6 | |||
| 5c2a94da16 | |||
| 162325e90e | |||
| b022a8c608 | |||
| 1e404f5e6b | |||
| 8ef7780332 | |||
| 51b4f7b3f7 | |||
| 9b3fa33e50 | |||
| 9349d0813d | |||
| 8d9bc500a1 | |||
| cae7b6e29f | |||
| 0b4ac732b2 | |||
| acacbb91e3 | |||
| fd6d3d9a2f | |||
| 3b531e30b1 | |||
| 0c78085b2e | |||
| 4ab53308f7 | |||
| 06ae161793 | |||
| 94e005d2f8 | |||
| 717072c3a5 | |||
| 02b4bde92a | |||
| a397d1e233 | |||
| d2198c0765 | |||
| 549bf63198 | |||
| 8b824f5342 | |||
| d052d5e8a1 | |||
| 610c22dd02 | |||
| a5496ab6a9 | |||
| c29c8f009c | |||
| fb7e9f2a6c | |||
| 62c2bbb9fa | |||
| 7656772194 | |||
| f22ff050e0 | |||
| 708f0b44fd | |||
| 2ee4581f17 | |||
| e337fb869f | |||
| 4a8b0147e1 | |||
| c95a1c7e1f | |||
| a07cd5c3f5 | |||
| 4d1473582e | |||
| 3bc9f4c452 | |||
| 11377038a0 | |||
| 6053d3eac1 | |||
| 529830f36b | |||
| 505cf6265c | |||
| 8cd9673eec | |||
| ac9cb28558 | |||
| 6eefe0698c | |||
| d0113532b6 | |||
| 5a1d2ad5f4 | |||
| dfe02f4c74 | |||
| 5349d556b9 | |||
| 7f7d8a501b | |||
| cbee0e465b | |||
| faf00f0b0d | |||
| fa97da5781 | |||
| e7bab546db | |||
| e2f4a30b5b | |||
| ccff1df041 | |||
| 2037cfc25a | |||
| 268a091d8a | |||
| 6b52dfab3e | |||
| 839999851f | |||
| a87470b7b5 |
+149
-13
@@ -36,24 +36,139 @@ jobs:
|
||||
- attach_workspace:
|
||||
at: ./
|
||||
- run:
|
||||
name: Patch
|
||||
name: Create Innosetup signing cert
|
||||
shell: powershell.exe
|
||||
command:
|
||||
| # If no tag, use 0.0.0.1 and don't make any YML (for testing only!)
|
||||
$tag = if([string]::IsNullOrEmpty($env:CIRCLE_TAG)) { "0.0.0" } else { $env:CIRCLE_TAG }
|
||||
$semver = if($tag.Contains('/')) {$tag.Split("/")[1] } else { $tag }
|
||||
command: |
|
||||
echo $env:PFX_B64 > "speckle-sharp-ci-tools\SignTool\AEC Systems Ltd.txt"
|
||||
certutil -decode "speckle-sharp-ci-tools\SignTool\AEC Systems Ltd.txt" "speckle-sharp-ci-tools\SignTool\AEC Systems Ltd.pfx"
|
||||
- run:
|
||||
name: Set Environment Variable
|
||||
shell: powershell.exe
|
||||
command: |
|
||||
$tag = if([string]::IsNullOrEmpty($env:CIRCLE_TAG)) { "2.0.999" } else { $env:CIRCLE_TAG }
|
||||
$semver = if($tag.Contains('/')) {$tag.Split("/")[0] } else { $tag }
|
||||
$ver = if($semver.Contains('-')) {$semver.Split("-")[0] } else { $semver }
|
||||
$channel = if($semver.Contains('-')) {$semver.Split("-")[1] } else { "latest" }
|
||||
$version = "$($ver).$($env:CIRCLE_BUILD_NUM)"
|
||||
New-Item -Force "speckle-sharp-ci-tools/Installers/sketchup/$channel.yml" -ItemType File -Value "version: $semver"
|
||||
echo $version
|
||||
$version = "$($ver).$($env:WORKFLOW_NUM)"
|
||||
python patch_version.py $semver
|
||||
speckle-sharp-ci-tools\InnoSetup\ISCC.exe speckle-sharp-ci-tools\sketchup.iss
|
||||
environment:
|
||||
WORKFLOW_NUM: << pipeline.number >>
|
||||
- run:
|
||||
name: Build Installer
|
||||
command: speckle-sharp-ci-tools\InnoSetup\ISCC.exe speckle-sharp-ci-tools\sketchup.iss /Sbyparam=$p
|
||||
shell: cmd.exe #does not work in powershell
|
||||
|
||||
#- run:
|
||||
# name: Patch
|
||||
# shell: powershell.exe
|
||||
# command:
|
||||
# | # If no tag, use 0.0.0.1 and don't make any YML (for testing only!)
|
||||
# $tag = if([string]::IsNullOrEmpty($env:CIRCLE_TAG)) { "0.0.0" } else { $env:CIRCLE_TAG }
|
||||
# $semver = if($tag.Contains('/')) {$tag.Split("/")[1] } else { $tag }
|
||||
# $ver = if($semver.Contains('-')) {$semver.Split("-")[0] } else { $semver }
|
||||
# $channel = if($semver.Contains('-')) {$semver.Split("-")[1] } else { "latest" }
|
||||
# $version = "$($ver).$($env:CIRCLE_BUILD_NUM)"
|
||||
# New-Item -Force "speckle-sharp-ci-tools/Installers/sketchup/$channel.yml" -ItemType File -Value "version: $semver"
|
||||
# echo $version
|
||||
# python patch_version.py $semver
|
||||
# speckle-sharp-ci-tools\InnoSetup\ISCC.exe speckle-sharp-ci-tools\sketchup.iss
|
||||
- persist_to_workspace:
|
||||
root: ./
|
||||
paths:
|
||||
- speckle-sharp-ci-tools/Installers
|
||||
|
||||
build-connector-mac:
|
||||
macos:
|
||||
xcode: 12.5.1
|
||||
parameters:
|
||||
projname:
|
||||
type: string
|
||||
default: ""
|
||||
slug:
|
||||
type: string
|
||||
default: ""
|
||||
installer:
|
||||
type: boolean
|
||||
default: false
|
||||
converter-files:
|
||||
type: string
|
||||
default: ""
|
||||
installername:
|
||||
type: string
|
||||
default: ""
|
||||
build-config:
|
||||
type: string
|
||||
default: Release
|
||||
bundlename:
|
||||
type: string
|
||||
default: ""
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: ./
|
||||
- run:
|
||||
name: Install dotnet
|
||||
command: |
|
||||
curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --channel Current
|
||||
|
||||
$HOME/.dotnet/dotnet --version
|
||||
$HOME/.dotnet/dotnet --list-runtimes
|
||||
$HOME/.dotnet/dotnet --list-sdks
|
||||
- run:
|
||||
name: Create installer target dir
|
||||
command: |
|
||||
mkdir -p speckle-sharp-ci-tools/Installers/<< parameters.slug >>
|
||||
- run:
|
||||
name: Set Environment Variable
|
||||
command: |
|
||||
TAG=$(if [ "${CIRCLE_TAG}" ]; then echo $CIRCLE_TAG; else echo "2.0.999"; fi;)
|
||||
SEMVER=$(echo "$TAG" | sed -e 's/\/[a-zA-Z-]*//')
|
||||
VER=$(echo "$SEMVER" | sed -e 's/-.*//')
|
||||
VERSION=$(echo $VER.$WORKFLOW_NUM)
|
||||
python3 patch_version.py $SEMVER
|
||||
environment:
|
||||
WORKFLOW_NUM: << pipeline.number >>
|
||||
- run:
|
||||
name: Zip Connector files
|
||||
command: |
|
||||
zip -r << parameters.slug >>-mac.zip "./speckle_connector" "./speckle_connector.rb"
|
||||
# Copy installer files
|
||||
- run:
|
||||
name: Copy files to installer
|
||||
command: |
|
||||
mkdir -p speckle-sharp-ci-tools/Mac/<< parameters.installername >>/.installationFiles/
|
||||
cp << parameters.slug >>-mac.zip speckle-sharp-ci-tools/Mac/<<parameters.installername>>/.installationFiles
|
||||
# Create installer
|
||||
- run:
|
||||
name: Exit if External PR
|
||||
command: if [ "$CIRCLE_PR_REPONAME" ]; then circleci-agent step halt; fi
|
||||
- run:
|
||||
name: Build Mac installer
|
||||
command: ~/.dotnet/dotnet publish speckle-sharp-ci-tools/Mac/<<parameters.installername>>/<<parameters.installername>>.sln -r osx-x64 -c Release
|
||||
- run:
|
||||
name: Zip installer
|
||||
command: |
|
||||
cd speckle-sharp-ci-tools/Mac/<<parameters.installername>>/bin/Release/net6.0/osx-x64/publish/
|
||||
zip -r <<parameters.slug>>.zip ./
|
||||
- store_artifacts:
|
||||
path: speckle-sharp-ci-tools/Mac/<<parameters.installername>>/bin/Release/net6.0/osx-x64/publish/<<parameters.slug>>.zip
|
||||
- run:
|
||||
name: Copy to installer location
|
||||
command: |
|
||||
TAG=$(if [ "${CIRCLE_TAG}" ]; then echo $CIRCLE_TAG; else echo "2.0.999"; fi;)
|
||||
SEMVER=$(echo "$TAG" | sed -e 's/\/[a-zA-Z-]*//')
|
||||
VER=$(echo "$SEMVER" | sed -e 's/-.*//')
|
||||
VERSION=$(echo $VER.$WORKFLOW_NUM)
|
||||
cp speckle-sharp-ci-tools/Mac/<<parameters.installername>>/bin/Release/net6.0/osx-x64/publish/<<parameters.slug>>.zip speckle-sharp-ci-tools/Installers/<< parameters.slug >>/<<parameters.slug>>-$SEMVER.zip
|
||||
environment:
|
||||
WORKFLOW_NUM: << pipeline.number >>
|
||||
- when:
|
||||
condition: << pipeline.git.tag >>
|
||||
steps:
|
||||
- persist_to_workspace:
|
||||
root: ./
|
||||
paths:
|
||||
- speckle-sharp-ci-tools/Installers
|
||||
|
||||
get-ci-tools: # Clones our ci tools and persists them to the workspace
|
||||
docker:
|
||||
- image: cimg/base:2021.01
|
||||
@@ -77,6 +192,7 @@ jobs:
|
||||
root: ./
|
||||
paths:
|
||||
- speckle-sharp-ci-tools
|
||||
|
||||
deploy-manager2:
|
||||
docker:
|
||||
- image: mcr.microsoft.com/dotnet/sdk:6.0
|
||||
@@ -115,7 +231,6 @@ workflows:
|
||||
only: /.*/
|
||||
|
||||
- build-connector:
|
||||
context: innosetup
|
||||
slug: sketchup
|
||||
requires:
|
||||
- get-ci-tools
|
||||
@@ -123,6 +238,17 @@ workflows:
|
||||
filters:
|
||||
tags:
|
||||
only: /.*/
|
||||
context: innosetup
|
||||
|
||||
- build-connector-mac:
|
||||
slug: sketchup
|
||||
requires:
|
||||
- get-ci-tools
|
||||
- build-ui
|
||||
filters:
|
||||
tags:
|
||||
only: /.*/
|
||||
installername: SpeckleSketchUpInstall
|
||||
|
||||
- deploy-manager2:
|
||||
context: do-spaces-speckle-releases
|
||||
@@ -130,11 +256,21 @@ workflows:
|
||||
os: Win
|
||||
extension: exe
|
||||
requires:
|
||||
- get-ci-tools
|
||||
- build-ui
|
||||
- build-connector
|
||||
filters:
|
||||
tags:
|
||||
only: /([0-9]+)\.([0-9]+)\.([0-9]+)(?:-\w+)?$/
|
||||
branches:
|
||||
ignore: /.*/ # For testing only! /ci\/.*/
|
||||
- deploy-manager2:
|
||||
context: do-spaces-speckle-releases
|
||||
slug: sketchup
|
||||
os: OSX
|
||||
extension: zip
|
||||
requires:
|
||||
- build-connector-mac
|
||||
filters:
|
||||
tags:
|
||||
only: /([0-9]+)\.([0-9]+)\.([0-9]+)(?:-\w+)?$/
|
||||
branches:
|
||||
ignore: /.*/ # For testing only! /ci\/.*/
|
||||
|
||||
+3
-4
@@ -1,7 +1,7 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
addressable (2.8.1)
|
||||
addressable (2.8.4)
|
||||
public_suffix (>= 2.0.2, < 6.0)
|
||||
ast (2.4.2)
|
||||
axiom-types (0.1.1)
|
||||
@@ -26,7 +26,7 @@ GEM
|
||||
path_expander (~> 1.0)
|
||||
ruby_parser (~> 3.1, > 3.1.0)
|
||||
sexp_processor (~> 4.8)
|
||||
git (1.12.0)
|
||||
git (1.18.0)
|
||||
addressable (~> 2.8)
|
||||
rchardet (~> 1.8)
|
||||
ice_nine (0.11.2)
|
||||
@@ -48,8 +48,7 @@ GEM
|
||||
pry (0.14.1)
|
||||
coderay (~> 1.1)
|
||||
method_source (~> 1.0)
|
||||
psych (3.3.4)
|
||||
public_suffix (5.0.0)
|
||||
public_suffix (5.0.1)
|
||||
rainbow (3.1.1)
|
||||
rake (13.0.6)
|
||||
rchardet (1.8.0)
|
||||
|
||||
+1
-1
Submodule _sqlite3 updated: 800dd5e366...3cce3fb807
@@ -3,6 +3,7 @@
|
||||
require 'sketchup'
|
||||
require 'pathname'
|
||||
require 'speckle_connector/debug'
|
||||
require_relative 'src/log/log'
|
||||
require_relative 'src/ui/sketchup_ui'
|
||||
require_relative 'src/ui/ui_controller'
|
||||
require_relative 'src/commands/menu_command_handler'
|
||||
|
||||
@@ -15,7 +15,9 @@ module SpeckleConnector
|
||||
def self.reload
|
||||
load(__FILE__)
|
||||
pattern = File.join(__dir__, '**/*.rb')
|
||||
Dir.glob(pattern).each { |file| load(file) }
|
||||
# TODO: Here is a opportunity to improve reloading process.
|
||||
# We can cache last edited time of the each file later to check which file need to be reloaded.
|
||||
Dir.glob(pattern).each { |file| load(file) unless file.include?('bootstrap') }
|
||||
.size
|
||||
end
|
||||
# rubocop:enable SketchupSuggestions/FileEncoding
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 7.4 KiB |
@@ -7,6 +7,7 @@ require_relative '../constants/path_constants'
|
||||
module SpeckleConnector
|
||||
# Accounts to communicate with models on user's account.
|
||||
module Accounts
|
||||
# Load accounts from user's app data.
|
||||
def self.load_accounts
|
||||
db_path = SPECKLE_ACCOUNTS_DB_PATH
|
||||
unless File.exist?(db_path)
|
||||
@@ -23,9 +24,21 @@ module SpeckleConnector
|
||||
rows.map { |row| JSON.parse(row[1]) }
|
||||
end
|
||||
|
||||
def self.get_account_by_id(id)
|
||||
accounts = load_accounts
|
||||
accounts.select { |acc| acc['id'] == id }[0]
|
||||
end
|
||||
|
||||
# Default account on the user computer.
|
||||
def self.default_account
|
||||
accounts = load_accounts
|
||||
accounts.select { |acc| acc['isDefault'] }[0] || accounts[0]
|
||||
end
|
||||
|
||||
# Try to get local server account for debug/test purposes.
|
||||
def self.try_get_local_server_account
|
||||
accounts = load_accounts
|
||||
accounts.select { |acc| acc['serverInfo']['url'].include?('localhost') }[0] || nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'action'
|
||||
require_relative 'deactivate_diffing'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Deactivate diffing for stream.
|
||||
class ActivateDiffing < Action
|
||||
def initialize(stream_id)
|
||||
super()
|
||||
@stream_id = stream_id
|
||||
end
|
||||
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def update_state(state)
|
||||
state = DeactivateDiffing.update_state(state, nil, {})
|
||||
puts "Diffing activated for #{@stream_id}"
|
||||
speckle_entities = state.speckle_state.speckle_entities
|
||||
invalid_speckle_entities = speckle_entities.select do |_id, entity|
|
||||
entity.invalid_stream_ids.include?(@stream_id) && entity.sketchup_entity.is_a?(Sketchup::Face)
|
||||
end
|
||||
invalid_speckle_entities.each do |id, entity|
|
||||
new_entity = entity.activate_diffing(@stream_id, state.sketchup_state.materials.by_id(MAT_EDIT))
|
||||
speckle_entities = speckle_entities.put(id, new_entity)
|
||||
end
|
||||
new_speckle_state = state.speckle_state.with_speckle_entities(speckle_entities)
|
||||
state.with_speckle_state(new_speckle_state)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,52 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'action'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Adds material to speckle state and Sketchup.
|
||||
class AddMaterial < Action
|
||||
def self.update_state(state, material_name:, color:, material_id:, alpha: nil)
|
||||
materials = state.sketchup_state.materials
|
||||
existing_material = materials.by_id(material_id)
|
||||
return state if existing_material&.valid?
|
||||
|
||||
new_material = create_or_get_material(state.sketchup_state.sketchup_model,
|
||||
material_name,
|
||||
color,
|
||||
material_id,
|
||||
alpha: alpha)
|
||||
new_materials = materials.add_material(material_id, new_material)
|
||||
new_sketchup_state = state.sketchup_state.with(:@materials => new_materials)
|
||||
state.with(:@sketchup_state => new_sketchup_state)
|
||||
end
|
||||
|
||||
def self.create_or_get_material(model, material_name, color, material_id, alpha: nil)
|
||||
materials = model.materials
|
||||
existing_material = materials.find { |mat| mat.name == material_name }
|
||||
return existing_material if existing_material&.valid?
|
||||
|
||||
existing_material = materials.add material_name
|
||||
existing_material.set_attribute(MAT_DICTIONARY, MAT_ID, material_id.to_s)
|
||||
set_hex_color(existing_material, color)
|
||||
existing_material.alpha = alpha if alpha
|
||||
existing_material
|
||||
end
|
||||
|
||||
def self.set_hex_color(skp_material, hex_value)
|
||||
hex_value = hex_value.to_s
|
||||
col_blue, col_green, col_red = parse_hex_color(hex_value)
|
||||
skp_material.color = col_red, col_green, col_blue
|
||||
end
|
||||
|
||||
def self.parse_hex_color(hex_value)
|
||||
split_values = hex_value.match(/^#([a-fA-F\d]{2})([a-fA-F\d]{2})([a-fA-F\d]{2})$/) ||
|
||||
hex_value.match(/^#([a-fA-F\d])([a-fA-F\d])([a-fA-F\d])$/)
|
||||
col_red = split_values[1].hex
|
||||
col_green = split_values[2].hex
|
||||
col_blue = split_values[3].hex
|
||||
return col_blue, col_green, col_red
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,73 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'action'
|
||||
require_relative 'mapped_entities_updated'
|
||||
require_relative 'events/selection_event_action'
|
||||
require_relative '../sketchup_model/dictionary/speckle_schema_dictionary_handler'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Apply mappings for selected entities.
|
||||
class ApplyMappings < Action
|
||||
def initialize(entities_to_map, method, category, family,
|
||||
family_type, level, name, is_definition)
|
||||
super()
|
||||
@entities_to_map = entities_to_map
|
||||
@method = method
|
||||
@category = category
|
||||
@name = name
|
||||
@family = family
|
||||
@family_type = family_type
|
||||
@level = level
|
||||
@is_definition = is_definition
|
||||
end
|
||||
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
# rubocop:disable Metrics/AbcSize
|
||||
# rubocop:disable Metrics/CyclomaticComplexity
|
||||
# rubocop:disable Metrics/PerceivedComplexity
|
||||
# rubocop:disable Metrics/MethodLength
|
||||
def update_state(state)
|
||||
sketchup_model = state.sketchup_state.sketchup_model
|
||||
entities = if sketchup_model.active_path.nil?
|
||||
sketchup_model.entities
|
||||
else
|
||||
sketchup_model.active_path.last.definition.entities
|
||||
end
|
||||
|
||||
# Collect entities from entity ids that comes from UI as list
|
||||
entities_to_map = entities.select { |e| @entities_to_map.include?(e.persistent_id) }
|
||||
|
||||
# Switch to definitions if all entities are component instance and UI flag shows that
|
||||
if entities_to_map.all? { |e| e.is_a?(Sketchup::ComponentInstance) } && @is_definition
|
||||
entities_to_map = entities_to_map.collect(&:definition).uniq
|
||||
end
|
||||
|
||||
# Store speckle state to update with mapped entities.
|
||||
speckle_state = state.speckle_state
|
||||
entities_to_map.each do |entity|
|
||||
name = if @name == '<Mixed>'
|
||||
entity.respond_to?(:name) ? entity.name : ''
|
||||
else
|
||||
@name
|
||||
end
|
||||
SketchupModel::Dictionary::SpeckleSchemaDictionaryHandler.set_attribute(entity, :category, @category)
|
||||
SketchupModel::Dictionary::SpeckleSchemaDictionaryHandler.set_attribute(entity, :name, name)
|
||||
SketchupModel::Dictionary::SpeckleSchemaDictionaryHandler.set_attribute(entity, :method, @method)
|
||||
SketchupModel::Dictionary::SpeckleSchemaDictionaryHandler.set_attribute(entity, :family, @family)
|
||||
SketchupModel::Dictionary::SpeckleSchemaDictionaryHandler.set_attribute(entity, :family_type, @family_type)
|
||||
SketchupModel::Dictionary::SpeckleSchemaDictionaryHandler.set_attribute(entity, :level, @level)
|
||||
speckle_state = speckle_state.with_mapped_entity(entity)
|
||||
end
|
||||
|
||||
new_state = MappedEntitiesUpdated.update_state(state.with_speckle_state(speckle_state))
|
||||
Events::SelectionEventAction.update_state(new_state, { apply: true })
|
||||
end
|
||||
# rubocop:enable Metrics/AbcSize
|
||||
# rubocop:enable Metrics/CyclomaticComplexity
|
||||
# rubocop:enable Metrics/PerceivedComplexity
|
||||
# rubocop:enable Metrics/MethodLength
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,47 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../action'
|
||||
require_relative '../../cards/send_card'
|
||||
require_relative '../../cards/receive_card'
|
||||
require_relative '../../filters/send/everything_filter'
|
||||
require_relative '../../filters/send/selection_filter'
|
||||
require_relative '../../filters/send_filters'
|
||||
require_relative '../../sketchup_model/dictionary/model_card_dictionary_handler'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Action to add send card.
|
||||
class AddModel < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, resolve_id, data)
|
||||
if data['typeDiscriminator'] == 'ReceiverModelCard'
|
||||
receive_card = Cards::ReceiveCard.new(data['id'], data['accountId'],
|
||||
data['projectId'], data['projectName'],
|
||||
data['modelId'], data['modelName'],
|
||||
data['referencedObject'])
|
||||
SketchupModel::Dictionary::ModelCardDictionaryHandler
|
||||
.save_card_to_model(receive_card, state.sketchup_state.sketchup_model)
|
||||
new_speckle_state = state.speckle_state.with_receive_card(receive_card)
|
||||
state = state.with_speckle_state(new_speckle_state)
|
||||
js_script = "baseBinding.receiveResponse('#{resolve_id}')"
|
||||
return state.with_add_queue_js_command('addSendCard', js_script)
|
||||
end
|
||||
|
||||
send_filter = Filters::SendFilters.get_filter_from_ui_data(data['sendFilter'])
|
||||
# Init card and add to the state
|
||||
send_card = Cards::SendCard.new(data['id'], data['accountId'], data['projectId'], data['modelId'],
|
||||
send_filter, {})
|
||||
|
||||
SketchupModel::Dictionary::ModelCardDictionaryHandler
|
||||
.save_card_to_model(send_card, state.sketchup_state.sketchup_model)
|
||||
|
||||
new_speckle_state = state.speckle_state.with_send_card(send_card)
|
||||
state = state.with_speckle_state(new_speckle_state)
|
||||
# Resolve promise
|
||||
js_script = "baseBinding.receiveResponse('#{resolve_id}')"
|
||||
state.with_add_queue_js_command('addSendCard', js_script)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,30 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../action'
|
||||
require_relative '../../cards/send_card'
|
||||
require_relative '../../filters/send_filters'
|
||||
require_relative '../../sketchup_model/dictionary/model_card_dictionary_handler'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Add model to document state.
|
||||
class AddModelToDocumentState < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, resolve_id, model)
|
||||
puts model.to_json
|
||||
|
||||
send_filter = Filters::SendFilters.get_filter_from_ui_data(model['sendFilter'])
|
||||
|
||||
send_card = Cards::SendCard.new(model['id'], model['accountId'], model['projectId'], model['modelId'], send_filter, {})
|
||||
SketchupModel::Dictionary::ModelCardDictionaryHandler
|
||||
.save_card_to_model(send_card, state.sketchup_state.sketchup_model)
|
||||
new_speckle_state = state.speckle_state.with_send_card(send_card)
|
||||
state = state.with_speckle_state(new_speckle_state)
|
||||
|
||||
js_script = "baseBinding.receiveResponse('#{resolve_id}')"
|
||||
state.with_add_queue_js_command('addModelToDocumentState', js_script)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,40 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../action'
|
||||
require_relative '../../filters/send_filters'
|
||||
require_relative '../../sketchup_model/dictionary/model_card_dictionary_handler'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Gets document state.
|
||||
class GetDocumentState < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, resolve_id)
|
||||
send_cards_hash = SketchupModel::Dictionary::ModelCardDictionaryHandler
|
||||
.get_cards_from_dict(state.sketchup_state.sketchup_model)
|
||||
|
||||
send_cards = send_cards_hash.collect do |id, card|
|
||||
filter = Filters::SendFilters.get_filter_from_document(card['sendFilter'])
|
||||
send_card = Cards::SendCard.new(id, card['account_id'], card['project_id'], card['model_id'], filter, {})
|
||||
|
||||
new_speckle_state = state.speckle_state.with_send_card(send_card)
|
||||
state = state.with_speckle_state(new_speckle_state)
|
||||
{
|
||||
id: send_card.id,
|
||||
accountId: send_card.account_id,
|
||||
projectId: send_card.project_id,
|
||||
modelId: send_card.model_id,
|
||||
sendFilter: send_card.send_filter,
|
||||
typeDiscriminator: send_card.type_discriminator
|
||||
}
|
||||
end
|
||||
|
||||
model_state = { models: send_cards }
|
||||
|
||||
js_script = "baseBinding.receiveResponse('#{resolve_id}', #{model_state.to_json})"
|
||||
state.with_add_queue_js_command('getDocumentState', js_script)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,38 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../action'
|
||||
require_relative '../../filters/send_filters'
|
||||
require_relative '../../sketchup_model/dictionary/model_card_dictionary_handler'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Gets model state.
|
||||
class GetModelState < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, resolve_id)
|
||||
send_cards_hash = SketchupModel::Dictionary::ModelCardDictionaryHandler
|
||||
.get_cards_from_dict(state.sketchup_state.sketchup_model)
|
||||
|
||||
send_cards = send_cards_hash.collect do |id, card|
|
||||
filters = Filters::SendFilters.get_filters_from_model(card['filters'])
|
||||
send_card = Cards::SendCard.new(id, card['account_id'], card['project_id'], card['model_id'], filters)
|
||||
|
||||
new_speckle_state = state.speckle_state.with_send_card(send_card)
|
||||
state = state.with_speckle_state(new_speckle_state)
|
||||
{
|
||||
accountId: send_card.account_id,
|
||||
projectId: send_card.project_id,
|
||||
modelId: send_card.model_id,
|
||||
filters: send_card.filters
|
||||
}
|
||||
end
|
||||
|
||||
model_state = { sendCards: send_cards }
|
||||
|
||||
js_script = "baseBinding.receiveResponse('#{resolve_id}', #{model_state.to_json})"
|
||||
state.with_add_queue_js_command('getModelState', js_script)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,19 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../action'
|
||||
require_relative '../../filters/send_filters'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Action to get send filter.
|
||||
class GetSendFilters < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, resolve_id)
|
||||
default_filters = Filters::SendFilters.get_default(state.sketchup_state.sketchup_model)
|
||||
js_script = "sendBinding.receiveResponse('#{resolve_id}', #{default_filters.to_json})"
|
||||
state.with_add_queue_js_command('getSendFilter', js_script)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,17 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../action'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Get source app name.
|
||||
class GetSourceAppName < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, resolve_id)
|
||||
js_command = "baseBinding.receiveResponse('#{resolve_id}', 'Sketchup')"
|
||||
state.with_add_queue_js_command('getSourceAppName', js_command)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,17 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../action'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Get source app version.
|
||||
class GetSourceAppVersion < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, resolve_id)
|
||||
js_command = "baseBinding.receiveResponse('#{resolve_id}', #{SKETCHUP_VERSION})"
|
||||
state.with_add_queue_js_command('getSourceAppVersion', js_command)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,45 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../action'
|
||||
require_relative '../../sketchup_model/query/entity'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Action to add send card.
|
||||
class HighlightModel < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, resolve_id, model_card_id)
|
||||
# objects_to_highlight = if data['typeDiscriminator'] == 'ReceiverModelCard'
|
||||
# # model_card = state.speckle_state.receive_cards[model_card_id]
|
||||
# # TODO: return received objects
|
||||
# []
|
||||
# else
|
||||
# model_card = state.speckle_state.send_cards[model_card_id]
|
||||
# model_card.send_filter.selected_object_ids
|
||||
# end
|
||||
objects_to_highlight = state.speckle_state.send_cards[model_card_id].send_filter.selected_object_ids
|
||||
|
||||
state.sketchup_state.sketchup_model.selection.clear
|
||||
|
||||
# Flat entities to select entities on card
|
||||
flat_entities = SketchupModel::Query::Entity.flat_entities(state.sketchup_state.sketchup_model.entities)
|
||||
|
||||
flat_entities.each do |entity|
|
||||
next unless objects_to_highlight.include?(entity.persistent_id)
|
||||
|
||||
if entity.is_a?(Sketchup::ComponentDefinition)
|
||||
state.sketchup_state.sketchup_model.selection.add(entity.instances)
|
||||
end
|
||||
state.sketchup_state.sketchup_model.selection.add(entity)
|
||||
end
|
||||
|
||||
state.sketchup_state.sketchup_model.active_view.zoom(state.sketchup_state.sketchup_model.selection)
|
||||
|
||||
# Resolve promise
|
||||
js_script = "baseBinding.receiveResponse('#{resolve_id}')"
|
||||
state.with_add_queue_js_command('highlightModel', js_script)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,31 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../action'
|
||||
require_relative '../../cards/send_card'
|
||||
require_relative '../../cards/receive_card'
|
||||
require_relative '../../filters/send/everything_filter'
|
||||
require_relative '../../filters/send/selection_filter'
|
||||
require_relative '../../filters/send_filters'
|
||||
require_relative '../../sketchup_model/dictionary/model_card_dictionary_handler'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Action to remove send card.
|
||||
class RemoveModel < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, resolve_id, data)
|
||||
SketchupModel::Dictionary::ModelCardDictionaryHandler.remove_card_dict(state.sketchup_state.sketchup_model, data)
|
||||
new_speckle_state = if data['typeDiscriminator'] == 'ReceiverModelCard'
|
||||
state.speckle_state.without_receive_card(data['id'])
|
||||
else
|
||||
state.speckle_state.without_send_card(data['id'])
|
||||
end
|
||||
state = state.with_speckle_state(new_speckle_state)
|
||||
# Resolve promise
|
||||
js_script = "baseBinding.receiveResponse('#{resolve_id}')"
|
||||
state.with_add_queue_js_command('removeModel', js_script)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,20 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../action'
|
||||
require_relative '../../sketchup_model/dictionary/model_card_dictionary_handler'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Action to update send filter.
|
||||
class UpdateSendFilter < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, resolve_id, data, value)
|
||||
SketchupModel::Dictionary::ModelCardDictionaryHandler.update_filter(state.sketchup_state.sketchup_model, data, value)
|
||||
|
||||
js_script = "sendBinding.receiveResponse('#{resolve_id}')"
|
||||
state.with_add_queue_js_command('updateSendFilter', js_script)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,31 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'action'
|
||||
require_relative '../sketchup_model/dictionary/speckle_entity_dictionary_handler'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Clear mapper source.
|
||||
class ClearMapperSource < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, _resolve_id, _data)
|
||||
new_speckle_state = state.speckle_state.with_removed_mapper_source
|
||||
erase_levels(state)
|
||||
state.with_speckle_state(new_speckle_state)
|
||||
end
|
||||
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
def self.erase_levels(state)
|
||||
levels = state.sketchup_state.sketchup_model.definitions.select do |definition|
|
||||
SketchupModel::Dictionary::SpeckleEntityDictionaryHandler.get_attribute(definition, :speckle_type) ==
|
||||
OBJECTS_BUILTELEMENTS_REVIT_LEVEL
|
||||
end
|
||||
levels.each do |level|
|
||||
level.entities.clear!
|
||||
level.instances.each(&:erase!)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,52 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'action'
|
||||
require_relative 'mapped_entities_updated'
|
||||
require_relative 'events/selection_event_action'
|
||||
require_relative '../sketchup_model/dictionary/speckle_schema_dictionary_handler'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Clear mappings for selected entities.
|
||||
class ClearMappings < Action
|
||||
def initialize(entities_to_map, is_definition)
|
||||
super()
|
||||
@entities_to_map = entities_to_map
|
||||
@is_definition = is_definition
|
||||
end
|
||||
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
# rubocop:disable Metrics/CyclomaticComplexity
|
||||
# rubocop:disable Metrics/PerceivedComplexity
|
||||
def update_state(state)
|
||||
sketchup_model = state.sketchup_state.sketchup_model
|
||||
entities = if sketchup_model.active_path.nil?
|
||||
sketchup_model.entities
|
||||
else
|
||||
sketchup_model.active_path.last.definition.entities
|
||||
end
|
||||
|
||||
# Collect entities from entity ids that comes from UI as list
|
||||
entities_to_map = entities.select { |e| @entities_to_map.include?(e.persistent_id) }
|
||||
|
||||
# Switch to definitions if all entities are component instance and UI flag shows that
|
||||
if entities_to_map.all? { |e| e.is_a?(Sketchup::ComponentInstance) } && @is_definition
|
||||
entities_to_map = entities_to_map.collect(&:definition).uniq
|
||||
end
|
||||
|
||||
# Store speckle state to update with mapped entities.
|
||||
speckle_state = state.speckle_state
|
||||
entities_to_map.each do |entity|
|
||||
SketchupModel::Dictionary::SpeckleSchemaDictionaryHandler.remove_dictionary(entity)
|
||||
speckle_state = speckle_state.with_removed_mapped_entity(entity)
|
||||
end
|
||||
|
||||
new_state = MappedEntitiesUpdated.update_state(state.with_speckle_state(speckle_state))
|
||||
Events::SelectionEventAction.update_state(new_state, { clear: true })
|
||||
end
|
||||
# rubocop:enable Metrics/CyclomaticComplexity
|
||||
# rubocop:enable Metrics/PerceivedComplexity
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,34 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'action'
|
||||
require_relative 'mapped_entities_updated'
|
||||
require_relative 'events/selection_event_action'
|
||||
require_relative '../sketchup_model/dictionary/speckle_schema_dictionary_handler'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Clear mappings for selected entities from mapped elements table.
|
||||
class ClearMappingsFromTable < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, _resolve_id, data)
|
||||
# Flat entities to clear mappings
|
||||
flat_entities = SketchupModel::Query::Entity.flat_entities(state.sketchup_state.sketchup_model.entities)
|
||||
|
||||
# Collect entity ids to clear mappings
|
||||
entity_ids = data.collect { |_, entities| entities['selectedElements'].collect { |e| e['entityId'] } }.flatten
|
||||
# Store speckle state to update with mapped entities.
|
||||
speckle_state = state.speckle_state
|
||||
flat_entities.each do |entity|
|
||||
next unless entity_ids.include?(entity.persistent_id)
|
||||
|
||||
SketchupModel::Dictionary::SpeckleSchemaDictionaryHandler.remove_dictionary(entity)
|
||||
speckle_state = speckle_state.with_removed_mapped_entity(entity)
|
||||
end
|
||||
|
||||
new_state = MappedEntitiesUpdated.update_state(state.with_speckle_state(speckle_state))
|
||||
Events::SelectionEventAction.update_state(new_state, { clear: true })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -10,7 +10,7 @@ module SpeckleConnector
|
||||
class CollectPreferences < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, _data)
|
||||
def self.update_state(state, _resolve_id, _data)
|
||||
state.with_add_queue('collectPreferences', state.user_state.preferences.to_json, [])
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'action'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Action to collect versions from sketchup and connector to track user's version by mixpanel.
|
||||
class CollectVersions < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, _resolve_id, _data)
|
||||
versions = {
|
||||
sketchup: Sketchup.version.to_i,
|
||||
speckle: SpeckleConnector::CONNECTOR_VERSION
|
||||
}
|
||||
state.with_add_queue('collectVersions', versions.to_json, [])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,22 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../action'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Action to get config.
|
||||
class GetConfig < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, resolve_id)
|
||||
# Previously it was stored in user state
|
||||
# config = state.user_state.preferences.to_json
|
||||
config = {
|
||||
darkTheme: state.user_state.user_preferences[:dark_theme]
|
||||
}
|
||||
js_script = "configBinding.receiveResponse('#{resolve_id}', #{config.to_json})"
|
||||
state.with_add_queue_js_command('getConfig', js_script)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,26 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../action'
|
||||
require_relative '../user_preferences_updated'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Action to update config.
|
||||
class UpdateConfig < Action
|
||||
KEY_VALUES = {
|
||||
'darkTheme' => 'dark_theme'
|
||||
}.freeze
|
||||
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, resolve_id, config)
|
||||
config.each do |key, value|
|
||||
state = Actions::UserPreferencesUpdated.new('configSketchup', KEY_VALUES[key], value).update_state(state)
|
||||
end
|
||||
|
||||
js_script = "configBinding.receiveResponse('#{resolve_id}')"
|
||||
state.with_add_queue_js_command('updateConfig', js_script)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,26 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'action'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Deactivate diffing.
|
||||
class DeactivateDiffing < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, _resolve_id, _data)
|
||||
puts 'Diffing deactivated!'
|
||||
speckle_entities = state.speckle_state.speckle_entities
|
||||
diffing_activated_speckle_entities = speckle_entities.reject do |_id, entity|
|
||||
entity.active_diffing_stream_id.nil?
|
||||
end
|
||||
diffing_activated_speckle_entities.each do |id, entity|
|
||||
new_entity = entity.deactivate_diffing
|
||||
speckle_entities = speckle_entities.put(id, new_entity)
|
||||
end
|
||||
new_speckle_state = state.speckle_state.with_speckle_entities(speckle_entities)
|
||||
state.with_speckle_state(new_speckle_state)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,58 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'event_action'
|
||||
require_relative 'on_document_changed'
|
||||
require_relative '../load_sketchup_model'
|
||||
require_relative '../collect_preferences'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
module Events
|
||||
# Handle events that are triggered by the {AppObserver}.
|
||||
class AppEventAction < EventAction
|
||||
# Handle loading new or existing model
|
||||
class OnNewOrChangedModel
|
||||
# Handle events when the new or existing model is loaded in Sketchup
|
||||
# @param state [States::State] the current state of speckle application
|
||||
# @param event_data [Array<(Sketchup::Model)>] the event data for the given event. It consists of
|
||||
# a double array with a single element that is the {Sketchup::Model} object of the loaded model.
|
||||
def self.update_state(state, event_data)
|
||||
return state unless event_data&.any?
|
||||
|
||||
model = event_data.flatten.first
|
||||
# LoadSketchupModel action should be responsible to update all model specific data for state and then
|
||||
# should notify the UI to update it's components.
|
||||
new_state = Actions::LoadSketchupModel.update_state(state, model)
|
||||
# Action to let UI to render itself with new preferences state
|
||||
# TODO: Later UI should be updated if any stream is invalid after
|
||||
# we collected speckle_entities appropriately
|
||||
new_state = CollectPreferences.update_state(new_state, nil, {})
|
||||
OnDocumentChanged.update_state(new_state)
|
||||
end
|
||||
end
|
||||
|
||||
# Run actions that are needed before the sketchup quits
|
||||
class OnQuit
|
||||
# Handle when Sketchup application closes
|
||||
# @param state [States::State] the current state of speckle application
|
||||
# @param _event_data [Array] the event data
|
||||
# @return [States::State] the transformed state object
|
||||
def self.update_state(state, _event_data)
|
||||
state
|
||||
end
|
||||
end
|
||||
|
||||
# Handlers that are used to handle specific events
|
||||
ACTIONS = {
|
||||
onNewModel: OnNewOrChangedModel,
|
||||
onOpenModel: OnNewOrChangedModel,
|
||||
onQuit: OnQuit
|
||||
}.freeze
|
||||
|
||||
def self.actions
|
||||
ACTIONS
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,89 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'event_action'
|
||||
require_relative '../../actions/send_actions/send_card_expiration_check'
|
||||
require_relative '../../sketchup_model/utils/face_utils'
|
||||
require_relative '../../constants/dict_constants'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
module Events
|
||||
# Event actions related to entities.
|
||||
class EntitiesEventAction < EventAction
|
||||
# Event action when element added.
|
||||
class OnElementAdded
|
||||
# @param state [States::State] the current state of the SpeckleConnector Application
|
||||
def self.update_state(state, event_data)
|
||||
modified_entities = event_data.to_a.collect { |e| e[1] }
|
||||
# do not copy speckle base object specific attributes, because they are entity specific
|
||||
modified_entities.each { |entity| entity.delete_attribute(SPECKLE_BASE_OBJECT) }
|
||||
state
|
||||
end
|
||||
end
|
||||
|
||||
# Event action when element modified.
|
||||
class OnElementModified
|
||||
# @param state [States::State] the current state of the SpeckleConnector Application
|
||||
def self.update_state(state, event_data)
|
||||
speckle_state = state.speckle_state
|
||||
modified_entity = event_data[0][1]
|
||||
modified_entities = event_data.collect { |data| data[1] }
|
||||
new_speckle_state = state.speckle_state.with_changed_object_ids(modified_entities.collect(&:persistent_id))
|
||||
state = state.with_speckle_state(new_speckle_state)
|
||||
state = Actions::SendCardExpirationCheck.update_state(state)
|
||||
# if modified_entity.is_a?(Sketchup::Face)
|
||||
# path = state.sketchup_state.sketchup_model.active_path
|
||||
# modified_faces = SketchupModel::Utils::FaceUtils.near_faces(modified_entity.edges)
|
||||
# path_objects = path.nil? ? [] : path + path.collect(&:definition)
|
||||
# parent_ids = path_objects.collect(&:persistent_id)
|
||||
# ids_to_invalidate = modified_faces.collect(&:persistent_id) + parent_ids
|
||||
# entities_to_invalidate = speckle_entities_to_invalidate(speckle_state, ids_to_invalidate)
|
||||
# new_speckle_state = invalidate_speckle_entities(speckle_state, entities_to_invalidate)
|
||||
# # This is the place we can send information to UI for diffing check
|
||||
# diffing = state.user_state.preferences[:user][:diffing]
|
||||
# new_speckle_state = new_speckle_state.with_invalid_streams_queue if diffing
|
||||
# return state.with_speckle_state(new_speckle_state)
|
||||
# end
|
||||
|
||||
state
|
||||
end
|
||||
|
||||
# @param speckle_state [States::SpeckleState] the current state of the Speckle
|
||||
def self.speckle_entities_to_invalidate(speckle_state, ids)
|
||||
speckle_state.speckle_entities.to_h.select { |id, _| ids.include?(id) }
|
||||
end
|
||||
|
||||
# @param speckle_state [States::SpeckleState] the current state of the Speckle
|
||||
def self.invalidate_speckle_entities(speckle_state, entities_to_invalidate)
|
||||
speckle_entities = speckle_state.speckle_entities
|
||||
entities_to_invalidate.each do |id, speckle_entity|
|
||||
edited_speckle_entity = speckle_entity.with_invalid
|
||||
speckle_entities = speckle_entities.put(id, edited_speckle_entity)
|
||||
end
|
||||
speckle_state.with_speckle_entities(speckle_entities)
|
||||
end
|
||||
end
|
||||
|
||||
# Event action when element removed.
|
||||
class OnElementRemoved
|
||||
# @param state [States::State] the current state of the SpeckleConnector Application
|
||||
def self.update_state(state, _event_data)
|
||||
# TODO: Do state updates when element removed
|
||||
state
|
||||
end
|
||||
end
|
||||
|
||||
# Handlers that are used to handle specific events
|
||||
ACTIONS = {
|
||||
onElementRemoved: OnElementRemoved,
|
||||
onElementAdded: OnElementAdded,
|
||||
onElementModified: OnElementModified
|
||||
}.freeze
|
||||
|
||||
def self.actions
|
||||
ACTIONS
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,34 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# This module contains actions that are performed to handle events triggered by observers in Sketchup.
|
||||
module Events
|
||||
# Base action for Handling events
|
||||
class EventAction
|
||||
def self.actions
|
||||
raise NoMethodError, 'Implement in a subclass'
|
||||
end
|
||||
|
||||
# Handle the events that were collected by the observer. In case of the selection observer,
|
||||
# we only need to handle the events once if any of the events actually happened.
|
||||
# @param state [States::State] the current state of the SpeckleConnector Application
|
||||
# @param events [Hash{Symbol=>Array}] the event data grouped by the event name
|
||||
# @return [States::State] the transformed state
|
||||
def self.update_state(state, events)
|
||||
# Don't do anything if there are no events for this action
|
||||
return state unless events
|
||||
|
||||
actions = self.actions
|
||||
actions.each do |event_name, action|
|
||||
next unless events.key?(event_name)
|
||||
|
||||
event_data = events[event_name]
|
||||
state = action.update_state(state, event_data)
|
||||
end
|
||||
state
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,41 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'event_action'
|
||||
require_relative '../load_sketchup_model'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
module Events
|
||||
# Handle events that are triggered by the {ModelObserver}.
|
||||
class ModelEventAction < EventAction
|
||||
# Handle loading new or existing model
|
||||
class OnActivePathChanged
|
||||
# Handle events when the new or existing model is loaded in Sketchup
|
||||
# @param state [States::State] the current state of speckle application
|
||||
# @param event_data [Array<(Sketchup::Model)>] the event data for the given event. It consists of
|
||||
# a double array with a single element that is the {Sketchup::Model} object of the loaded model.
|
||||
def self.update_state(state, _event_data)
|
||||
sketchup_state = state.sketchup_state
|
||||
active_path = sketchup_state.sketchup_model.active_path
|
||||
observers = state.speckle_state.observers
|
||||
update_object_observers(active_path, observers)
|
||||
return state
|
||||
end
|
||||
|
||||
def self.update_object_observers(path, observers)
|
||||
path[-1].definition.entities.add_observer(observers[ENTITIES_OBSERVER]) unless path.nil?
|
||||
end
|
||||
end
|
||||
|
||||
# Handlers that are used to handle specific events
|
||||
ACTIONS = {
|
||||
onActivePathChanged: OnActivePathChanged
|
||||
}.freeze
|
||||
|
||||
def self.actions
|
||||
ACTIONS
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,15 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Triggers whenever document has changed.
|
||||
class OnDocumentChanged < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state)
|
||||
js_command = "baseBinding.emit('documentChanged')"
|
||||
state.with_add_queue_js_command('documentChanged', js_command)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,33 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'event_action'
|
||||
require_relative '../mapper_selection_changed'
|
||||
require_relative '../selection_actions/get_selection'
|
||||
require_relative '../../mapper/category/revit_category'
|
||||
require_relative '../../sketchup_model/reader/speckle_entities_reader'
|
||||
require_relative '../../sketchup_model/reader/mapper_reader'
|
||||
require_relative '../../sketchup_model/query/entity'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
module Events
|
||||
# Update selected speckle objects when the selection changes for mapper tool.
|
||||
class SelectionEventAction < EventAction
|
||||
# @param state [States::State] the current state of Speckle application.
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, event_data)
|
||||
return state unless event_data&.any?
|
||||
|
||||
# Get sketchup selection
|
||||
sketchup_selection = state.sketchup_state.sketchup_model.selection
|
||||
|
||||
Actions::GetSelection.update_state(state)
|
||||
|
||||
# Collect and return mapper selection info.
|
||||
# Later we can add more selection info for different scopes.
|
||||
# MapperSelectionChanged.new(sketchup_selection).update_state(state)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,21 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'action'
|
||||
require_relative '../accounts/accounts'
|
||||
require_relative 'load_saved_streams'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Action to initialize local accounts from database.
|
||||
class GetAccounts < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, resolve_id)
|
||||
puts 'Initialisation of Speckle accounts requested by plugin'
|
||||
accounts_data = state.speckle_state.accounts
|
||||
js_script = "accountsBinding.receiveResponse('#{resolve_id}', #{accounts_data.to_json})"
|
||||
state.with_add_queue_js_command('getAccounts', js_script)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,22 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'action'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Get document info.
|
||||
class GetDocumentInfo < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, resolve_id)
|
||||
document_info = {
|
||||
location: state.sketchup_state.sketchup_model.path,
|
||||
name: state.sketchup_state.sketchup_model.name,
|
||||
id: state.sketchup_state.sketchup_model.guid
|
||||
}
|
||||
js_command = "baseBinding.receiveResponse('#{resolve_id}', #{document_info.to_json})"
|
||||
state.with_add_queue_js_command('getDocumentInfo', js_command)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,31 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Action to return error message to UI.
|
||||
class HandleError < Action
|
||||
# @param error [String] error
|
||||
# @param view_name [String] name of the view (binding)
|
||||
# @param action [Action] action that error happened
|
||||
# @param parameters [Array<String>] arguments
|
||||
def initialize(error, view_name, action, parameters)
|
||||
super()
|
||||
@error = error
|
||||
@view_name = view_name
|
||||
@action = action
|
||||
@args = parameters
|
||||
end
|
||||
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def update_state(state)
|
||||
error_message = "Error: #{@error}\nBinding: #{@view_name}\nAction:#{@action}\nArgs: #{@args}\n"
|
||||
error = {
|
||||
error: error_message
|
||||
}
|
||||
js_error_script = "#{@view_name}.receiveResponse('#{@args.first}', #{error.to_json})"
|
||||
state.with_add_queue_js_command("error_#{@view_name}", js_error_script)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,36 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'action'
|
||||
require_relative 'events/selection_event_action'
|
||||
require_relative '../sketchup_model/dictionary/speckle_schema_dictionary_handler'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Hide entities that selected from mapped elements table.
|
||||
class HideMappingsFromTable < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, _resolve_id, data)
|
||||
# Flat entities to clear mappings
|
||||
flat_entities = SketchupModel::Query::Entity.flat_entities(state.sketchup_state.sketchup_model.entities)
|
||||
|
||||
# Collect entity ids to clear mappings
|
||||
entity_ids = data.collect { |_, entities| entities['selectedElements'].collect { |e| e['entityId'] } }.flatten
|
||||
|
||||
# Store speckle state to update with mapped entities.
|
||||
flat_entities.each do |entity|
|
||||
next unless entity_ids.include?(entity.persistent_id)
|
||||
|
||||
if entity.is_a?(Sketchup::ComponentDefinition)
|
||||
entity.instances.each do |instance|
|
||||
instance.hidden = true
|
||||
end
|
||||
end
|
||||
entity.hidden = true
|
||||
end
|
||||
|
||||
Events::SelectionEventAction.update_state(state, { clear: true })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -10,7 +10,7 @@ module SpeckleConnector
|
||||
class InitLocalAccounts < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, _data)
|
||||
def self.update_state(state, _request_id, _data)
|
||||
puts 'Initialisation of Speckle accounts requested by plugin'
|
||||
accounts_data = state.speckle_state.accounts
|
||||
state.with_add_queue('loadAccounts', accounts_data.to_json, [])
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'action'
|
||||
require_relative 'add_material'
|
||||
require_relative '../constants/mat_constants'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Action to initialize materials
|
||||
class InitializeMaterials < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state)
|
||||
new_state = recreate_material(state, DEFAULT_NAMES[MAT_ADD], DEFAULT_COLORS[MAT_ADD], MAT_ADD)
|
||||
new_state = recreate_material(new_state, DEFAULT_NAMES[MAT_EDIT], DEFAULT_COLORS[MAT_EDIT], MAT_EDIT)
|
||||
recreate_material(new_state, DEFAULT_NAMES[MAT_REMOVE], DEFAULT_COLORS[MAT_REMOVE], MAT_REMOVE)
|
||||
end
|
||||
|
||||
def self.recreate_material(state, name, color, id, alpha: nil)
|
||||
Actions::AddMaterial.update_state(
|
||||
state,
|
||||
material_name: name,
|
||||
color: color,
|
||||
material_id: id,
|
||||
alpha: alpha
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -6,6 +6,8 @@ require_relative '../states/speckle_state'
|
||||
require_relative '../states/sketchup_state'
|
||||
require_relative '../accounts/accounts'
|
||||
require_relative '../preferences/preferences'
|
||||
require_relative '../constants/observer_constants'
|
||||
require_relative '../ext/worker'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
@@ -13,14 +15,23 @@ module SpeckleConnector
|
||||
class InitializeSpeckle < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state)
|
||||
def self.update_state(state, observers, instant_message_sender)
|
||||
worker = SpeckleConnector::Worker.new()
|
||||
attach_app_observer!(observers[APP_OBSERVER])
|
||||
accounts = SpeckleConnector::Accounts.load_accounts
|
||||
speckle_state = States::SpeckleState.new(accounts, {}, {})
|
||||
speckle_state = States::SpeckleState.new(accounts, observers, {}, {})
|
||||
# This should be the only point that `Sketchup_active_model` passed to application state.
|
||||
sketchup_state = States::SketchupState.new(Sketchup.active_model)
|
||||
preferences = Preferences.init_preferences(sketchup_state.sketchup_model)
|
||||
preferences = Preferences.read_preferences(sketchup_state.sketchup_model)
|
||||
user_state_with_preferences = state.user_state.with_preferences(preferences)
|
||||
States::State.new(user_state_with_preferences, speckle_state, sketchup_state, false)
|
||||
state = States::State.new(user_state_with_preferences, speckle_state, sketchup_state, false,
|
||||
worker, &instant_message_sender)
|
||||
# This is where we attach observers to related model objects like selection, entities..
|
||||
Actions::LoadSketchupModel.update_state(state, sketchup_state.sketchup_model)
|
||||
end
|
||||
|
||||
def self.attach_app_observer!(observer)
|
||||
Sketchup.add_observer(observer)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'action'
|
||||
require_relative 'events/selection_event_action'
|
||||
require_relative '../sketchup_model/dictionary/speckle_schema_dictionary_handler'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Isolate entities that selected from mapped elements table.
|
||||
class IsolateMappingsFromTable < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
# rubocop:disable Metrics/AbcSize
|
||||
# rubocop:disable Metrics/MethodLength
|
||||
# rubocop:disable Metrics/PerceivedComplexity
|
||||
# rubocop:disable Metrics/CyclomaticComplexity
|
||||
def self.update_state(state, _resolve_id, data)
|
||||
sketchup_model = state.sketchup_state.sketchup_model
|
||||
|
||||
# Hide all entities first
|
||||
sketchup_model.entities.each do |ent|
|
||||
ent.hidden = true
|
||||
end
|
||||
|
||||
# Flat entities to isolate mappings
|
||||
flat_entities = SketchupModel::Query::Entity.flat_entities(sketchup_model.entities)
|
||||
|
||||
comp_flat_entities = flat_entities.grep(Sketchup::ComponentInstance) + flat_entities.grep(Sketchup::Group) +
|
||||
flat_entities.grep(Sketchup::ComponentDefinition)
|
||||
face_edge_flat_entities = flat_entities.grep(Sketchup::Face) + flat_entities.grep(Sketchup::Edge)
|
||||
|
||||
# Collect entity ids to clear mappings
|
||||
selected_elements = data.collect { |_, entities| entities['selectedElements'] }.flatten
|
||||
|
||||
comps_or_groups, faces_or_edges = selected_elements.partition do |e|
|
||||
e['entityType'] == 'Component' || e['entityType'] == 'Definition' || e['entityType'] == 'Group'
|
||||
end
|
||||
|
||||
faces_or_edges_ids = faces_or_edges.collect { |e| e['entityId'] }
|
||||
|
||||
face_edge_flat_entities.select { |e| faces_or_edges_ids.include?(e.persistent_id) }.each do |entity|
|
||||
entity.hidden = false
|
||||
end
|
||||
|
||||
comps_or_groups_ids = comps_or_groups.collect { |e| e['entityId'] }
|
||||
|
||||
comp_flat_entities.select { |e| comps_or_groups_ids.include?(e.persistent_id) }.each do |entity|
|
||||
if entity.is_a?(Sketchup::ComponentDefinition)
|
||||
entity.instances.each do |instance|
|
||||
instance.hidden = false
|
||||
end
|
||||
end
|
||||
entity.hidden = false
|
||||
end
|
||||
|
||||
Events::SelectionEventAction.update_state(state, { clear: true })
|
||||
end
|
||||
# rubocop:enable Metrics/AbcSize
|
||||
# rubocop:enable Metrics/MethodLength
|
||||
# rubocop:enable Metrics/PerceivedComplexity
|
||||
# rubocop:enable Metrics/CyclomaticComplexity
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -8,8 +8,9 @@ module SpeckleConnector
|
||||
class LoadSavedStreams < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, _data)
|
||||
(saved_streams = state.sketchup_state.sketchup_model.attribute_dictionary('speckle', true)['streams']) or []
|
||||
def self.update_state(state, _request_id, _data)
|
||||
(saved_streams = state.sketchup_state.sketchup_model
|
||||
.attribute_dictionary('Speckle', true)['saved_streams']) or []
|
||||
state.with_add_queue('setSavedStreams', saved_streams, [])
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'action'
|
||||
require_relative 'initialize_materials'
|
||||
require_relative '../sketchup_model/reader/speckle_entities_reader'
|
||||
require_relative '../sketchup_model/reader/mapper_reader'
|
||||
require_relative '../preferences/preferences'
|
||||
require_relative '../states/state'
|
||||
require_relative '../states/sketchup_state'
|
||||
require_relative '../constants/observer_constants'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Switch sketchup model wit a new one
|
||||
class LoadSketchupModel < Action
|
||||
# Replace current model state with the state of a new model. This action is triggered when user opens new or
|
||||
# existing Sketchup model.
|
||||
# @param state [States::State] the current state of Speckle
|
||||
# @param additional_parameters [Array] parameters that the action takes
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, sketchup_model)
|
||||
# Init sketchup state again with new model
|
||||
new_sketchup_state = States::SketchupState.new(sketchup_model)
|
||||
sketchup_model.rendering_options['DisplaySectionPlanes'] = true
|
||||
new_state = state.with(:@sketchup_state => new_sketchup_state)
|
||||
# Init materials again
|
||||
new_state = InitializeMaterials.update_state(new_state)
|
||||
|
||||
# Read speckle entities
|
||||
new_speckle_entities = SketchupModel::Reader::SpeckleEntitiesReader.read(sketchup_model.entities)
|
||||
new_speckle_state = new_state.speckle_state.with_speckle_entities(Immutable::Hash.new(new_speckle_entities))
|
||||
# Read mapped entities
|
||||
new_mapped_entities = SketchupModel::Reader::MapperReader.read_mapped_entities(sketchup_model.entities)
|
||||
new_speckle_state = new_speckle_state.with_mapped_entities(Immutable::Hash.new(new_mapped_entities))
|
||||
new_state = new_state.with_speckle_state(new_speckle_state)
|
||||
|
||||
# Read preferences from database and model.
|
||||
preferences = Preferences.read_preferences(new_state.sketchup_state.sketchup_model)
|
||||
new_user_state = new_state.user_state.with_preferences(preferences)
|
||||
new_state = new_state.with(:@user_state => new_user_state)
|
||||
attach_observers(sketchup_model, new_state.speckle_state.observers)
|
||||
new_state
|
||||
end
|
||||
|
||||
# Attach observers to the sketchup model
|
||||
# @param sketchup_model [Sketchup::Model] the model to attach observers to
|
||||
# @param observers [Hash{Class=>}] the observer objects indexed by their class that will be attached
|
||||
def self.attach_observers(sketchup_model, observers)
|
||||
selection = sketchup_model.selection
|
||||
selection.add_observer(observers[SELECTION_OBSERVER])
|
||||
# layers = sketchup_model.layers
|
||||
# layers.add_observer(observers[LAYERS_OBSERVER_NAME])
|
||||
entities = sketchup_model.entities
|
||||
entities.add_observer(observers[ENTITIES_OBSERVER])
|
||||
sketchup_model.add_observer(observers[MODEL_OBSERVER])
|
||||
# materials = sketchup_model.materials
|
||||
# materials.add_observer(observers[MATERIALS_OBSERVER_NAME])
|
||||
# pages = sketchup_model.pages
|
||||
# pages.add_observer(observers[PAGES_OBSERVER_NAME])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,20 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'action'
|
||||
require_relative '../sketchup_model/reader/mapper_reader'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Triggers when mapped entities updated.
|
||||
class MappedEntitiesUpdated < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, _resolve_id = nil, _data = nil)
|
||||
mapped_entities = SketchupModel::Reader::MapperReader
|
||||
.mapped_entity_details(state.speckle_state.speckle_mapper_state.mapped_entities.values.to_a)
|
||||
|
||||
state.with_mapped_entities_queue(mapped_entities)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,22 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'action'
|
||||
require_relative '../mapper/category/revit_category'
|
||||
require_relative '../mapper/category/revit_family_category'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Collects mapper selection info.
|
||||
class MapperInitialized < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, _data)
|
||||
init_parameters = {
|
||||
categories: Mapper::Category::RevitCategory.to_a,
|
||||
familyCategories: Mapper::Category::RevitFamilyCategory.to_a
|
||||
}.freeze
|
||||
state.with_mapper_init_queue(init_parameters)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,200 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'action'
|
||||
require_relative '../mapper/category/revit_category'
|
||||
require_relative '../mapper/category/revit_family_category'
|
||||
require_relative '../sketchup_model/reader/mapper_reader'
|
||||
require_relative '../sketchup_model/reader/speckle_entities_reader'
|
||||
require_relative '../sketchup_model/dictionary/speckle_entity_dictionary_handler'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Collects mapper selection info.
|
||||
class MapperSelectionChanged < Action
|
||||
READER = SketchupModel::Reader
|
||||
DICTIONARY = SketchupModel::Dictionary
|
||||
|
||||
def initialize(selection)
|
||||
super()
|
||||
@selection = selection
|
||||
end
|
||||
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def update_state(state)
|
||||
# Get mapping info from selection.
|
||||
mapping = get_mapping_info(state, @selection)
|
||||
|
||||
state.with_mapper_selection_queue(mapping)
|
||||
end
|
||||
|
||||
def filter_out_levels(selection)
|
||||
selection.reject do |e|
|
||||
DICTIONARY::SpeckleEntityDictionaryHandler
|
||||
.get_attribute(e, :speckle_type) == OBJECTS_BUILTELEMENTS_REVIT_LEVEL
|
||||
end
|
||||
end
|
||||
|
||||
def get_mapping_info(state, selection)
|
||||
source_exist = !state.speckle_state.speckle_mapper_state.mapper_source.nil?
|
||||
selection = filter_out_levels(selection)
|
||||
grouped_by_type = group_by_type(selection)
|
||||
|
||||
supported_entity_count = grouped_by_type.length
|
||||
|
||||
# Return empty method list if there is no supported entity to map.
|
||||
return EMPTY_SELECTION if supported_entity_count == 0
|
||||
|
||||
# Return Direct Shape itself if multiple kinds of element are selected like Edge and Face.
|
||||
# OR single type is equal to only direct shape supports.
|
||||
return multiple_supported_selection_info(selection) if supported_entity_count > 1
|
||||
|
||||
# FIXME: Distinguish selection info according to selection elegantly!!!
|
||||
if grouped_by_type.keys.first == Sketchup::ComponentInstance
|
||||
return component_selection_info(selection, source_exist)
|
||||
end
|
||||
|
||||
return group_selection_info(selection) if grouped_by_type.keys.first == Sketchup::Group
|
||||
|
||||
if supported_entity_count > 1 ||
|
||||
(supported_entity_count == 1 &&
|
||||
MAPPER_DIRECT_SHAPE_SUPPORTED_ENTITY_TYPES.include?(grouped_by_type.keys.first))
|
||||
if source_exist
|
||||
return direct_shape_selection_info_with_source(selection, [])
|
||||
else
|
||||
return direct_shape_selection_info(selection, source_exist)
|
||||
end
|
||||
end
|
||||
|
||||
# Only single type selections remained after this point.
|
||||
return face_selection_info(state, grouped_by_type.values.first) if grouped_by_type.keys.first == Sketchup::Face
|
||||
|
||||
return edge_selection_info(state, grouped_by_type.values.first) if grouped_by_type.keys.first == Sketchup::Edge
|
||||
|
||||
EMPTY_SELECTION
|
||||
end
|
||||
|
||||
MAPPER_SUPPORTED_ENTITY_TYPES = [
|
||||
Sketchup::ComponentInstance,
|
||||
Sketchup::Group,
|
||||
Sketchup::Face,
|
||||
Sketchup::Edge
|
||||
].freeze
|
||||
|
||||
MAPPER_DIRECT_SHAPE_SUPPORTED_ENTITY_TYPES = [
|
||||
Sketchup::ComponentInstance,
|
||||
Sketchup::Group
|
||||
].freeze
|
||||
|
||||
EMPTY_SELECTION = {
|
||||
selection: [],
|
||||
mappingMethods: []
|
||||
}.freeze
|
||||
|
||||
def multiple_supported_selection_info(selection)
|
||||
{
|
||||
selection: SketchupModel::Reader::MapperReader.entities_schema_details(selection),
|
||||
mappingMethods: ['Direct Shape']
|
||||
}.freeze
|
||||
end
|
||||
|
||||
def component_selection_info(selection, source_exist)
|
||||
if source_exist
|
||||
{
|
||||
selection: SketchupModel::Reader::MapperReader.entities_schema_details(selection),
|
||||
mappingMethods: ['Direct Shape', 'New Revit Family', 'Family Instance']
|
||||
}.freeze
|
||||
else
|
||||
{
|
||||
selection: SketchupModel::Reader::MapperReader.entities_schema_details(selection),
|
||||
mappingMethods: ['Direct Shape', 'New Revit Family']
|
||||
}.freeze
|
||||
end
|
||||
end
|
||||
|
||||
def group_selection_info(selection)
|
||||
{
|
||||
selection: SketchupModel::Reader::MapperReader.entities_schema_details(selection),
|
||||
mappingMethods: ['Direct Shape']
|
||||
}.freeze
|
||||
end
|
||||
|
||||
def direct_shape_selection_info(selection, source_exist)
|
||||
methods = ['Direct Shape', 'New Revit Family']
|
||||
methods.append('Family Instance') if source_exist
|
||||
{
|
||||
selection: SketchupModel::Reader::MapperReader.entities_schema_details(selection),
|
||||
mappingMethods: methods
|
||||
}.freeze
|
||||
end
|
||||
|
||||
def direct_shape_selection_info_with_default(selection, methods)
|
||||
{
|
||||
selection: SketchupModel::Reader::MapperReader.entities_schema_details(selection),
|
||||
mappingMethods: ['Direct Shape'] + methods
|
||||
}.freeze
|
||||
end
|
||||
|
||||
def direct_shape_selection_info_with_source(filtered_selection, methods)
|
||||
instances = @selection.grep(Sketchup::ComponentInstance)
|
||||
selected_level = instances.find do |i|
|
||||
DICTIONARY::SpeckleEntityDictionaryHandler
|
||||
.get_attribute(i, :speckle_type) == OBJECTS_BUILTELEMENTS_REVIT_LEVEL
|
||||
end
|
||||
selected_level_name = nil
|
||||
if selected_level
|
||||
selected_level_name = DICTIONARY::SpeckleEntityDictionaryHandler.get_attribute(selected_level, :name)
|
||||
end
|
||||
{
|
||||
selection: READER::MapperReader.entities_schema_details(filtered_selection),
|
||||
mappingMethods: ['Direct Shape'] + methods,
|
||||
categories: Mapper::Category::RevitCategory.to_a,
|
||||
selectedLevelName: selected_level_name
|
||||
}.freeze
|
||||
end
|
||||
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
def face_selection_info(state, faces)
|
||||
source_exist = !state.speckle_state.speckle_mapper_state.mapper_source.nil?
|
||||
grouped_by_verticality = faces.group_by { |face| face.normal.perpendicular?(VECTOR_Z) }
|
||||
return direct_shape_selection_info(faces, source_exist) if grouped_by_verticality.length == 2
|
||||
|
||||
if source_exist
|
||||
if grouped_by_verticality.keys.first
|
||||
direct_shape_selection_info_with_source(faces, ['Wall'])
|
||||
else
|
||||
direct_shape_selection_info_with_source(faces, ['Floor'])
|
||||
end
|
||||
else
|
||||
if grouped_by_verticality.keys.first
|
||||
direct_shape_selection_info_with_default(faces, ['Default Wall'])
|
||||
else
|
||||
direct_shape_selection_info_with_default(faces, ['Default Floor'])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def edge_selection_info(state, edges)
|
||||
source_exist = !state.speckle_state.speckle_mapper_state.mapper_source.nil?
|
||||
|
||||
if source_exist
|
||||
methods = ['Column', 'Beam', 'Pipe', 'Duct']
|
||||
direct_shape_selection_info_with_source(edges, methods)
|
||||
else
|
||||
default_methods = ['Default Column', 'Default Beam', 'Default Pipe', 'Default Duct']
|
||||
direct_shape_selection_info_with_default(edges, default_methods)
|
||||
end
|
||||
end
|
||||
|
||||
def group_by_type_old(selection)
|
||||
selection.group_by(&:class).filter_map do |group|
|
||||
[group.first, group] if MAPPER_SUPPORTED_ENTITY_TYPES.include?(group.first)
|
||||
end.to_h
|
||||
end
|
||||
|
||||
def group_by_type(selection)
|
||||
selection.select { |s| MAPPER_SUPPORTED_ENTITY_TYPES.include?(s.class) }.group_by(&:class)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,77 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'action'
|
||||
require_relative '../constants/type_constants'
|
||||
require_relative '../mapper/mapper_source'
|
||||
require_relative '../speckle_objects/built_elements/revit/revit_element_type'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Action to update mapper source.
|
||||
class MapperSourceUpdated < Action
|
||||
def initialize(base, stream_id, commit_id)
|
||||
super()
|
||||
@base = base
|
||||
@stream_id = stream_id
|
||||
@commit_id = commit_id
|
||||
end
|
||||
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def update_state(state)
|
||||
levels = convert_levels(state, @base['@Levels'])
|
||||
types = convert_types(@base['@Types'])
|
||||
family_instances = convert_family_instance_types(@base['@Types'])
|
||||
mapper_source = Mapper::MapperSource.new(@stream_id, @commit_id, levels, types)
|
||||
new_speckle_state = state.speckle_state.with_mapper_source(mapper_source)
|
||||
state = state.with_speckle_state(new_speckle_state)
|
||||
|
||||
state.with_add_queue('mapperSourceUpdated', @stream_id, [
|
||||
{ is_string: false, val: levels.to_json },
|
||||
{ is_string: false, val: types.to_json },
|
||||
{ is_string: false, val: family_instances.to_json }
|
||||
])
|
||||
end
|
||||
|
||||
def convert_types(types)
|
||||
types.collect do |type, type_elements|
|
||||
next if type_elements.nil? || !type_elements.is_a?(Array) || type == '__closure'
|
||||
|
||||
type = type[1..-1] if type[0] == '@'
|
||||
elements = type_elements.map do |type_element|
|
||||
SpeckleObjects::BuiltElements::Revit::RevitElementType.to_native(type_element)
|
||||
end
|
||||
elements = elements.group_by { |e| e[:family] }
|
||||
[type, elements]
|
||||
end.compact.to_h
|
||||
end
|
||||
|
||||
def convert_family_instance_types(types)
|
||||
family_instance_types = {}
|
||||
types.each do |type, type_elements|
|
||||
next if type_elements.nil? || !type_elements.is_a?(Array) || type == '__closure'
|
||||
|
||||
# skip type if there is no any revit symbol element type
|
||||
symbol_element_types = type_elements.select do |t|
|
||||
t['speckle_type'] == OBJECTS_BUILTELEMENTS_REVIT_REVITSYMBOLELEMENTTYPE &&
|
||||
t['placementType'] == 'OneLevelBased'
|
||||
end
|
||||
next if symbol_element_types.empty?
|
||||
|
||||
elements = type_elements.map do |type_element|
|
||||
SpeckleObjects::BuiltElements::Revit::RevitElementType.to_native(type_element)
|
||||
end
|
||||
elements = elements.group_by { |e| e[:family] }
|
||||
family_instance_types.merge!(elements)
|
||||
end
|
||||
family_instance_types
|
||||
end
|
||||
|
||||
def convert_levels(state, levels)
|
||||
levels.collect do |level|
|
||||
SpeckleObjects::BuiltElements::Level.to_native(state, level, @stream_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,35 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'action'
|
||||
require_relative 'events/app_event_action'
|
||||
require_relative 'events/entities_event_action'
|
||||
require_relative 'events/model_event_action'
|
||||
require_relative 'events/selection_event_action'
|
||||
require_relative '../constants/observer_constants'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Handle events that were collected by observers
|
||||
class OnEventsAction < Action
|
||||
RUN_ORDER = {
|
||||
APP_OBSERVER => Events::AppEventAction,
|
||||
ENTITIES_OBSERVER => Events::EntitiesEventAction,
|
||||
MODEL_OBSERVER => Events::ModelEventAction,
|
||||
# MATERIALS_OBSERVER => Events::MaterialsEventAction,
|
||||
# LAYERS_OBSERVER => Events::LayerEventAction,
|
||||
# PAGES_OBSERVER => Events::PagesEventAction,
|
||||
SELECTION_OBSERVER => Events::SelectionEventAction
|
||||
}.freeze
|
||||
|
||||
def self.update_state(state, events)
|
||||
RUN_ORDER.each do |observer_name, action|
|
||||
next unless events.key?(observer_name)
|
||||
|
||||
parameters = events[observer_name]
|
||||
state = action.update_state(state, parameters)
|
||||
end
|
||||
state
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,18 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../action'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Action to let sketchup know receive from server is finished..
|
||||
class AfterReceive < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, resolve_id, stream_id, root_id)
|
||||
puts "receive finished for: #{root_id}"
|
||||
js_script = "sketchupReceiveBinding.receiveResponse('#{resolve_id}')"
|
||||
state.with_add_queue_js_command('afterReceive', js_script)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,18 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../action'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Action to let sketchup know receive will be started.
|
||||
class BeforeReceive < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, resolve_id, stream_id, root_id)
|
||||
puts "receive started for: #{root_id}"
|
||||
js_script = "sketchupReceiveBinding.receiveResponse('#{resolve_id}')"
|
||||
state.with_add_queue_js_command('beforeReceive', js_script)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,91 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require 'json'
|
||||
|
||||
require_relative '../action'
|
||||
require_relative '../../convertors/units'
|
||||
require_relative '../../convertors/to_native'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Clear mappings for selected entities.
|
||||
class ReceiveSingleObject < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, resolve_id, stream_id, root_id, speckle_objects)
|
||||
puts "object receive #{speckle_objects.length}"
|
||||
buffer = speckle_objects.collect { |obj| [obj['id'], obj] }.to_h
|
||||
t_0 = Time.now.to_f
|
||||
root_obj = traverse_and_construct(speckle_objects.first, buffer)
|
||||
puts root_obj
|
||||
puts "Elapsed traverse and construct #{Time.now.to_f - t_0}"
|
||||
|
||||
# File.open("#{ENV['HOME']}/OneDrive/Masaüstü/root.json", 'w') do |f|
|
||||
# f.write(JSON.pretty_generate(root_obj))
|
||||
# end
|
||||
|
||||
# converter = Converters::ToNative.new(state, stream_id, 'test', 'testt', 'test')
|
||||
# state = converter.receive_commit_object(root_obj)
|
||||
|
||||
js_script = "sketchupReceiveBinding.receiveResponse('#{resolve_id}')"
|
||||
state.with_add_queue_js_command('receiveObject', js_script)
|
||||
end
|
||||
|
||||
def self.traverse_and_construct(obj, buffer)
|
||||
return if obj.nil?
|
||||
return obj if !obj.is_a?(Hash) && !obj.is_a?(Array)
|
||||
|
||||
# Handle arrays
|
||||
if obj.is_a?(Array) && !obj.empty?
|
||||
arr = handle_array(buffer, obj)
|
||||
|
||||
# De-chunk, if array is a set of datachunk, flat them into single data chunk.
|
||||
arr = try_dechunk(arr)
|
||||
|
||||
return arr
|
||||
end
|
||||
|
||||
# Handle object
|
||||
obj = handle_hash(buffer, obj)
|
||||
|
||||
return obj
|
||||
rescue StandardError => e
|
||||
puts "#{e} -> #{obj}"
|
||||
return nil
|
||||
end
|
||||
|
||||
def self.handle_array(buffer, obj)
|
||||
arr = []
|
||||
obj.collect do |element|
|
||||
next if element.nil?
|
||||
|
||||
deref = element.is_a?(Hash) && !element['referencedId'].nil? ? buffer[element['referencedId']] : element
|
||||
arr.append(traverse_and_construct(deref, buffer))
|
||||
end
|
||||
arr
|
||||
end
|
||||
|
||||
def self.try_dechunk(arr)
|
||||
if arr[0].is_a?(Hash) && !arr[0]['speckle_type'].nil? && arr[0]['speckle_type'].downcase.include?('datachunk')
|
||||
sum_arr = []
|
||||
arr.each do |chunk|
|
||||
sum_arr += chunk['data']
|
||||
end
|
||||
sum_arr
|
||||
else
|
||||
arr
|
||||
end
|
||||
end
|
||||
|
||||
def self.handle_hash(buffer, obj)
|
||||
obj.each do |prop, value|
|
||||
next if value.nil? || (!value.is_a?(Hash) && !value.is_a?(Array))
|
||||
|
||||
obj[prop] = buffer[value['referencedId']] if value.is_a?(Hash) && value['referencedId']
|
||||
obj[prop] = traverse_and_construct(obj[prop], buffer)
|
||||
end
|
||||
obj
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,26 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../action'
|
||||
require_relative '../../convertors/to_native'
|
||||
require_relative '../../ext/TT_Lib2/progressbar'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Receive from server.
|
||||
class AfterGetObjects < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, resolve_id, model_card_id, source_application, root_obj)
|
||||
model_card = state.speckle_state.receive_cards[model_card_id]
|
||||
converter = Converters::ToNative.new(state, model_card.model_id, model_card.project_name,
|
||||
model_card.model_name, source_application)
|
||||
# Have side effects on the sketchup model. It effects directly on the entities by adding new objects.
|
||||
state = converter.receive_commit_object(root_obj)
|
||||
|
||||
|
||||
resolve_js_script = "receiveBinding.receiveResponse('#{resolve_id}')"
|
||||
state.with_add_queue_js_command('receive', resolve_js_script)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,37 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../action'
|
||||
require_relative '../../accounts/accounts'
|
||||
require_relative '../../convertors/units'
|
||||
require_relative '../../convertors/to_speckle'
|
||||
require_relative '../../operations/send'
|
||||
require_relative '../../ext/TT_Lib2/progressbar'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Receive from server.
|
||||
class Receive < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, resolve_id, model_card_id, source_application)
|
||||
model_card = state.speckle_state.receive_cards[model_card_id]
|
||||
account = Accounts.get_account_by_id(model_card.account_id)
|
||||
|
||||
resolve_js_script = "receiveBinding.receiveResponse('#{resolve_id}')"
|
||||
state = state.with_add_queue_js_command('receive', resolve_js_script)
|
||||
args = {
|
||||
modelCardId: model_card_id,
|
||||
projectId: model_card.project_id,
|
||||
modelId: model_card.model_id,
|
||||
token: account['token'],
|
||||
serverUrl: account['serverInfo']['url'],
|
||||
accountId: model_card.account_id,
|
||||
objectId: model_card.object_id,
|
||||
sourceApplication: source_application
|
||||
}
|
||||
js_script = "receiveBinding.emit('receiveViaBrowser', #{args.to_json})"
|
||||
state.with_add_queue_js_command('receiveViaBrowser', js_script)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -3,29 +3,43 @@
|
||||
require_relative 'action'
|
||||
require_relative '../convertors/units'
|
||||
require_relative '../convertors/to_native'
|
||||
require_relative '../operations/receive'
|
||||
require_relative '../convertors/clean_up'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Action to receive objects from Speckle Server.
|
||||
class ReceiveObjects < Action
|
||||
def initialize(stream_id, base, stream_name, branch_name, branch_id)
|
||||
# rubocop:disable Metrics/ParameterLists
|
||||
def initialize(stream_id, base, stream_name, branch_name, branch_id, source_app, object_id)
|
||||
super()
|
||||
@stream_id = stream_id
|
||||
@base = base
|
||||
@stream_name = stream_name
|
||||
@branch_name = branch_name
|
||||
@branch_id = branch_id
|
||||
@source_app = source_app
|
||||
@object_id = object_id
|
||||
end
|
||||
# rubocop:enable Metrics/ParameterLists
|
||||
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def update_state(state)
|
||||
converter = Converters::ToNative.new(state.sketchup_state.sketchup_model)
|
||||
# content = Operations.receive(@stream_id, @object_id)
|
||||
|
||||
converter = Converters::ToNative.new(state, @stream_id, @stream_name, @branch_name, @source_app)
|
||||
# Have side effects on the sketchup model. It effects directly on the entities by adding new objects.
|
||||
start_time = Time.now.to_f
|
||||
converter.receive_commit_object(@base, state.user_state.preferences[:model])
|
||||
state.sketchup_state.sketchup_model.start_operation('Receive Speckle Objects', true)
|
||||
state = converter.receive_commit_object(@base)
|
||||
if state.user_state.model_preferences[:merge_coplanar_faces]
|
||||
Converters::CleanUp.merge_coplanar_faces(converter.converted_faces)
|
||||
end
|
||||
state.sketchup_state.sketchup_model.commit_operation
|
||||
elapsed_time = (Time.now.to_f - start_time).round(3)
|
||||
puts "==== Converting to Native executed in #{elapsed_time} sec ===="
|
||||
puts "==== Source application is #{@source_app}. ===="
|
||||
state.with_add_queue('finishedReceiveInSketchup', @stream_id, [])
|
||||
end
|
||||
end
|
||||
|
||||
@@ -10,7 +10,7 @@ module SpeckleConnector
|
||||
class ReloadAccounts < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, _data)
|
||||
def self.update_state(state, _resolve_id, _data)
|
||||
puts 'Reload of Speckle accounts requested by plugin'
|
||||
new_speckle_state = state.speckle_state.with_accounts(Accounts.load_accounts)
|
||||
state = state.with_speckle_state(new_speckle_state)
|
||||
|
||||
@@ -18,10 +18,10 @@ module SpeckleConnector
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def update_state(state)
|
||||
speckle_dict = state.sketchup_state.sketchup_model.attribute_dictionary('speckle', true)
|
||||
saved = speckle_dict['streams'] || []
|
||||
speckle_dict = state.sketchup_state.sketchup_model.attribute_dictionary('Speckle', true)
|
||||
saved = speckle_dict['saved_streams'] || []
|
||||
saved -= [@stream_id]
|
||||
speckle_dict['streams'] = saved
|
||||
speckle_dict['saved_streams'] = saved
|
||||
state
|
||||
end
|
||||
end
|
||||
|
||||
@@ -16,10 +16,10 @@ module SpeckleConnector
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def update_state(state)
|
||||
speckle_dict = state.sketchup_state.sketchup_model.attribute_dictionary('speckle', true)
|
||||
saved = speckle_dict['streams'] || []
|
||||
speckle_dict = state.sketchup_state.sketchup_model.attribute_dictionary('Speckle', true)
|
||||
saved = speckle_dict['saved_streams'] || []
|
||||
saved = saved.empty? ? [@stream_id] : saved.unshift(@stream_id)
|
||||
speckle_dict['streams'] = saved
|
||||
speckle_dict['saved_streams'] = saved
|
||||
state
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'action'
|
||||
require_relative 'events/selection_event_action'
|
||||
require_relative '../sketchup_model/dictionary/speckle_schema_dictionary_handler'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Select entities that selected from mapped elements table.
|
||||
class SelectMappingsFromTable < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, _resolve_id, data)
|
||||
# Clear first selection
|
||||
state.sketchup_state.sketchup_model.selection.clear
|
||||
|
||||
# Flat entities to select mapped elements
|
||||
flat_entities = SketchupModel::Query::Entity.flat_entities(state.sketchup_state.sketchup_model.entities)
|
||||
|
||||
# Collect entity ids to clear mappings
|
||||
entity_ids = data.collect { |_, entities| entities['selectedElements'].collect { |e| e['entityId'] } }.flatten
|
||||
|
||||
# Store speckle state to update with mapped entities.
|
||||
flat_entities.each do |entity|
|
||||
next unless entity_ids.include?(entity.persistent_id)
|
||||
|
||||
if entity.is_a?(Sketchup::ComponentDefinition)
|
||||
state.sketchup_state.sketchup_model.selection.add(entity.instances)
|
||||
end
|
||||
state.sketchup_state.sketchup_model.selection.add(entity)
|
||||
end
|
||||
|
||||
Events::SelectionEventAction.update_state(state, { clear: true })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,22 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../action'
|
||||
require_relative '../../ui_data/sketchup/selection_info'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Action to get selection.
|
||||
class GetSelection < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state)
|
||||
selected_object_ids = state.sketchup_state.sketchup_model.selection.collect(&:persistent_id)
|
||||
summary = "Selected #{selected_object_ids.length} objects."
|
||||
selection_info = UiData::Sketchup::SelectionInfo.new(selected_object_ids, summary)
|
||||
# js_script = "selectionBinding.receiveResponse('#{resolve_id}', #{selection_info.to_json})"
|
||||
js_script = "selectionBinding.emit('setSelection', #{selection_info.to_json})"
|
||||
state.with_add_queue_js_command('setSelection', js_script)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,22 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../action'
|
||||
require_relative '../../sketchup_model/dictionary/model_card_dictionary_handler'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Action to activate send filter.
|
||||
class ActivateSendFilter < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, resolve_id, data, value)
|
||||
SketchupModel::Dictionary::ModelCardDictionaryHandler.update_filter(state.sketchup_state.sketchup_model, data, value)
|
||||
card_id = "#{data['accountId']}-#{data['projectId']}-#{data['modelId']}"
|
||||
send_card = state.speckle_state.send_cards[card_id]
|
||||
puts "Send card filter updated -> #{card_id} -> #{send_card}"
|
||||
js_script = "sendBindingOld.receiveResponse('#{resolve_id}')"
|
||||
state.with_add_queue_js_command('activateSendFilter', js_script)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,22 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../action'
|
||||
require_relative '../../sketchup_model/dictionary/model_card_dictionary_handler'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Action to activate send filter tag.
|
||||
class ActivateSendFilterTag < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, resolve_id, data, value)
|
||||
SketchupModel::Dictionary::ModelCardDictionaryHandler.update_tag_filter(state.sketchup_state.sketchup_model, data, value)
|
||||
card_id = "#{data['accountId']}-#{data['projectId']}-#{data['modelId']}"
|
||||
send_card = state.speckle_state.send_cards[card_id]
|
||||
puts "Send card filter updated -> #{card_id} -> #{send_card}"
|
||||
js_script = "sendBindingOld.receiveResponse('#{resolve_id}')"
|
||||
state.with_add_queue_js_command('activateSendFilterTag', js_script)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,86 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../action'
|
||||
require_relative '../../accounts/accounts'
|
||||
require_relative '../../convertors/units'
|
||||
require_relative '../../convertors/to_speckle'
|
||||
require_relative '../../operations/send'
|
||||
require_relative '../../ext/TT_Lib2/progressbar'
|
||||
require_relative '../../ext/worker'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Send to server.
|
||||
class Send < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, resolve_id, model_card_id)
|
||||
model_card = state.speckle_state.send_cards[model_card_id]
|
||||
account = Accounts.get_account_by_id(model_card.account_id)
|
||||
converter = Converters::ToSpeckle.new(state, model_card_id, model_card.send_filter)
|
||||
|
||||
new_speckle_state, base = converter.convert_selection_to_base(state.user_state.preferences)
|
||||
id, total_children_count, batches, new_speckle_state = converter.serialize(base, new_speckle_state,
|
||||
state.user_state.preferences)
|
||||
|
||||
# update_test(state)
|
||||
|
||||
puts("converted #{base.count} objects for stream #{@stream_id}")
|
||||
|
||||
state = state.with_speckle_state(new_speckle_state)
|
||||
|
||||
resolve_js_script = "sendBinding.receiveResponse('#{resolve_id}')"
|
||||
state = state.with_add_queue_js_command('send', resolve_js_script)
|
||||
args = {
|
||||
modelCardId: model_card_id,
|
||||
projectId: model_card.project_id,
|
||||
modelId: model_card.model_id,
|
||||
token: account['token'],
|
||||
serverUrl: account['serverInfo']['url'],
|
||||
accountId: model_card.account_id,
|
||||
message: model_card.message,
|
||||
sendObject: {
|
||||
id: id,
|
||||
totalChildrenCount: total_children_count,
|
||||
batches: batches
|
||||
}
|
||||
}
|
||||
js_script = "sendBinding.emit('sendViaBrowser', #{args.to_json})"
|
||||
state.with_add_queue_js_command('sendViaBrowser', js_script)
|
||||
end
|
||||
|
||||
def self.update_test(state)
|
||||
dialog = UI::HtmlDialog.new(
|
||||
{
|
||||
:dialog_title => 'Dialog Example',
|
||||
:preferences_key => 'com.sample.plugin',
|
||||
:scrollable => true,
|
||||
:resizable => true,
|
||||
:width => 600,
|
||||
:height => 400,
|
||||
:left => 10,
|
||||
:top => 10,
|
||||
:min_width => 50,
|
||||
:min_height => 50,
|
||||
:max_width =>1000,
|
||||
:max_height => 1000,
|
||||
:style => UI::HtmlDialog::STYLE_DIALOG
|
||||
})
|
||||
html = '<div id="hi"><b>Hello world!</b></div>'
|
||||
dialog.set_html(html)
|
||||
dialog.show
|
||||
|
||||
action = Proc.new do |status|
|
||||
js_command = "document.getElementById('hi').innerHTML = '<b>#{status}</b>'"
|
||||
log_js_command = "console.log('test')"
|
||||
dialog.execute_script(js_command)
|
||||
dialog.execute_script(log_js_command)
|
||||
end
|
||||
|
||||
selected_object_ids = state.sketchup_state.sketchup_model.selection.collect(&:persistent_id)
|
||||
state.worker.add_jobs(1000.times.to_a.map { |i| Job.new(i, &action) })
|
||||
state.worker.do_work(Time.now.to_f, &action)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,23 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../action'
|
||||
require_relative '../../sketchup_model/dictionary/model_card_dictionary_handler'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Action to check send card expirations.
|
||||
class SendCardExpirationCheck < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state)
|
||||
return state unless state.speckle_state.changed_entity_ids.any?
|
||||
|
||||
expired_send_cards_ids = state.speckle_state.send_cards.select do |_id, send_card|
|
||||
send_card.send_filter.check_expiry(state.speckle_state.changed_entity_ids)
|
||||
end.keys.to_a
|
||||
js_script = "sendBinding.emit('sendersExpired', #{expired_send_cards_ids.to_json})"
|
||||
state.with_add_queue_js_command('sendersExpired', js_script)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -16,11 +16,10 @@ module SpeckleConnector
|
||||
# @return [States::State] the new updated state object
|
||||
def update_state(state)
|
||||
to_send_stream_id = state.speckle_state.stream_queue[:stream_id]
|
||||
return state if to_send_stream_id == @stream_id
|
||||
return state if to_send_stream_id == @stream_id || to_send_stream_id.nil?
|
||||
|
||||
to_send_converted = state.speckle_state.stream_queue[:converted].to_json
|
||||
new_state = state.with_add_queue('convertedFromSketchup', to_send_stream_id, [to_send_converted])
|
||||
new_state = new_state.with_add_queue('oneClickSend', to_send_stream_id, [])
|
||||
new_state.with_empty_stream_queue
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'action'
|
||||
require_relative 'deactivate_diffing'
|
||||
require_relative '../convertors/units'
|
||||
require_relative '../convertors/to_speckle'
|
||||
require_relative '../operations/send'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
@@ -16,16 +18,26 @@ module SpeckleConnector
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def update_state(state)
|
||||
sketchup_model = state.sketchup_state.sketchup_model
|
||||
converter = Converters::ToSpeckle.new(sketchup_model)
|
||||
base = converter.convert_selection_to_base(state.user_state.preferences)
|
||||
id, total_children_count, batches = converter.send_info(base)
|
||||
state = DeactivateDiffing.update_state(state, nil, {})
|
||||
converter = Converters::ToSpeckle.new(state, @stream_id, {})
|
||||
new_speckle_state, base = converter.convert_selection_to_base(state.user_state.preferences)
|
||||
id, total_children_count, batches, new_speckle_state = converter.serialize(base, new_speckle_state,
|
||||
state.user_state.preferences)
|
||||
# TODO: Later active send operation.
|
||||
# Operations.send(@stream_id, batches)
|
||||
|
||||
puts("converted #{base.count} objects for stream #{@stream_id}")
|
||||
state.with_add_queue('convertedFromSketchup', @stream_id, [
|
||||
{ is_string: false, val: batches },
|
||||
{ is_string: true, val: id },
|
||||
{ is_string: false, val: total_children_count }
|
||||
])
|
||||
|
||||
# This is the place we can send information to UI for diffing check
|
||||
diffing = state.user_state.preferences[:user][:diffing]
|
||||
new_speckle_state = new_speckle_state.with_invalid_streams_queue if diffing
|
||||
|
||||
new_state = state.with_speckle_state(new_speckle_state)
|
||||
new_state.with_add_queue('convertedFromSketchup', @stream_id, [
|
||||
{ is_string: false, val: batches },
|
||||
{ is_string: true, val: id },
|
||||
{ is_string: false, val: total_children_count }
|
||||
])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'action'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Show all entities on the model.
|
||||
class ShowAllEntities < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, _resolve_id, _data)
|
||||
# Show all entities first
|
||||
state.sketchup_state.sketchup_model.entities.each do |ent|
|
||||
ent.hidden = false
|
||||
end
|
||||
state
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,46 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../action'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Action to get user config.
|
||||
class GetUserConfig < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, resolve_id)
|
||||
# Previously it was stored in user state
|
||||
# config = state.user_state.preferences.to_json
|
||||
config = [
|
||||
{
|
||||
key: 'darkTheme',
|
||||
title: 'Theme',
|
||||
type: 'toggle',
|
||||
config: {
|
||||
value: state.user_state.user_preferences[:dark_theme]
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'diffing',
|
||||
title: 'Diffing',
|
||||
type: 'toggle',
|
||||
config: {
|
||||
value: state.user_state.user_preferences[:diffing]
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'referencePoint',
|
||||
title: 'Reference Point',
|
||||
type: 'dropdown',
|
||||
config: {
|
||||
value: 'test',
|
||||
items: ['test', 'test1', 'test2']
|
||||
}
|
||||
}
|
||||
]
|
||||
js_script = "connectorConfigBinding.receiveResponse('#{resolve_id}', #{config.to_json})"
|
||||
state.with_add_queue_js_command('getUserConfig', js_script)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,18 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../action'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Action to get user config.
|
||||
class UpdateUserConfig < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, resolve_id, new_config)
|
||||
puts new_config.values
|
||||
js_script = "connectorConfigBinding.receiveResponse('#{resolve_id}')"
|
||||
state.with_add_queue_js_command('updateUserConfig', js_script)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,21 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../action'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Test purpose action.
|
||||
class GetComplexType < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, resolve_id)
|
||||
complex_type = {
|
||||
id: 'complex_type_id',
|
||||
count: 3
|
||||
}
|
||||
js_script = "testBinding.receiveResponse('#{resolve_id}', #{complex_type.to_json})"
|
||||
state.with_add_queue_js_command('getComplexType', js_script)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,18 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../action'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Test purpose action.
|
||||
class GoAway < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, resolve_id)
|
||||
puts 'SketchUp went away :('
|
||||
js_script = "testBinding.receiveResponse('#{resolve_id}')"
|
||||
state.with_add_queue_js_command('goAway', js_script)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,21 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../action'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Test purpose action.
|
||||
class SayHi < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, resolve_id, name, count, say_hello_not_hi)
|
||||
said_hi = []
|
||||
count.times do
|
||||
said_hi.append("#{say_hello_not_hi ? 'Hello' : 'Hi'} #{name}!")
|
||||
end
|
||||
js_script = "testBinding.receiveResponse('#{resolve_id}', #{said_hi})"
|
||||
state.with_add_queue_js_command('sayHi', js_script)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,28 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../action'
|
||||
|
||||
module SpeckleConnector
|
||||
module Actions
|
||||
# Test purpose action.
|
||||
class TriggerEvent < Action
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
def self.update_state(state, resolve_id, event_name)
|
||||
if event_name == 'emptyTestEvent'
|
||||
js_script = "testBinding.emit('#{event_name}')"
|
||||
else
|
||||
args = {
|
||||
name: 'Oguzhan',
|
||||
isOk: true,
|
||||
count: 3
|
||||
}
|
||||
js_script = "testBinding.emit('#{event_name}', #{args.to_json})"
|
||||
end
|
||||
resolve_js_script = "testBinding.receiveResponse('#{resolve_id}')"
|
||||
state = state.with_add_queue_js_command('triggerEventResolve', resolve_js_script)
|
||||
state.with_add_queue_js_command('triggerEvent', js_script)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -18,6 +18,8 @@ module SpeckleConnector
|
||||
|
||||
# @param state [States::State] the current state of the {App::SpeckleConnectorApp}
|
||||
# @return [States::State] the new updated state object
|
||||
# rubocop:disable Metrics/AbcSize
|
||||
# rubocop:disable Metrics/MethodLength
|
||||
def update_state(state)
|
||||
# Init sqlite database
|
||||
db = Sqlite3::Database.new(SPECKLE_CONFIG_DB_PATH)
|
||||
@@ -46,8 +48,19 @@ module SpeckleConnector
|
||||
user[@preference.to_sym] = @value
|
||||
new_preferences = state.user_state.preferences.put(:user, user)
|
||||
new_user_state = state.user_state.with_preferences(new_preferences)
|
||||
# This is the place we can send information to UI for diffing check. It is a technical depth!
|
||||
if @preference == 'diffing'
|
||||
new_speckle_state = if @value
|
||||
state.speckle_state.with_invalid_streams_queue
|
||||
else
|
||||
state.speckle_state.with_empty_invalid_streams_queue
|
||||
end
|
||||
state = state.with_speckle_state(new_speckle_state)
|
||||
end
|
||||
state.with_user_state(new_user_state)
|
||||
end
|
||||
# rubocop:enable Metrics/AbcSize
|
||||
# rubocop:enable Metrics/MethodLength
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -15,6 +15,9 @@ module SpeckleConnector
|
||||
# @return [Ui::UiController] controller for ui views
|
||||
attr_reader :ui_controller
|
||||
|
||||
# @return [Observers::Handler] the observers indexed by their classes to handle
|
||||
attr_reader :observer_handler
|
||||
|
||||
def initialize(menu_commands, state, ui_controller)
|
||||
@menu_commands = menu_commands
|
||||
@state = state
|
||||
@@ -25,21 +28,32 @@ module SpeckleConnector
|
||||
state.speckle_state?
|
||||
end
|
||||
|
||||
def update_ui!
|
||||
ui_controller.update_ui(state)
|
||||
# Attach observers to application when speckle initialized via menu commands.
|
||||
def add_observer_handler!(observer_handler)
|
||||
@observer_handler = observer_handler
|
||||
end
|
||||
|
||||
# Send messages to HtmlDialog if any.
|
||||
def send_messages!
|
||||
queue = @state.speckle_state.message_queue
|
||||
queue.each_value { |value| ui_controller.user_interfaces[Ui::SPECKLE_UI_ID].dialog.execute_script(value) }
|
||||
queue.each_value do |value|
|
||||
instant_message_sender(value)
|
||||
end
|
||||
update_state!(Actions::ClearQueue)
|
||||
end
|
||||
|
||||
def instant_message_sender(message)
|
||||
ui_controller.user_interfaces.each_value do |dialog|
|
||||
dialog.execute_script(message)
|
||||
end
|
||||
end
|
||||
|
||||
# This is the only function application state will be switched by calling upcoming action with it's parameters
|
||||
# if any.
|
||||
def update_state!(action, *parameters)
|
||||
old_state = @state
|
||||
@state = action.update_state(old_state, *parameters)
|
||||
send_messages! if @state.speckle_state.message_queue.any?
|
||||
update_ui! unless @state.equal?(old_state)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../speckle_objects/other/color'
|
||||
|
||||
module SpeckleConnector
|
||||
module Cards
|
||||
# Card for sketchup connector to communicate speckle.
|
||||
class Card < Hash
|
||||
# @return [String] id of the card.
|
||||
attr_reader :id
|
||||
|
||||
# @return [String] account id of the card.
|
||||
attr_reader :account_id
|
||||
|
||||
# @return [String] project id of the card.
|
||||
attr_reader :project_id
|
||||
|
||||
# @return [String] model id of the card.
|
||||
attr_reader :model_id
|
||||
|
||||
# @return [Boolean] card is valid or not.
|
||||
attr_reader :valid
|
||||
|
||||
def initialize(card_id, account_id, project_id, model_id)
|
||||
super()
|
||||
@id = card_id
|
||||
@account_id = account_id
|
||||
@project_id = project_id
|
||||
@model_id = model_id
|
||||
@valid = true
|
||||
self[:id] = card_id
|
||||
self[:account_id] = account_id
|
||||
self[:project_id] = project_id
|
||||
self[:model_id] = model_id
|
||||
self[:valid] = @valid
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,36 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'card'
|
||||
|
||||
module SpeckleConnector
|
||||
module Cards
|
||||
# Receive card for sketchup connector to communicate speckle.
|
||||
class ReceiveCard < Card
|
||||
attr_reader :type_discriminator
|
||||
|
||||
# @return [String, NilClass] message to send
|
||||
attr_reader :message
|
||||
|
||||
# @return [String] object id to receive
|
||||
attr_reader :object_id
|
||||
|
||||
# @return [String] name of the project
|
||||
attr_reader :project_name
|
||||
|
||||
# @return [String] name of the model
|
||||
attr_reader :model_name
|
||||
|
||||
def initialize(card_id, account_id, project_id, project_name, model_id, model_name, object_id)
|
||||
super(card_id, account_id, project_id, model_id)
|
||||
@object_id = object_id
|
||||
self[:object_id] = object_id
|
||||
self[:model_name] = model_name
|
||||
self[:project_name] = project_name
|
||||
@model_name = model_name
|
||||
@project_name = project_name
|
||||
@type_discriminator = 'ReceiverModelCard'
|
||||
self[:type_discriminator] = @type_discriminator
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,31 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'card'
|
||||
|
||||
module SpeckleConnector
|
||||
module Cards
|
||||
# Send card for sketchup connector to communicate speckle.
|
||||
class SendCard < Card
|
||||
# @return [Filters::Send::EverythingFilter | Filters::Send::SelectionFilter | Filters::Send::LayerFilter] filter of the card.
|
||||
attr_reader :send_filter
|
||||
|
||||
# @return [Object] send settings of the card.
|
||||
attr_reader :send_settings
|
||||
|
||||
attr_reader :type_discriminator
|
||||
|
||||
# @return [String, NilClass] message to send
|
||||
attr_reader :message
|
||||
|
||||
def initialize(card_id, account_id, project_id, model_id, send_filter, send_settings)
|
||||
super(card_id, account_id, project_id, model_id)
|
||||
@send_filter = send_filter
|
||||
@send_settings = send_settings
|
||||
@type_discriminator = 'SenderModelCard'
|
||||
self[:sendFilter] = send_filter
|
||||
self[:sendSettings] = send_settings
|
||||
self[:type_discriminator] = @type_discriminator
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,19 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'card'
|
||||
|
||||
module SpeckleConnector
|
||||
module Cards
|
||||
# Send card for sketchup connector to communicate speckle.
|
||||
class SendCardMultipleFilters < Card
|
||||
# @return [Hash{String=>Filter}] filters of the card.
|
||||
attr_reader :filters
|
||||
|
||||
def initialize(card_id, account_id, project_id, model_id, filters)
|
||||
super(card_id, account_id, project_id, model_id)
|
||||
@filters = filters
|
||||
self[:filters] = filters
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -7,10 +7,10 @@ module SpeckleConnector
|
||||
# Command to update state of the application.
|
||||
class ActionCommand < Command
|
||||
# @param app [App::SpeckleConnectorApp] the app object to run command on
|
||||
# @param binding [Ui::Binding] binding object holds commands to call
|
||||
# @param action [#update_state] the action that knows how to change the state of the speckle app
|
||||
def initialize(app, action)
|
||||
super(app)
|
||||
@app = app
|
||||
def initialize(app, binding, action)
|
||||
super(app, binding)
|
||||
@action = action
|
||||
end
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'command'
|
||||
require_relative '../actions/activate_diffing'
|
||||
|
||||
module SpeckleConnector
|
||||
module Commands
|
||||
# Command to activate diffing for stream.
|
||||
class ActivateDiffing < Command
|
||||
def _run(_resolve_id, data)
|
||||
stream_id = data['stream_id']
|
||||
action = Actions::ActivateDiffing.new(stream_id)
|
||||
app.update_state!(action)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,25 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'command'
|
||||
require_relative '../actions/apply_mappings'
|
||||
|
||||
module SpeckleConnector
|
||||
module Commands
|
||||
# Command to apply mapping for selected entities.
|
||||
class ApplyMappings < Command
|
||||
def _run(_resolve_id, data)
|
||||
entities_to_map = data['entitiesToMap']
|
||||
method = data['method']
|
||||
category = data['category']
|
||||
family = data['family']
|
||||
family_type = data['familyType']
|
||||
level = data['level']
|
||||
name = data['name']
|
||||
is_definition = data['isDefinition']
|
||||
action = Actions::ApplyMappings.new(entities_to_map, method, category, family,
|
||||
family_type, level, name, is_definition)
|
||||
app.update_state!(action)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,18 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'command'
|
||||
require_relative '../actions/clear_mappings'
|
||||
|
||||
module SpeckleConnector
|
||||
module Commands
|
||||
# Command to clear mapping for selected entities.
|
||||
class ClearMappings < Command
|
||||
def _run(_resolve_id, data)
|
||||
entities_to_map = data['entitiesToClearMap']
|
||||
is_definition = data['isDefinition']
|
||||
action = Actions::ClearMappings.new(entities_to_map, is_definition)
|
||||
app.update_state!(action)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,5 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../actions/handle_error'
|
||||
|
||||
module SpeckleConnector
|
||||
module Commands
|
||||
# Base command schema to wrap common operations for all commands.
|
||||
@@ -7,22 +9,39 @@ module SpeckleConnector
|
||||
# @return [App::SpeckleConnectorApp] the main app object
|
||||
attr_reader :app
|
||||
|
||||
# @return [Ui::View] view object holds dialog and it's state
|
||||
attr_reader :view
|
||||
# @return [Ui::Binding] binding object holds dialog and it's state
|
||||
attr_reader :binding
|
||||
|
||||
# @@param app [App::SpeckleConnectorApp] the main app object
|
||||
def initialize(app)
|
||||
# @param app [App::SpeckleConnectorApp] the main app object
|
||||
# @param binding [Ui::Binding] binding object holds commands to call
|
||||
def initialize(app, binding)
|
||||
@app = app
|
||||
@view = app.ui_controller.user_interfaces[Ui::SPECKLE_UI_ID]
|
||||
@binding = binding
|
||||
end
|
||||
|
||||
def run(*parameters)
|
||||
# Run here common operations that same for each command.
|
||||
_run(*parameters)
|
||||
begin
|
||||
# Run here common operations that same for each command.
|
||||
with_observers_disabled do
|
||||
_run(*parameters)
|
||||
end
|
||||
rescue StandardError => e
|
||||
action = Actions::HandleError.new(e, @binding.name, @action, parameters)
|
||||
app.update_state!(action)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def with_observers_disabled(&block)
|
||||
observer_handler = @app.observer_handler
|
||||
if observer_handler
|
||||
observer_handler.with_observers_disabled(&block)
|
||||
else
|
||||
block.call
|
||||
end
|
||||
end
|
||||
|
||||
def _run(*_parameters)
|
||||
raise NotImplementedError, 'Implement in subclass'
|
||||
end
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'command'
|
||||
|
||||
module SpeckleConnector
|
||||
module Commands
|
||||
# Run this command when the UI is ready to get data
|
||||
class DialogReady < Command
|
||||
# Update the selected user interface
|
||||
def _run(_data)
|
||||
view.update_view(app.state)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,85 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'command'
|
||||
require_relative '../ui/dui3_dialog'
|
||||
require_relative '../states/initial_state'
|
||||
require_relative '../ui/legacy_binding'
|
||||
require_relative '../ui/bindings/accounts_binding'
|
||||
require_relative '../ui/bindings/base_binding'
|
||||
require_relative '../ui/bindings/send_binding'
|
||||
require_relative '../ui/bindings/receive_binding'
|
||||
require_relative '../ui/bindings/selection_binding'
|
||||
require_relative '../ui/test_binding'
|
||||
require_relative '../ui/bindings/config_binding'
|
||||
require_relative '../ui/sketchup_config_binding'
|
||||
require_relative '../actions/initialize_speckle'
|
||||
require_relative '../observers/factory'
|
||||
|
||||
module SpeckleConnector
|
||||
module Commands
|
||||
# Command to initialize Speckle UI and register it to ui_controller.
|
||||
# This is the command where we show UI to user.
|
||||
class InitializeDUI3Speckle < Command
|
||||
SPECKLE_DUI3 = 'speckle_dui3'
|
||||
|
||||
def dialog_title
|
||||
"Speckle #{CONNECTOR_VERSION}"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def _run
|
||||
app = self.app
|
||||
if !app.state.instance_of?(States::InitialState) && app.ui_controller.user_interfaces[SPECKLE_DUI3]
|
||||
dialog = app.ui_controller.user_interfaces[SPECKLE_DUI3]
|
||||
dialog.show
|
||||
return
|
||||
end
|
||||
|
||||
initialize_speckle_dui3(app)
|
||||
end
|
||||
|
||||
# Do the actual Speckle initialization.
|
||||
# rubocop:disable Naming/VariableNumber
|
||||
def initialize_speckle_dui3(app)
|
||||
# TODO: Initialize here speckle states and observers.
|
||||
observer_handler = Observers::Factory.create_handler(app)
|
||||
app.add_observer_handler!(observer_handler)
|
||||
observers = Observers::Factory.create_observers(observer_handler)
|
||||
app.update_state!(Actions::InitializeSpeckle, observers, app.method(:instant_message_sender))
|
||||
dialog_specs = {
|
||||
dialog_id: SPECKLE_DUI3,
|
||||
dialog_title: dialog_title,
|
||||
height: 950,
|
||||
width: 300
|
||||
}
|
||||
# Init bindings
|
||||
base_binding = Ui::BaseBinding.new(app, Ui::BASE_BINDING_NAME)
|
||||
accounts_binding = Ui::AccountsBinding.new(app, Ui::ACCOUNTS_BINDING_NAME)
|
||||
send_binding = Ui::SendBinding.new(app, Ui::SEND_BINDING_NAME)
|
||||
receive_binding = Ui::ReceiveBinding.new(app, Ui::RECEIVE_BINDING_NAME)
|
||||
selection_binding = Ui::SelectionBinding.new(app, Ui::SELECTION_BINDING_NAME)
|
||||
test_bindings = Ui::TestBinding.new(app, Ui::TEST_BINDINGS_NAME)
|
||||
config_bindings = Ui::ConfigBinding.new(app, Ui::CONFIG_BINDING_NAME)
|
||||
connector_config_bindings = Ui::SketchupConfigBinding.new(app, Ui::CONNECTOR_CONFIG_BINDING_NAME)
|
||||
|
||||
# Init dialog
|
||||
dui3_dialog = SpeckleConnector::Ui::DUI3Dialog.new(**dialog_specs)
|
||||
|
||||
# Register bindings to dialog
|
||||
dui3_dialog.bindings[Ui::BASE_BINDING_NAME] = base_binding
|
||||
dui3_dialog.bindings[Ui::ACCOUNTS_BINDING_NAME] = accounts_binding
|
||||
dui3_dialog.bindings[Ui::SEND_BINDING_NAME] = send_binding
|
||||
dui3_dialog.bindings[Ui::RECEIVE_BINDING_NAME] = receive_binding
|
||||
dui3_dialog.bindings[Ui::TEST_BINDINGS_NAME] = test_bindings
|
||||
dui3_dialog.bindings[Ui::CONFIG_BINDING_NAME] = config_bindings
|
||||
dui3_dialog.bindings[Ui::CONNECTOR_CONFIG_BINDING_NAME] = connector_config_bindings
|
||||
dui3_dialog.bindings[Ui::SELECTION_BINDING_NAME] = selection_binding
|
||||
|
||||
app.ui_controller.register_ui(SPECKLE_DUI3, dui3_dialog)
|
||||
dui3_dialog.show
|
||||
end
|
||||
# rubocop:enable Naming/VariableNumber
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -2,14 +2,17 @@
|
||||
|
||||
require_relative 'command'
|
||||
require_relative '../states/initial_state'
|
||||
require_relative '../ui/vue_view'
|
||||
require_relative '../ui/legacy_binding'
|
||||
require_relative '../actions/initialize_speckle'
|
||||
require_relative '../observers/factory'
|
||||
|
||||
module SpeckleConnector
|
||||
module Commands
|
||||
# Command to initialize Speckle UI and register it to ui_controller.
|
||||
# Command to initialize old Speckle UI and register it to ui_controller.
|
||||
# This is the command where we show UI to user.
|
||||
class InitializeSpeckle < Command
|
||||
SPECKLE_LEGACY_UI = 'speckle_legacy_ui'
|
||||
|
||||
def dialog_title
|
||||
"Speckle #{CONNECTOR_VERSION}"
|
||||
end
|
||||
@@ -18,29 +21,34 @@ module SpeckleConnector
|
||||
|
||||
def _run
|
||||
app = self.app
|
||||
unless app.state.instance_of?(States::InitialState)
|
||||
vue_view = app.ui_controller.user_interfaces[Ui::SPECKLE_UI_ID]
|
||||
if !app.state.instance_of?(States::InitialState) && app.ui_controller.user_interfaces[SPECKLE_LEGACY_UI]
|
||||
vue_view = app.ui_controller.user_interfaces[SPECKLE_LEGACY_UI]
|
||||
vue_view.show
|
||||
return
|
||||
end
|
||||
|
||||
initialize_speckle(app)
|
||||
initialize_speckle_legacy_view(app)
|
||||
end
|
||||
|
||||
# Do the actual Speckle initialization.
|
||||
def initialize_speckle(app)
|
||||
def initialize_speckle_legacy_view(app)
|
||||
# TODO: Initialize here speckle states and observers.
|
||||
app.update_state!(Actions::InitializeSpeckle)
|
||||
observer_handler = Observers::Factory.create_handler(app)
|
||||
app.add_observer_handler!(observer_handler)
|
||||
observers = Observers::Factory.create_observers(observer_handler)
|
||||
app.update_state!(Actions::InitializeSpeckle, observers)
|
||||
dialog_specs = {
|
||||
dialog_id: Ui::SPECKLE_UI_ID,
|
||||
dialog_id: SPECKLE_LEGACY_UI,
|
||||
htm_file: Ui::VUE_UI_HTML,
|
||||
dialog_title: dialog_title,
|
||||
height: 950,
|
||||
width: 300
|
||||
}
|
||||
vue_view = Ui::VueView.new(dialog_specs, app)
|
||||
app.ui_controller.register_ui(Ui::SPECKLE_UI_ID, vue_view)
|
||||
vue_view.show
|
||||
legacy_ui_dialog = SpeckleConnector::Ui::Dialog.new(**dialog_specs)
|
||||
legacy_binding = Ui::LegacyBinding.new(app, 'legacy_ui')
|
||||
legacy_ui_dialog.bindings[Ui::SPECKLE_LEGACY_BINDING_NAME] = legacy_binding
|
||||
app.ui_controller.register_ui(SPECKLE_LEGACY_UI, legacy_ui_dialog)
|
||||
legacy_ui_dialog.show
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'command'
|
||||
require_relative '../actions/mapper_source_updated'
|
||||
|
||||
module SpeckleConnector
|
||||
module Commands
|
||||
# Command to update mapper source.
|
||||
class MapperSourceUpdated < Command
|
||||
def _run(_resolve_id, data)
|
||||
base = data['base']
|
||||
stream_id = data['stream_id']
|
||||
commit_id = data['commit_id']
|
||||
action = Actions::MapperSourceUpdated.new(base, stream_id, commit_id)
|
||||
app.update_state!(action)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -8,7 +8,7 @@ module SpeckleConnector
|
||||
module Commands
|
||||
# Command to update theme.
|
||||
class ModelPreferencesUpdated < Command
|
||||
def _run(data)
|
||||
def _run(_resolve_id, data)
|
||||
preference = data['preference']
|
||||
new_value = data['value']
|
||||
app.update_state!(Actions::ModelPreferencesUpdated.new(preference, new_value))
|
||||
|
||||
@@ -8,7 +8,7 @@ module SpeckleConnector
|
||||
module Commands
|
||||
# Command to notify connected.
|
||||
class NotifyConnected < Command
|
||||
def _run(data)
|
||||
def _run(_resolve_id, data)
|
||||
stream_id = data['stream_id']
|
||||
app.update_state!(Actions::Connected)
|
||||
app.update_state!(Actions::SendFromQueue.new(stream_id))
|
||||
|
||||
@@ -7,13 +7,15 @@ module SpeckleConnector
|
||||
module Commands
|
||||
# Command to receive objects from Speckle Server.
|
||||
class ReceiveObjects < Command
|
||||
def _run(data)
|
||||
def _run(_resolve_id, data)
|
||||
stream_id = data['stream_id']
|
||||
base = data['base']
|
||||
branch_name = data['branch_name']
|
||||
branch_id = data['branch_id']
|
||||
stream_name = data['stream_name']
|
||||
action = Actions::ReceiveObjects.new(stream_id, base, stream_name, branch_name, branch_id)
|
||||
source_app = data['source_app']
|
||||
object_id = data['object_id']
|
||||
action = Actions::ReceiveObjects.new(stream_id, base, stream_name, branch_name, branch_id, source_app, object_id)
|
||||
app.update_state!(action)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -8,7 +8,7 @@ module SpeckleConnector
|
||||
module Commands
|
||||
# Command to remove stream.
|
||||
class RemoveStream < Command
|
||||
def _run(data)
|
||||
def _run(_resolve_id, data)
|
||||
stream_id = data['stream_id']
|
||||
action = Actions::RemoveStream.new(stream_id)
|
||||
app.update_state!(action)
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative 'command'
|
||||
require_relative '../states/initial_state'
|
||||
require_relative '../actions/initialize_speckle'
|
||||
require_relative '../observers/factory'
|
||||
|
||||
module SpeckleConnector
|
||||
module Commands
|
||||
# Command to reset Speckle UI window location onto center of SketchUp window.
|
||||
class ResetWindowLocation < Command
|
||||
|
||||
private
|
||||
|
||||
def _run
|
||||
app = self.app
|
||||
vue_view = app.ui_controller.user_interfaces[Ui::SPECKLE_LEGACY_UI]
|
||||
if vue_view
|
||||
vue_view.dialog.reset_dialog_location
|
||||
else
|
||||
puts "Speckle UI didn't initialized!"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -9,7 +9,7 @@ module SpeckleConnector
|
||||
module Commands
|
||||
# Command to saved stream.
|
||||
class SaveStream < Command
|
||||
def _run(data)
|
||||
def _run(_resolve_id, data)
|
||||
stream_id = data['stream_id']
|
||||
app.update_state!(Actions::SaveStream.new(stream_id))
|
||||
end
|
||||
|
||||
@@ -7,7 +7,7 @@ module SpeckleConnector
|
||||
module Commands
|
||||
# Command to send selection to Speckle Server.
|
||||
class SendSelection < Command
|
||||
def _run(data)
|
||||
def _run(_resolve_id, data)
|
||||
stream_id = data['stream_id']
|
||||
action = Actions::SendSelection.new(stream_id)
|
||||
app.update_state!(action)
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
require_relative 'menu_command_handler'
|
||||
require_relative 'action_command'
|
||||
require_relative 'initialize_speckle'
|
||||
require_relative 'initialize_dui3_speckle'
|
||||
require_relative 'reset_window_location'
|
||||
require_relative '../actions/one_click_send'
|
||||
|
||||
module SpeckleConnector
|
||||
@@ -10,6 +12,8 @@ module SpeckleConnector
|
||||
# Speckle menu commands that adds them to Sketchup menu and toolbar.
|
||||
class SpeckleMenuCommands
|
||||
CMD_INITIALIZE_SPECKLE = :initialize_speckle
|
||||
CMD_INITIALIZE_DUI3_SPECKLE = :initialize_dui3_speckle
|
||||
CMD_RESET_WINDOW_LOCATION_SPECKLE = :reset_window_location_speckle
|
||||
CMD_SEND_TO_SPECKLE = :send_to_speckle
|
||||
CMD_RECEIVE_FROM_SPECKLE = :receive_from_speckle
|
||||
|
||||
@@ -26,6 +30,13 @@ module SpeckleConnector
|
||||
commands.add_to_menu!(CMD_INITIALIZE_SPECKLE, speckle_menu)
|
||||
commands.add_to_toolbar!(CMD_INITIALIZE_SPECKLE, speckle_toolbar)
|
||||
|
||||
commands[CMD_INITIALIZE_DUI3_SPECKLE] = initialize_dui3_speckle_command(app)
|
||||
commands.add_to_menu!(CMD_INITIALIZE_DUI3_SPECKLE, speckle_menu)
|
||||
commands.add_to_toolbar!(CMD_INITIALIZE_DUI3_SPECKLE, speckle_toolbar)
|
||||
|
||||
commands[CMD_RESET_WINDOW_LOCATION_SPECKLE] = reset_window_location_command(app)
|
||||
commands.add_to_menu!(CMD_RESET_WINDOW_LOCATION_SPECKLE, speckle_menu)
|
||||
|
||||
# commands[CMD_SEND_TO_SPECKLE] = send_command(app)
|
||||
# commands.add_to_menu!(CMD_SEND_TO_SPECKLE, speckle_menu)
|
||||
# commands.add_to_toolbar!(CMD_SEND_TO_SPECKLE, speckle_toolbar)
|
||||
@@ -33,7 +44,7 @@ module SpeckleConnector
|
||||
|
||||
def self.initialize_speckle_command(app)
|
||||
cmd = MenuCommandHandler.sketchup_command(
|
||||
InitializeSpeckle.new(app), 'Initialize Speckle'
|
||||
InitializeSpeckle.new(app, nil), 'Initialize Speckle'
|
||||
)
|
||||
cmd.tooltip = 'Launch Connector'
|
||||
cmd.status_bar_text = 'Opens the Speckle Connector window'
|
||||
@@ -42,9 +53,31 @@ module SpeckleConnector
|
||||
cmd
|
||||
end
|
||||
|
||||
def self.initialize_dui3_speckle_command(app)
|
||||
cmd = MenuCommandHandler.sketchup_command(
|
||||
InitializeDUI3Speckle.new(app, nil), 'Initialize DUI3 Speckle'
|
||||
)
|
||||
cmd.tooltip = 'Launch Connector with DUI3'
|
||||
cmd.status_bar_text = 'Opens the Speckle Connector DUI3 Window'
|
||||
cmd.small_icon = '../../img/s2logo_dui3.png'
|
||||
cmd.large_icon = '../../img/s2logo_dui3.png'
|
||||
cmd
|
||||
end
|
||||
|
||||
def self.reset_window_location_command(app)
|
||||
cmd = MenuCommandHandler.sketchup_command(
|
||||
ResetWindowLocation.new(app, nil), 'Reset Window Location'
|
||||
)
|
||||
cmd.tooltip = 'Bring Speckle window onto center of SketchUp window'
|
||||
cmd.status_bar_text = 'Bring Speckle window onto center of SketchUp window'
|
||||
cmd.small_icon = '../../img/s2logo.png'
|
||||
cmd.large_icon = '../../img/s2logo.png'
|
||||
cmd
|
||||
end
|
||||
|
||||
def self.send_command(app)
|
||||
cmd = MenuCommandHandler.sketchup_command(
|
||||
ActionCommand.new(app, Actions::OneClickSend), 'Send to Speckle'
|
||||
ActionCommand.new(app, nil, Actions::OneClickSend), 'Send to Speckle'
|
||||
)
|
||||
cmd.tooltip = 'Send to Speckle'
|
||||
cmd.status_bar_text = 'Send to Speckle'
|
||||
|
||||
@@ -8,7 +8,7 @@ module SpeckleConnector
|
||||
module Commands
|
||||
# Command to update preferences.
|
||||
class UserPreferencesUpdated < Command
|
||||
def _run(data)
|
||||
def _run(_resolve_id, data)
|
||||
preference_hash = data['preference_hash']
|
||||
preference = data['preference']
|
||||
new_value = data['value']
|
||||
|
||||
@@ -1,8 +1,19 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module SpeckleConnector
|
||||
SPECKLE_BASE_OBJECT = 'Speckle_Base_Object'
|
||||
SPECKLE_MAPPING_TOOL_SCHEMA = 'Speckle_Mapping_Tool_Schema'
|
||||
SPECKLE_SCHEMA = 'Speckle_Schema'
|
||||
|
||||
SPECKLE_SEND_CARDS = 'Speckle_Send_Cards'
|
||||
SPECKLE_RECEIVE_CARDS = 'Speckle_Receive_Cards'
|
||||
|
||||
SPECKLE_ID = 'speckle_id'
|
||||
SPECKLE_TYPE = 'speckle_type'
|
||||
APPLICATION_ID = 'application_id'
|
||||
TOTAL_CHILDREN_COUNT = 'total_children_count'
|
||||
CHILDREN = 'children'
|
||||
PARENT = 'parent'
|
||||
VALID_STREAM_IDS = 'valid_stream_ids'
|
||||
INVALID_STREAM_IDS = 'invalid_stream_ids'
|
||||
end
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module SpeckleConnector
|
||||
VECTOR_Z = Geom::Vector3d.new(0, 0, 1)
|
||||
end
|
||||
@@ -0,0 +1,22 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module SpeckleConnector
|
||||
MAT_DICTIONARY = 'Speckle_Connector_Materials'
|
||||
MAT_ID = 'Speckle_Connector_Material_Id'
|
||||
|
||||
MAT_ADD = :speckle_connector_add_material
|
||||
MAT_EDIT = :speckle_connector_edit_material
|
||||
MAT_REMOVE = :speckle_connector_remove_material
|
||||
|
||||
DEFAULT_COLORS = {
|
||||
MAT_ADD => '#66FF66',
|
||||
MAT_EDIT => '#FFFF9F',
|
||||
MAT_REMOVE => '#FF6666'
|
||||
}.freeze
|
||||
|
||||
DEFAULT_NAMES = {
|
||||
MAT_ADD => 'Speckle_Material_Add',
|
||||
MAT_EDIT => 'Speckle_Material_Edit',
|
||||
MAT_REMOVE => 'Speckle_Material_Remove'
|
||||
}.freeze
|
||||
end
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user