From cffbb7a0aaa3460eb4c3d08d99f96e35fd56c281 Mon Sep 17 00:00:00 2001 From: lempinen Date: Fri, 18 May 2012 14:08:09 +0000 Subject: [PATCH] Import/Export update (refs #3414) git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@25018 ac1ea38d-2e2b-0410-8846-a27921b304fc --- .../Release/FMUSimulator.write.1.tlog | 15 + .../FMUSimulator/Release/vc100.pdb | Bin 577536 -> 577536 bytes .../FMUSolution/FMUSolution.sdf | Bin 35344384 -> 35344384 bytes .../FMUSolution/FMUSolution.suo | Bin 16896 -> 16896 bytes .../FMUSolution/Release/FMUSimulator.dll | Bin 284160 -> 284160 bytes .../FMUSolution/Release/FMUSimulator.exp | Bin 4707 -> 4707 bytes .../FMUSolution/Release/FMUSimulator.lib | Bin 8542 -> 8542 bytes .../FMUSolution/Release/FMUSimulator.pdb | Bin 2305024 -> 2460672 bytes .../handlers/exports/ExportModelHandler.java | 7 +- .../handlers/imports/ImportModelHandler.java | 290 ++++++------------ .../expressions/ParameterExpression.java | 2 +- .../sysdyn/manager/SysdynGameExperiment.java | 85 +++-- .../representation/IndependentVariable.java | 11 + .../sysdyn/representation/Variability.java | 21 +- 14 files changed, 203 insertions(+), 228 deletions(-) diff --git a/org.simantics.modelica/FMUSolution/FMUSimulator/Release/FMUSimulator.write.1.tlog b/org.simantics.modelica/FMUSolution/FMUSimulator/Release/FMUSimulator.write.1.tlog index 924abca6..1fffa993 100644 --- a/org.simantics.modelica/FMUSolution/FMUSimulator/Release/FMUSimulator.write.1.tlog +++ b/org.simantics.modelica/FMUSolution/FMUSimulator/Release/FMUSimulator.write.1.tlog @@ -83,3 +83,18 @@ D:\Workspaces\Sysdyn\org.simantics.modelica\FMUSolution\Release\FMUSimulator.lib D:\Workspaces\Sysdyn\org.simantics.modelica\FMUSolution\Release\FMUSimulator.lib D:\Workspaces\Sysdyn\org.simantics.modelica\FMUSolution\Release\FMUSimulator.exp D:\Workspaces\Sysdyn\org.simantics.modelica\FMUSolution\Release\FMUSimulator.exp +^D:\Workspaces\Sysdyn\org.simantics.modelica\FMUSolution\FMUSimulator\FMUSimulator.vcxproj +D:\Workspaces\Sysdyn\org.simantics.modelica\FMUSolution\Release\FMUSimulator.lib +D:\Workspaces\Sysdyn\org.simantics.modelica\FMUSolution\Release\FMUSimulator.lib +D:\Workspaces\Sysdyn\org.simantics.modelica\FMUSolution\Release\FMUSimulator.exp +D:\Workspaces\Sysdyn\org.simantics.modelica\FMUSolution\Release\FMUSimulator.exp +^D:\Workspaces\Sysdyn\org.simantics.modelica\FMUSolution\FMUSimulator\FMUSimulator.vcxproj +D:\Workspaces\Sysdyn\org.simantics.modelica\FMUSolution\Release\FMUSimulator.lib +D:\Workspaces\Sysdyn\org.simantics.modelica\FMUSolution\Release\FMUSimulator.lib +D:\Workspaces\Sysdyn\org.simantics.modelica\FMUSolution\Release\FMUSimulator.exp +D:\Workspaces\Sysdyn\org.simantics.modelica\FMUSolution\Release\FMUSimulator.exp +^D:\Workspaces\Sysdyn\org.simantics.modelica\FMUSolution\FMUSimulator\FMUSimulator.vcxproj +D:\Workspaces\Sysdyn\org.simantics.modelica\FMUSolution\Release\FMUSimulator.lib +D:\Workspaces\Sysdyn\org.simantics.modelica\FMUSolution\Release\FMUSimulator.lib +D:\Workspaces\Sysdyn\org.simantics.modelica\FMUSolution\Release\FMUSimulator.exp +D:\Workspaces\Sysdyn\org.simantics.modelica\FMUSolution\Release\FMUSimulator.exp diff --git a/org.simantics.modelica/FMUSolution/FMUSimulator/Release/vc100.pdb b/org.simantics.modelica/FMUSolution/FMUSimulator/Release/vc100.pdb index f79c33fe4d387f5309e2b3728aa32f308d84040d..854213819bcdfa70f89bfb3277f00191ba2f5543 100644 GIT binary patch delta 208 zcmZozpxm%Pd4dUJ_vS?Q|7_AM3=9m+FBupnF!X`31&{_|27$iK{_OiWSPdB%59P*2@{INeaBIKphGH;37>1Z3c{O225=R%xwlNZ3e8{4A?jV7!|g2Hn4F!2u1)^ z@0iKJ&;_J3fVgA3>H)UvjEwoy{~lyhXKdfDdWh||F7Lnh|K2kKrA>gCVY>fHCh_Si z3pivXK+Xe+gMcIu%K|Yo5O0sTz_x6{H5&ODe}mo4BBm^Oh!VY|WxjtBApRvt+D diff --git a/org.simantics.modelica/FMUSolution/FMUSolution.sdf b/org.simantics.modelica/FMUSolution/FMUSolution.sdf index 708fe51d07e594f2936ae6d0657c97f070ef0106..de61e09943bb83a1e827256b41f0b01a455f778b 100644 GIT binary patch delta 3126 zcma*md6-UR9|!RJIWu#{8Dkb>8)JDGW|U=y?7~RdV?>c9GqQy;mMq!6#5cQ<w>8xg!I)H_@160?Y^lV+PF<1bm$Iv=qzCCb@19=F=+nS16t-U`wA6Bo=pSbM)GN~K3j*F}0vlqx9r1)1zr6BMFK^V*xNjzhejr2k%)d#}7EcwSzi zoD?g?=|3^~k{ghOsC0X&M+e)(XUee56VDWq03J+;=LolIic@mw!JZKM_iyIHV~Ejwv@CR`1Z}V%LgVW2HFz>(an9)ty19GXs=fhp?Zr-o z;Xz&c>fMg`oII;vF?We00!thoh;Cl+lpT4NH^%Lb3v|Q=qH^~Q>iZIQ-Rn&Zv?m0j za$nlbYxVq@yR3|eoYas!XZWop&D^D&;x46@*K4Ob*H08`>XvZU?`&3ESe2GbCx;rZ z2`c9gyJ95-7fLs#v^6NmWThu<^u*l1Z+zKJuCKK-J?=L1-?jhs9?s_g7p(NXSptx>RB&7l8(yM}EWF(y#1=U%y?oeIkJvP~hKE z_cRfqgrY-)5rv6xq6iT|L=sU%G*Og@A&L>ji4sIfq7)HJlqTYcGDKOT98sR|5*3Jw zL_AT6s7xdfi9{9R0pdZTDp8H7PShZhh-9KBQHywps7=%%>Js&c`a}bwA<>9@fgv9Xi2mpS`%%EwnRJPaiTrZfk-7f5>F7Fh|a{5#8X5UqAT$< z(T(U%^dNc?&k((cG$NhoO*~8VA^H;ii2lR?;yGdfuMpFS>BJ0TCNYbcP0S(Y5}Cw2 z;#Fckv4B`eEFyfwV&XO8bz%vzlvqYAC$flaVg<31c!O9)yh-E`tBEzlT4Eisp4dRV zMQkKC5u1rE#M?wJv6Xm-*hct?cZu!9d&Canec}V+Lt-b9N9-a#B6brW6MKkHh`q$8 z#6IFP;&b8)Vn6XE@fDFz93T!7hls<(5#np&DDe&PEpd!EPJBn4AigI~5~qmM#1F)e z#81Q-;%DM4agI1o{6btHekCpvmx#;672+!K8}U1FjrfDOPTU~=B>p0961Rxk#NWgn z;_eK1=D;JC1WB-jh%KQ~NE`{1!V)e;Btjx3N}{Ex#7HqIE+wR-l#*B}Epbvt%1SvY zFJ7r26(wFONo7fpM5!VV$b(W$1 zUXmv1(p#RDKGIkENq-q2&&fa;B!lI7c|nFqh76TqGF(Q;i!xG1$!HlPFUeRLC*x&; zOceL~Pm;;{mN_z4GG(5;D)VK5ER;p!lg09yye>;*sVtM_ zk|o))LRQKfvP#~R99b=EWUZ`|^|C?Ul8v%SHp>=yTXJQqyd&GhFYn5Bc~5r8`|^Q& zC_5!jcF9MwTRxUO@`>z~Pi3EcCZEd}vR}TGuOwd%$U!+IhvkTTEl1@W`Bsj}arsV8 z$oFzmPRVKcL4K5<G+E!K@uz>VoRtL5=X+Mu!KtyiI7N%l4vO^F;Yy5O9?3{r6ktch|*U6 EKZnYSUjP6A delta 3527 zcmb8v2~<>70LJnA9&cuN2+SZLpb(=dplFh~;67NITRP;v0+vf6hL&qCqo!DHgGf)! z0wvLM%Ty*cWvJY83DZnd3v;U!BSSG4rtcd$9XfeBr#a{Un>+8#%$s}fJ7dc&HQA8b z_FmdTfk#ZH8X-k*Z*od%5jI%}$t=XtKq30#R9eCUk*x@Ew%r1}67I1SB}8M46+Bl) z3Nb^QvvZukzG+E}u*Nw~PCar-DYV}>B`x%*{!}EbGnv#AqxWR@P%I+Pp~iZym;6L- z(u#g@$EEuCzPcz}ODQt;$=TLso8;pNZ{~T)N9~+F_G(Xjq`;v%gkKmzGoRUYGS5}aDXW@KYIqM%+{`+_2@K;sVu$M`4s7)ser!>!%&-P_W{<)gUN(KC zVu%)^ww&sbvv$>*|N7k~$zYe<^UZL%WQWV;A=%VxO>W-h{$*9|Uvj&FgSdYYcw-O> z{MY{F+ZBtN)^CJ+54S$v!~7D(s&-gDv@ut_tEQ$W9#XoBVnsWhp4eRR7qRl=wGZ8W z|MnTKd&8=A?^Aux+HK;JEo0VY+Bd|A}@mi1f*!5<0hW=Iu?$jSGAxbaMHAB&b_yL?pm?Q5MTY4E7O}px3)F~a_Wt$rar#<)c?;d zXEs<>V_s2nPIH{5+T=DNrMRbB3);->O}fEP4)gMqSYJs4MD*x}zSbCwc+(LcNg{ zC88HmAJiB1L;cYJG!P9!gV7K)6b(beQ4&fJ(YLOrkOhQO)Qip_+F!B@$CuUNY z)FTn3K50NANfe1D4M`&sLmHDNgM$vBcm#*Hj&L_3)xDxk&nrC@(I~Nc9LDB zfH=sfWH;GE_L9%YKC+(_5+^AlpOY`hm*fCBNDh(1pb516(YdD_DKlIhcSVyfD!( zJOLacKn^=hpoBMsg#*gj{Dt>C6DQ+;AmD?^e-Q}aUMC;)kiFp(1drIVipb4i2CQA58QM zPXGrKki!lWDB%rZVTE!wf8jmPH2E-#;p8s@0USI)QEs?0LI26l0``-cgq%3ofP$iM z2_cY#?IdAmPDW0kATLy6bBXYI7EVTKAXgl&Rw95y0mzYr3T*x&ah`SZVL`*qU*tmg zSrp;w^a5CvKpX`vg~jL?1xRlD@=9jWI7YGUd#^Kp NR|Sh~|I6$d0RWPW6@CB! delta 64 zcmZozBiOJ;Z~-Ip|DMg0nHhbV;;%IaF}4RWf-uweAV%h(3Xt6P<(15$ag4&-_g-iI Nt_l{}{+HP^0s#Nl88`p{ diff --git a/org.simantics.modelica/FMUSolution/Release/FMUSimulator.exp b/org.simantics.modelica/FMUSolution/Release/FMUSimulator.exp index c3fff80a4043f638a780e7d37c5d7923e7dc4fb5..ee1787a0ed650408132abdfb883365fb62a6240e 100644 GIT binary patch delta 23 dcmaE?@>qr4hmnavOJv(b_C#hNwK4mLAOKVy2W|iW delta 23 dcmaE?@>qr4hmnclf6wNL?1{`kYGd{fK>%(`3IYHC diff --git a/org.simantics.modelica/FMUSolution/Release/FMUSimulator.lib b/org.simantics.modelica/FMUSolution/Release/FMUSimulator.lib index a19f6f3df6d7688131d6f01552f2b45d2a53e5c0..02ef8e8b7a54a93b69fe9d3e4531e0f417308516 100644 GIT binary patch delta 564 zcmccTbkAvm44bjBk-53WWCv04jh5=1NZie}oQ80Ift2{<(?W&_X|c%?!UD`%BHK1= z3-dD}#ML-~V*dLW7#Nr)8wyKL?h<{2kQA4&uuy=21TG&&W(JVjTTr!TlOKwGgsBaX zlbHNLTnKDfC{O{zh}%#mK@ol0snNK*@51uohV8 zw`4v{s6YxLG*=3)%0X0YvVpV+*m7T>-K;>%O((zR=bGFjt%jrztRM=gfDP=r``l8K z&1F*|U?chEtP#dR+*vD!VicD=#0Gi!LL`-7 umjwY`#sfCSfJ109uL9gX(qRKyEbG*`hCW&*kbKCl8?MMVICxsIv; delta 564 zcmccTbkAvm44a{uxuJpaWCv04jh5=1NZie}oQ80Ift2{<(?W&_X|c%?!UD|ydp2*@ z7UpL{h^uh|#r*d%FfcGpHWZeg+$H)3At^3lVW9v430yvm%nTs4x1egxCO;JW2vZv% zCo%bhxDeQ|P@n>a$r~k%CKvFDPIi?NoZK%filz|clF6$jijjqFB!$4jfs*A2VJ)!G zZ^?X^P=ORgXs#4om4m3*WCLjtu;so$yIFyjn@)bs&o#M6S`A4bSV0s}0UOwL_qnAe zo6D%e6o9-?B?ECnzYN?ysL#O8FqB1cFtUd^!AA1SStE>txU*Ic#V9U$hz;`cg-9yF uE(-#>j0bFt0f*3JUInqVnfcVcJsE8M=Xs&`O%mj1=d|(B(ii!Y2@ucDa diff --git a/org.simantics.modelica/FMUSolution/Release/FMUSimulator.pdb b/org.simantics.modelica/FMUSolution/Release/FMUSimulator.pdb index a6e09bcee7a03f02769538cedcfdac73924ccdd0..8b84aba547aab7015ce1958669cfd69ee1074c01 100644 GIT binary patch delta 94008 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%0DaG(0Yk#sAiMNJHa(3C>ZxnI0)V~V*Zci*R=6& z2%G_ud94jqzq4f^-5Hm4!;jerX<4l%P*?gAfrV}2 zZ->YV3Ud}~D;~#zOYVpk8pd_w-a+6s&E?1d-eTw;RlT6L#CkjvFgvm zI1}671iX{XML=z=3}UOrAG5Q8>g)%KV>IJF{rBN-kXFICx8No4v#tM|fGl7pyc7Z5 zkWer#3)q6?3iz~$bM7s0{DXDj7vtAffv4adWPdN=4SjkvHKl9*X0D(i`{b zpMp=%6f`ai*mV6IylO|GCg6w4-5zE#Y7<@3xHsWm@NFnSea5&(LYwXOh7U-%MndZa zqaSAfuj$lhpr2&4UNHX`@es+^&|9GGBQ0B?6Z~7sj$low3ebwdDYt*5T9^NPj|q4S z98U%dL-L}A%E0cJoC2SpaHY4eQk?<6B;kI#UZ=WDXJF9>%!Iy%--Bz^^A_-JJPU5y zcdLM};UjR{oMw8|Om@|OA!zBYoBDwqO(!EyFuEj`MG?Jq{)ftbG83`RX3n;;Vj zFTQ~N9JdO1eh7T1Pt1F9j2P$t!w?vp2>6>$7sKrg$HaUAPr>g2Xu7o~^waU=C*nOH z&&`5b2b4}nKna@@5I+ZQBOxC{kOHc$Vij%!O{DRznH{yxfS+n0d(F-d!u(VE1OXkJ z`jDH5i>u(9c*uKiq0YbJwjG+P0@eiH0)3y1%X-hF1z7*6hC|jW5c%%#Y{iln;Jev@ z@V=RXrhp$uZiAn#f?Nm{w1MOf1kP;Jw8KvI8)e_keugXh5`YiArsz{_<9<)ay^`u= z!Pj|jxK#1nT3y*rg4+th(g&|nlPKZo2<*(O&%hVZ)Jg%j!fl~#HVFk}`LF*B&&8lg ze|3Z`$fi|W<81ir;#Q&w_zVWaH!_gDdOi|vw<=A6nnr{7&(b+w&8LU65txR62Igq= z+GXf0_;(WSzpedG_yq}<0vga&;3~Mh%IE(-eM6Us`h4@*_*91%@L%^n6|Qkn!POwI zz@>04i>18sP>=$)+k75w{m#bD@JND9knbYUGp5V`mx+!41FqXhKKPTv_P;5dtT_d@ zXolB(C1E=Rj>Ji%y*Z+4pyNnoxD#B1tLHk`vcCnnGki$GbuZL@ID8)bsaj6^@4=O9 zF1Y-;y3&(;8btI8sMb>8C-7SmuHRm_Rpd?Zn-Z?yUbj``E%57WIPLF$eEs0(i$fLj zcJIY!z|X)UeaOTsXcKf5eqzEuLV_{BQRs_%HMM)d;*>S6jdj1CK8AkKe@! zSWV!aY-2vRC4K^5l`-RLqIjE+pT31_nQQ4)eo1ZAF;n0(1U_~G;%Xv2YOL_j-`ABM z%tF%d%oVU3JbJ@FG4Qkq5RT82$%(SLg2(gK%jJ2;8B4k@b@$B zn?PMl3j7NGLc*nhJyGxs{OO#>@@o{Rdx=|#xd3knUV-c27sku^c;J0x>z9kW!Cpb@ z#-km#Em2sbNPES75a^i|U@z+D=0xM*cJ5`|-yt{=-rqp>s&NFr3;9ol_sOnj^{<`b zuR`FfcKq@*HjPG)BU!I3gC%f1aOe5v=M^Tt2mZT+9|yN4UJaiadGScXQ$ZjWH}5ZX z;a4ClBryf-TZuB`p?@vT&5Zl$b~3y#atgAjf^VX^@IP^_BKw4K;fNl!sFmO>uPR)-upJZ9RWL<45|4~1=v8d1b(1_>{VaMv%Sz# z_&y2OSMsb09)=I(lP|yIzmwN?dGXYTS-_ic3-~X|!0#0NPU1y4K3l`R1^)tPuN2Go z1=xK3HUj3w#{DX<@pXPEt4$n+ZKRWeHV}Omu70jAXk34w+kV47Nmexp#2*>tex;L&yrxQ&UfLDX-nWU*gGu!WjOvS zG6Ih#{Kmke&yRd-O&{=1xHtTpA*bR$?}Ve_Yy38ecfuwF7LvA7q^~)?9{6@_W6ymX ze+_;?me#td_n{-+=15{fBH-KjUNW!^wfTV0;2pRWRPda!C4Bw>K0nZc`}~Kjs21JC zGVp&p?Q1KF+tJ4T-%gtaADR^q8?APrnFqIl$hcSF{we}i!z`bgBZI%g_f2Xb3uvh= zg+74~Pq;r<`xL%M!u`2gb?0~Z_A;9Qp25nyi3+HYNCoT%KRMz1-Kky@?QsD7*o0pT zw_jnJ2tOj>pTo0WR4u*vQOg^LkKhC71=_io6McTWo{Nd+zdb%FzCULR5Mm5PelZS!ee>Fz8uE8wocqdg{mR?HPcb_Y1schk3hQP zmkBMwTX0Pl_F1pKfWO1*11$=W6WXWFtJodOglqa({7S+$2)r(rb^`bOOv$6Z+rwW; zc-pz&8k~i~qa@ zr^9cci3hv*zxgR@W&Efxrhr{r~G}#mKFRP+(tsBQoush{HHYDLcp9T;NYyo-x9pP){Py1T|n;_6q0fXUR&onb1@V%fBJ~HFhO~q|vasgb; zt6)6*jd;6{H4}mDBF_ahR@=|P&4rr@EdzfKWEuP+(rZCu3Tnaf^~}fi*`OQ_p**j7 zB;gzctN_cv*YJPfci?1tFvD}(p5G6@GT~R>S8UIJ4!^9HS4)3G!1m`4BcQ(`=?fUX zR3?f2c>m7j{E-D+Rq)+xF1)$*fUTP6!RN$f#00))6M~8>Q0BBlkkTF zk1o3yKDywc{L<#DWZY#!;NYzeYZS6)?tRq#1E zkL8ziL}Je_{TqRqxqy<#6B4t~gw1H8g!@CR^S3CMzD5&NLdy7`_mRat%Hhs(;92=K z58Q9KRXM*KY>VWk{?&yKwF@kI6?8;KTqGMcezvnhWc9peyksfKxi_A%m=&^ zj)ngaW?hW8!GgB^o&=wnaP=~?;F0k2Rld)_KLdF#0+W*r8t15(sLosP?e)~ zVtR+eTwx>SrtnG5|AL&lk$G`<1P=G9d9Q91_q^mS6fpxyzjEnaYEa>d_Ys@#cZENnaD9u^7BqXn^#rI-e+?D1>3&2%z7qOaBA}tt z+PLe0I1u&WiUuBqE%y|StLD=N#y@cFxwpWr@U3F9{D1EwPY>iPA?bWC6Lmsd1wKy( z!RNBi%0)XHtKkdq*}6zD1^trk5AZOzIqsKi6RX>l^S}0D8At*1(!=3bgzSp~{NLF) z0e(TkcW=;z*kC8ZXXqor@?X%PPq7zOKSW?3nn1w>q(Haq^Jnl836}-zFORQ+4^Ox( zuzsdM+d<{h(1be+R7=CQE$1g3-pR}Yd%{Nr^{h_(*-DMmnY#PKZAoS6{ZANO1lOTi z^Sy}i?^6Vn&tKk-d%lZBAH8Mb|5Bz9}6O8-q_gMI_h;yzcl8Ryc-vz z;RhyMHLwc23EwZ_z5+XrDCb{AHb)LWNuaSr8t;L?QBt2^0;++nSQ_Ay0xh^-a(xQF zH{+_Mf-Gc<+SPEa4HS%r{lBeh>qZuPKNFCX*%3?`u3e0Raqnce!qW;!0ULdOe|Qyy6F}0tuv7MNbOG&+=qaT<(7fw zYbp_%=;!cl4P>u==d%K?#fcAozOUP>9DaA>90Z~Q^go$MM`pUPF#;F!S_qU%k2AlT z4{QRTlkhGxxsdguo8jN$lk$rFD&}uXt|f3ipqF#?e;o$fG2FWd*wkwoOxzWrEW5UQ zmrK8;n|cLR0lWXdDg54qpMrvxe|Pwuj)(F0K?KanHbX#XJidU>f4R`@Wu9_dl2nv=;yj5R?+FVGrSjTC(P{V0IxJ%r|X z6C5L!D*D?XUZ5vQ^!ZK%So%vK=g(YS%w~7Nw@&z`Z0Kz+xDU<|Ku!9y;MO3okB@Uf zMe83^z@O2K+`k;wXBCnd_iMua;Im<}jt#}KfOW$|;b$d$2Qsp|W=F$M7MK571{X}` zL)OoKkHC9;>f^ZI`P_X#RM2y;;Ac#g)^wB`g6}2UPAHc)#)-q=AMWw{ZlYzfG(I1J%XsZiG(PgC z!UryZ&rSH{aPxuh!_`DSz5e*S<+jPeQULpV0cmIo3_zeI1qQ-fQeZoHOA7n~ez)3R z!F)gp*n;6n1Tawu#x-5rdg0gb8xroP>&}N12N;^*eZt9O%u%-ufANDB1Iu2m6G z0iJ81>K3l>^Rn=(60U*DR>fDsWg(y5|4>(-iR}Mn;=x3_Yo*&_ThZc5^vI#n%Xymz z@5N8SkI0Dmh$>(+=%3+Z6TSi-RpO5YA6Dgg30eolPD+Av|dM|~43s-Fwd<881 zn{Zq6HOH&Fd^?=Og$#TFR>KkSGXgCXkO^%Z7zv-2aK9>^2Hz&(?jW*SdJuu{X98YB z>jjU)&rZ1S1y91yOt_z}pMpge%o1yS6BhI<+=Rb!3CgZ-1J8?}_ zSPWld_qz`BuboibhJbmnW#Ieq?QpwpuSGxR6m3ee_lq{moh&FY2Yz%?ftvmQr3kcS zfh*uGS>QeR9$5j+DKOx8PD0tt4o1d&C_MkKwYU-tLEs}s1ut+SL!TW&eFMHY;rGGq zhQuBx#6u{bUbCq+=yw|9&Fel~(IQ8o>KBzCATWfBUce7Dy-uYYDitBG0X||Q<#2dg zx~Vd^Ci2~QEL=M$$EziO()lz3$J7dx8gEl^>PV&1XYd^p{+qy~%Z@s|<=ONI_&Cx_ zxu_uh&-c^Q5O^|!R)c=Gs%SM3vhcaQ78#UErv)Ar{1g1}gg+m6RPfemiGu3?Qov03 z1Of*p8F&S|PcP?f7gefFKN$WE(kn!jBDdM}8}RKS4qWBeJOQyA0ybM&2ELyk4_`(a zSs>Oa7GOj5X>gr_d9Jy{EVvkcUcp28;R^_+?|TSHL!W`4Oa`1$&i`VcDd;WO2;W5I z5t_5m_u+qo#U_m9hbHKpCAbQK-{%6nA*cp+J}@8tTdu_n0uB|hq4)>z=M(NLFy+kH z#7dd(|9uS}MBss#Z?h(T6uuVc_bp4+klUCwJ+ft}z{0ovbc;1xI(ftC~)K9ff@*d&~T$`zu5ETs8E7C00> zH{p+8;P(G;?Uc@u|5bUnqUlkHoWRH81kTsj|%LMz&S|3;7rsuyuZP<>uphjf@c(F-%$o3^rgEugZT)LaI1K?? zGAWsYx6sA#`?A?E)~U7v^WhhfM*d-3v#nL&2k`2gL_lXaR)eb%n4NI{4T#|jnqO4n zx50vY!>x%-ffZQ9n((*<*ngZp6HLHQHusT1@Hx0OfxLVGpVdSU!58wXU|b_%@65}W z!Naki;~EKjX40=MVE=EMN6Wx3Do?$(xZ$7z75qrp=7;6do6R(VMor0Y0Dn2*Y64qT zcc~)qTq59`pey{@g!?9VYhk%`8U?A1O+j(nJ8pPgIqZr&_e;9!;RqZ+Vg<`UHMBOI z3?CbD&ShegZiMfaaGBT|Cs^K5kDiHY_t?&<8QDD{DxY}O|)ZN~46Rh6~-=q~@fomf3K^9Q? zL4nV>@z~Oh!&Pv9<521ReZ$Y;E!{V~cXYG&4XZ&bS>P!IZsb)FW;)%D0>;Grb06>poC(K@HTU(zdy+;OUI8DF@ch2v(ytDwFSl*C61nC5o7&B& z@7s1)enxcZ4m0X6E;l`RTz!XOqdV|`J8>*=AL2OTzQp~AhY%+c4<#N(q?pohULRwo ze4KdGr24i?znod$wr$fp)%xyByFXNaO}WhlO?N(0zoKc$>iSC4vt4`7s~gc_>3$#9 zkF9IE@$>pAo%SSyk;GBNy*e~){zd(HO@CZn|9IW(_DxqWtFIq&HFjR0hCGkVzzla|ZKPG-c{FL|^QJb63iC+-^P5hGh74bjB)kK{Qw;|RM%fzvq5y+IMK``(^zZZ9Z+f?#udWo0prm{HlJZz0~@T_vg@t*X|FmTk5up+L1*7 zgJX|F`D=L$FB9&LBaOUcAsxK(7u4^|b*7M!oB;N}t7)&v^}B5K)QRLpe|V8a`ouou zfg7Gf@k_XNNtdR%lk0y}H@tU9=M7Fn6{l@gUG9MsnmenWaiW!$lec|!L^mV z-qX41+GFYm?lK73X*}#RgKN`}JB#;yxHgPC%&&68r#siXGoP*`KE(C;y!Ie|+-2$8 z$JC$LrpmRI#5cLNn6#6KACu3Ulv5%7A`Uc8;{7!0x0)auEWXM+BWnb7{3dZcaev|g z!~=;FhzAkV9`FRc;8(;aiA^hytM9V3`>gtR%C0-e=|BGe4*q|~!I$FTKW)==%}4c9 z?psxVW1DsErxz6CPycEM+H5^yN8aiT#NEJFo&Az?*@@ZHR-2+Y+}UZciLc+<`cR z_%-5C;@62g5_cl*O#B9M7viqOVZ_~tyA$^yHgvf6+TLfhTRP#Z`o{majWDEZ(+gYn zZr`-T8k^Sncl{}CE@_(n@A^Az2D)?j?&X2Sw9{HozjOE_y&qby X^}OrL1ONMZRC(Vyen|^)@4Ej3pVvNx delta 24617 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%0DhI>`c}a z(xiLacPja6kR*I4ct6(GuvX Q#cry*Bb(|z*JTK=63OYyJ+^5`4nGa%>x&B>o1 zA@`N@g?l0Q{#O_rcQ*}|gbp0X$6F=VFet!zIQ|~wQ&@A(Za!j>z`@D*bR5J|tH(-l z>5}IcUTx*y&E;HH3KpxIfeA;$^EnFhw&mv@y;i_D@Z;ZHy{)n@DDdhN1uYZvb zoC!f|5B=|ugsC^k3pTOb>jSq!-unjmhaR~}$GL<@>80`T#Wf@F!vo}F9op)_wXhyr zAb+n_=972bh=f)>&O(l*VsJ1Soz9=vhdX8UvePMRT(QocS|qDOdpNgh*2g-n z>g5Ed%A=}oz111R7j&YZvr}cJa|%x#&!^o7D+b!tM>3sR;)*-<^zB$@hO|o()TBvW z-jUX)J54T!Q!i`Uz3FedAh{x)vTR9*uCr0tvCB`m=}%E@7wvpQvQ?uuFM-XV4iKoM z&u?;eU7za=UfsnB#EQ)mcE>ZGrvPR&4O8dWQ0oyM$11sne>3y@ef~ zvTCTc%V~*vEbACT6XrXeYX5R)V^8(;ZO%Fg-%DI{TbFOC;N~vj)U?1^A@0(v!@hGG zH0ro6&P|&2jZXQN8`TP4=_mXoT)oO;BbDM0KAFqC;6D}%{VOmF)mt3S4s&eX>)AA=0EcR+DEF4^;*nox|7P!Y{6}1>s<4?69yB|6lWx{n&-O z(ej)wOI<0>Dv=tdb;(opL!F0ZS{B-+Q7stQB|gyGg(|%|VS;n5#{W6kZw=T{(model, l0.HasName, Bindings.STRING )); ArrayList> roots = new ArrayList>(); @@ -108,7 +111,7 @@ public class ExportModelHandler extends AbstractHandler { TransferableGraph1 tg = graph.syncRequest(new TransferableGraphRequest2(roots, model)); try { - Files.createFile(new File(selected), Bindings.getBindingUnchecked(TransferableGraph1.class), tg); + DataContainers.writeFile(new File(selected), new DataContainer("sysdynModel", 1, new Variant(TransferableGraph1.BINDING, tg))); } catch (RuntimeBindingConstructionException e) { e.printStackTrace(); } catch (IOException e) { diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportModelHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportModelHandler.java index ccecf5bb..03c8bc65 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportModelHandler.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/imports/ImportModelHandler.java @@ -13,8 +13,7 @@ package org.simantics.sysdyn.ui.handlers.imports; import java.io.File; import java.io.IOException; -import java.util.HashSet; -import java.util.UUID; +import java.util.HashMap; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; @@ -25,12 +24,13 @@ import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.MessageBox; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.handlers.HandlerUtil; -import org.simantics.databoard.Bindings; -import org.simantics.databoard.Files; -import org.simantics.databoard.binding.error.RuntimeBindingConstructionException; +import org.simantics.databoard.binding.Binding; +import org.simantics.databoard.container.DataContainer; +import org.simantics.databoard.container.DataContainers; +import org.simantics.databoard.container.DataFormatException; +import org.simantics.databoard.container.FormatHandler; import org.simantics.db.Resource; import org.simantics.db.WriteGraph; -import org.simantics.db.common.request.ObjectsWithType; import org.simantics.db.common.request.WriteRequest; import org.simantics.db.common.utils.NameUtils; import org.simantics.db.exception.DatabaseException; @@ -38,16 +38,8 @@ import org.simantics.db.layer0.adapter.impl.DefaultPasteHandler; import org.simantics.db.layer0.adapter.impl.DefaultPasteImportAdvisor; import org.simantics.graph.representation.TransferableGraph1; import org.simantics.layer0.Layer0; -import org.simantics.layer0.utils.direct.GraphUtils; -import org.simantics.modeling.ModelingResources; -import org.simantics.operation.Layer0X; -import org.simantics.simulation.ontology.SimulationResource; -import org.simantics.spreadsheet.resource.SpreadsheetResource; -import org.simantics.structural.stubs.StructuralResource2; import org.simantics.sysdyn.SysdynResource; import org.simantics.sysdyn.ui.Activator; -import org.simantics.sysdyn.ui.utils.OldTransferableGraph1; -import org.simantics.sysdyn.ui.utils.SheetUtils; import org.simantics.ui.SimanticsUI; /** @@ -57,20 +49,20 @@ import org.simantics.ui.SimanticsUI; * */ public class ImportModelHandler extends AbstractHandler { - + public static String IMPORTMODELTPATH = "IMPORT_MODEL_PATH"; @Override public Object execute(ExecutionEvent event) throws ExecutionException { - - Resource project = SimanticsUI.getProject().get(); + + final Resource project = SimanticsUI.getProject().get(); if(project == null) return null; // Get imported transferable graph file using FileDialog final Shell shell = HandlerUtil.getActiveShellChecked(event); FileDialog fd = new FileDialog(shell, SWT.OPEN); fd.setText("Import Model"); - + String path = Activator.getDefault().getPreferenceStore().getString(IMPORTMODELTPATH); if(path.isEmpty() || !(new File(path).exists())) path = Platform.getLocation().toOSString(); @@ -79,200 +71,102 @@ public class ImportModelHandler extends AbstractHandler { fd.setFilterExtensions(filterExt); String selected = fd.open(); if(selected == null) return null; - + Activator.getDefault().getPreferenceStore().setValue(IMPORTMODELTPATH, (new File(selected)).getParent()); - - // Get the transferable graph from file - TransferableGraph1 tg = null; - try { - tg = (TransferableGraph1)Files.readFile(new File(selected), Bindings.getBindingUnchecked(TransferableGraph1.class)); - } catch (RuntimeBindingConstructionException e) { - e.printStackTrace(); - } catch (IOException e) { - try { - // "Version migration". Use OldTransferableGraph1 if the file was imported using old methods - OldTransferableGraph1 otg = (OldTransferableGraph1)Files.readFile(new File(selected), Bindings.getBindingUnchecked(OldTransferableGraph1.class)); - tg = new TransferableGraph1(otg.resourceCount, otg.identities, otg.statements, otg.values); - } catch (RuntimeBindingConstructionException e1) { - e1.printStackTrace(); - } catch (IOException e1) { - MessageBox mb = new MessageBox(shell, SWT.OK | SWT.ERROR); - mb.setText("Error"); - mb.setMessage("The imported file is not of type: Model"); - mb.open(); - return null; + + + + HashMap> handlers = new HashMap>(); + handlers.put("sysdynModel:1", new FormatHandler() { + @Override + public Binding getBinding() { + return TransferableGraph1.BINDING; } - } - if(tg == null) return null; - - try { - - DefaultPasteImportAdvisor ia = new DefaultPasteImportAdvisor(project); - DefaultPasteHandler.defaultExecute(tg, SimanticsUI.getProject().get(), ia); - - // Check that imported resource was actually a model - //and fix changes made to old ontology versions - final Resource root = ia.getRoot(); - SimanticsUI.getSession().syncRequest(new WriteRequest() { - - @Override - public void perform(WriteGraph graph) throws DatabaseException { - - if(!graph.isInstanceOf(root, SysdynResource.getInstance(graph).SysdynModel)) { - // Imported model was not a SysdynModel, display error message. - Resource instanceOf = graph.getPossibleObject(root, Layer0.getInstance(graph).InstanceOf); - String type = "..."; - if(instanceOf != null) - type = NameUtils.getSafeName(graph, instanceOf); - else { - Resource inheritedFrom = graph.getPossibleObject(root, Layer0.getInstance(graph).Inherits); - if(inheritedFrom != null) - type = NameUtils.getSafeName(graph, inheritedFrom); - } - final String ft = type; - graph.deny(root, Layer0.getInstance(graph).PartOf); - - shell.getDisplay().asyncExec(new Runnable() { - - @Override - public void run() { - MessageBox mb = new MessageBox(shell, SWT.OK | SWT.ERROR); - mb.setText("Error"); - mb.setMessage("The imported file is not of type: System Dynamics Model (" + ft +")"); - mb.open(); - } - }); + @Override + public Object process(DataContainer container) throws DataFormatException { + DefaultPasteImportAdvisor ia = new DefaultPasteImportAdvisor(project); + try { + DefaultPasteHandler.defaultExecute((TransferableGraph1)container.content.getValue(), SimanticsUI.getProject().get(), ia); + return ia.getRoot(); - } else { - - Resource project = SimanticsUI.getProject().get(); - graph.claim(root, Layer0X.getInstance(graph).IsActivatedBy, project); - - // Do all modifications that are necessary - updateOldConfigurationToBaseRealization(graph, root); - addDefaultOntologyLinks(graph, root); - addURIsToDiagrams(graph, root); - addSpreadSheetBook(graph, root); - } + } catch (Exception e) { + e.printStackTrace(); + return null; } - }); - } catch (DatabaseException e) { - e.printStackTrace(); - } catch (Exception e) { - e.printStackTrace(); - } + } + }); - return null; - } - - /** - * In old versions base realization was separate. Newer versions use configuration as base realization. - * @param graph WriteGraph - * @param model Imported model - */ - private static void updateOldConfigurationToBaseRealization(WriteGraph graph, Resource model) { - Layer0X L0X = Layer0X.getInstance(graph); + Object result = null; try { - Resource configuration = graph.getPossibleObject(model, SimulationResource.getInstance(graph).HasConfiguration); - if(configuration != null && !graph.hasStatement(configuration, L0X.IsBaseRealizationOf, model)) - graph.claim(configuration, L0X.IsBaseRealizationOf, model); - } catch (DatabaseException e) { + File file = new File(selected); + if(!file.isFile()) { + displayErrorMessage(shell, "File " + selected + " not found"); + return null; + } else { + result = DataContainers.readFile(file, handlers); + } + } catch(DataFormatException e) { e.printStackTrace(); - } - - } - - /** - * Links should be exported and imported automatically. If it has failed, the - * default ontology links sysdyn and layer0 are added. - * - * @param graph WriteGraph - * @param model Imported model - */ - - private static void addDefaultOntologyLinks(WriteGraph graph, Resource model) { - try { - Layer0 l0 = Layer0.getInstance(graph); - // The links should be exported and imported automatically - Resource sysdyn = graph.getResource("http://www.simantics.org/Sysdyn-1.1"); - Resource layer0 = graph.getResource("http://www.simantics.org/Layer0-1.0"); - if(!graph.hasStatement(model, l0.IsLinkedTo, sysdyn)) - graph.claim(model, l0.IsLinkedTo, sysdyn); - if(!graph.hasStatement(model, l0.IsLinkedTo, layer0)) - graph.claim(model, l0.IsLinkedTo, layer0); - } catch (DatabaseException e) { + } catch(IOException e) { e.printStackTrace(); + } catch(Exception e) { + if(e instanceof RuntimeException) + throw (RuntimeException)e; + else + throw new RuntimeException(e); } - } - - - /** - * Add a container for providing URIs to diagrams. - * - * @param graph WriteGraph - * @param model Imported model - */ - private static void addURIsToDiagrams(WriteGraph graph, Resource model) { - Layer0 l0 = Layer0.getInstance(graph); - SimulationResource simu = SimulationResource.getInstance(graph); - ModelingResources mr = ModelingResources.getInstance(graph); - SysdynResource sr = SysdynResource.getInstance(graph); - StructuralResource2 sr2 = StructuralResource2.getInstance(graph); - try { - HashSet configurations = new HashSet(); - Resource configuration = graph.getPossibleObject(model, simu.HasConfiguration); - if(configuration != null) - configurations.add(configuration); - - for(Resource r : graph.getObjects(model, l0.ConsistsOf)) { - if(graph.isInheritedFrom(r, sr.Module)) { - Resource moduleConfiguration = graph.getPossibleObject(r, sr2.IsDefinedBy); - if(moduleConfiguration != null) - configurations.add(moduleConfiguration); - } - } - - for(Resource conf : configurations) { - Resource configurationDiagram = graph.getPossibleObject(conf, mr.CompositeToDiagram); - if(configurationDiagram != null && !graph.hasStatement(configurationDiagram, l0.PartOf)) { - GraphUtils.create2(graph, l0.Library, - l0.HasName, "__CONTAINER__", - l0.PartOf, conf, - l0.ConsistsOf, configurationDiagram); - } + if(result == null || !(result instanceof Resource)) { + displayErrorMessage(shell, "Model could not be imported."); + } else { + try { + final Resource ModelRoot = (Resource) result; + SimanticsUI.getSession().syncRequest(new WriteRequest() { + + @Override + public void perform(WriteGraph graph) throws DatabaseException { + if(!graph.isInstanceOf(ModelRoot, SysdynResource.getInstance(graph).SysdynModel)) { + // Imported model was not a SysdynModel, display error message. + Resource instanceOf = graph.getPossibleObject(ModelRoot, Layer0.getInstance(graph).InstanceOf); + String type = "..."; + if(instanceOf != null) + type = NameUtils.getSafeName(graph, instanceOf); + else { + Resource inheritedFrom = graph.getPossibleObject(ModelRoot, Layer0.getInstance(graph).Inherits); + if(inheritedFrom != null) + type = NameUtils.getSafeName(graph, inheritedFrom); + } + final String ft = type; + graph.deny(ModelRoot, Layer0.getInstance(graph).PartOf); + + shell.getDisplay().asyncExec(new Runnable() { + + @Override + public void run() { + MessageBox mb = new MessageBox(shell, SWT.OK | SWT.ERROR); + mb.setText("Error"); + mb.setMessage("The imported file is not of type: System Dynamics Model (" + ft +")"); + mb.open(); + } + }); + + } + } + }); + } catch (DatabaseException e) { + e.printStackTrace(); } - - } catch (DatabaseException e) { - e.printStackTrace(); } + + return null; + } - - - /** - * Add a missing spreadsheet book to the model - * - * @param graph - * @param model - */ - private static void addSpreadSheetBook(WriteGraph graph, Resource model) { - try { - Layer0 l0 = Layer0.getInstance(graph); - SpreadsheetResource ssr = SpreadsheetResource.getInstance(graph); - SimulationResource simu = SimulationResource.getInstance(graph); - Resource conf = graph.getPossibleObject(model, simu.HasConfiguration); - if(conf != null && graph.syncRequest(new ObjectsWithType(conf, l0.ConsistsOf, ssr.Book)).isEmpty()) { - Resource book = graph.newResource(); - graph.claim(book, l0.InstanceOf, null, ssr.Book); - graph.addLiteral(book, l0.HasName, l0.NameOf, l0.String, "Book" + UUID.randomUUID().toString(), Bindings.STRING); - graph.claim(conf, l0.ConsistsOf, l0.PartOf, book); - SheetUtils.createSheet(graph, book, "Sheet1", new String[] { }, new int[] { 50 }); - } - } catch (DatabaseException e) { - e.printStackTrace(); - } + private void displayErrorMessage(Shell shell, String message) { + MessageBox mb = new MessageBox(shell, SWT.OK | SWT.ERROR); + mb.setText("Error"); + mb.setMessage("The imported file is not of type: Model"); + mb.open(); } - } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ParameterExpression.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ParameterExpression.java index 7d37311f..131705c9 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ParameterExpression.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/ParameterExpression.java @@ -87,7 +87,7 @@ public class ParameterExpression extends BasicExpression { } catch (DatabaseException e) { throw new DatabaseException(e.getMessage()); } catch (FMUJNIException e) { - e.printStackTrace(); + System.err.println("ParameterExpression.java: " + e.getMessage()); return null; } } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynGameExperiment.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynGameExperiment.java index be625aa3..8d82b12f 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynGameExperiment.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynGameExperiment.java @@ -16,6 +16,9 @@ import java.util.ArrayList; import java.util.HashMap; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; import org.simantics.db.AsyncReadGraph; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; @@ -201,36 +204,72 @@ public class SysdynGameExperiment extends SysdynExperiment { @Override public void simulateDuration(double duration) { - if(subscription == null || this.results == null || control == null) - return; - - if(duration <= 0.0) - duration = stepDuration; - - - try { - control.setStepLength(stepLength); // Set step length each time in case there has been changes + Job job = new simulateDurationJob("Simulate steps", duration); + // Start the Job + job.schedule(); + } + + private class simulateDurationJob extends Job { - double time = control.getTime(); - double eTime = time + duration; - double[] results = new double[subscription.length]; + private double duration; + public simulateDurationJob(String name, double duration) { + super(name); + this.duration = duration; + } - while(control.getTime() < (eTime - 1e-9)) { // Substract a very small number, because OpenModelica is not very precise with its Real numbers - - control.simulateStep(); + @Override + protected IStatus run(IProgressMonitor monitor) { + + int nSteps = (int)(duration / stepLength); + int work = 1 + nSteps * 3 + 2; // initialization + number of steps * number of phases per step + set result + call result listeners + + monitor.beginTask("Simulating " + duration + " time steps", work); + monitor.subTask("Initialize step simulation"); + + if(subscription == null || SysdynGameExperiment.this.results == null || control == null) + return Status.OK_STATUS; + + if(duration <= 0.0) + duration = stepDuration; + + + try { + control.setStepLength(stepLength); // Set step length each time in case there has been changes + + double time = control.getTime(); + double eTime = time + duration; + double[] results = new double[subscription.length]; - results = control.getSubscribedResults(results); + monitor.worked(1); - for(int k = 0; k < subscription.length; k++) { - this.results.get(subscription[k]).add(results[k]); + while(control.getTime() < (eTime - 1e-9)) { // Substract a very small number, because OpenModelica is not very precise with its Real numbers + monitor.subTask("Simulate step (time = " + control.getTime() + ")"); + control.simulateStep(); + monitor.worked(1); + + monitor.subTask("Get results (time = " + control.getTime() + ")"); + results = control.getSubscribedResults(results); + monitor.worked(1); + + monitor.subTask("Save results (time = " + control.getTime() + ")"); + for(int k = 0; k < subscription.length; k++) { + SysdynGameExperiment.this.results.get(subscription[k]).add(results[k]); + } + monitor.worked(1); } + + monitor.subTask("Display results"); + sysdynModel.getSysdynResult().setResult(new GameResult(SysdynGameExperiment.this.results, SysdynGameExperiment.this.subscription)); + monitor.worked(1); + + sysdynModel.resultChanged(); + monitor.worked(1); + + } catch (FMUJNIException e) { + System.err.println("SysdynGameExperiment simulateDuration failed: \n\t" + e.getMessage()); } - sysdynModel.getSysdynResult().setResult(new GameResult(this.results, this.subscription)); - sysdynModel.resultChanged(); - - } catch (FMUJNIException e) { - System.err.println("SysdynGameExperiment simulateDuration failed: \n\t" + e.getMessage()); + return Status.OK_STATUS; } } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/IndependentVariable.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/IndependentVariable.java index 0b95bf6b..c2975cb7 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/IndependentVariable.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/IndependentVariable.java @@ -14,6 +14,8 @@ package org.simantics.sysdyn.representation; import java.util.ArrayList; import java.util.Iterator; +import org.simantics.objmap.annotations.RelatedElements; +import org.simantics.sysdyn.SysdynResource; import org.simantics.sysdyn.representation.expressions.IExpression; import org.simantics.sysdyn.representation.utils.FormatUtils; @@ -24,6 +26,11 @@ import org.simantics.sysdyn.representation.utils.FormatUtils; * */ public abstract class IndependentVariable extends Variable { + + @RelatedElements( + value = SysdynResource.URIs.Variable_isHeadOf, + composition = true) + private ArrayList isHeadOf = new ArrayList(); /** * Get the declaration of this variable @@ -150,4 +157,8 @@ public abstract class IndependentVariable extends Variable { return sb.toString(); } } + + public ArrayList getIncomingDependencies() { + return isHeadOf; + } } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Variability.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Variability.java index 8fb226a4..2b85df43 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Variability.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Variability.java @@ -135,11 +135,24 @@ public enum Variability { * @return Variabilty of a variable */ static public Variability getVariability(IndependentVariable variable) { - if(RepresentationUtils.isGameExperimentActive() && !(variable instanceof Stock)) - // FIXME: Game experiment may not be runnable even if normal experiments are. - return getVariability(variable, false, null); - else + if(RepresentationUtils.isGameExperimentActive() && !(variable instanceof Stock)) { + + /* + * Game experiments cannot use as many parameter variables as normal experiments. + * If a parameter variable is changed, other parameter values depending on that + * parameter value are not automatically changed. + * + * Something of a hack: + * Allow variable references, if there are not incoming dependencies to the variable. + * This enables the use of derived variables for initial values of stocks. + */ + if(variable.getIncomingDependencies() == null || variable.getIncomingDependencies().isEmpty()) + return getVariability(variable, true, null); + else + return getVariability(variable, false, null); + } else { return getVariability(variable, true, null); + } } /** -- 2.47.1