Sign in to follow this  
Guest Vorlin

Critique please: Power of macros & Formatted Text

Recommended Posts

Hello all,I did start to study C++ today but I was feeling restless since I haven't built anything in quite some time. So, about six hours ago, I started on a bull rush.Yea, you all know how that goes. I have to work tomorrow, yet here I am finishing code at midnight.It all works perfectly. I don't need any help with it. What I would like is a critique of how I implemented formatted text and macros. This is my first try at making these puppies into serious work horses and I'm wondering what I might have done better, cleaner, more efficiently, etc.As always, thanks for any tips and insight!(P.S.: I made those huge gaps between sections purposely to make it as easy as possible to read and follow.)Scott / Vorlin***************************************<!DOCTYPE Gauge SYSTEM "file:/C:/Documents and Settings/SS/My Documents/Visual Studio 2005/DTDs/FS9XML.dtd"><Gauge Name="Vizor" Version="1.0"> <Update Frequency="6"/> <Image Name="Mainbg.bmp" /> <!-- Lights that indicate if one of the 3 windows is ready to be set --> <Element> <Position X ="39" Y="56" /> <Visible> 1 (L:SetDisp,number) == </Visible> <Image Name="light.bmp" /> </Element> <Element> <Position X ="126" Y="56" /> <Visible> 2 (L:SetDisp,number) == </Visible> <Image Name="light.bmp" /> </Element> <Element> <Position X ="213" Y="56" /> <Visible> 3 (L:SetDisp,number) == </Visible> <Image Name="light.bmp" /> </Element> <!-- "Assign" This actually assigns the chosen gauge variable to the chosen large window. This was originally a CASE setup but it stubbornly refused to work for reasons still unknown.--> <Macro Name="assign"> (L:SetDisp, number) 1 == if{ @1 (L:ScrollPos,number) + (>L:1L,number) } (L:SetDisp, number) 2 == if{ @1 (L:ScrollPos,number) + (>L:2L,number) } (L:SetDisp, number) 3 == if{ @1 (L:ScrollPos,number) + (>L:3L,number) } 0 (>L:SetDisp,number) </Macro> <!-- "Variable Display" Lists the possible variables to choose from for the 3 large windows --> <Macro Name ="VarDisp"> %( @1 )%{case} %{:0} %{:1}%( (A:ADF CARD,degrees) (A:HEADING INDICATOR, degree) > if{ (A:ADF CARD,degrees) (A:HEADING INDICATOR, degree) + dnor } els{ (A:ADF CARD,degrees) (A:HEADING INDICATOR, degree) + dnor } ) %!03.0f! deg %{:2}%((A:Eng1 Oil Pressure, psi))%!3d! psi %{:3}%((A:ENG1 OIL TEMPERATURE,celsius))%!3d! c %{:4}%((A:FUEL TANK CENTER LEVEL,percent))%!3d!%%% %{:5}%((A:Eng1 Fuel Pressure, psi))%!2.1f! psi %{:6}%((A:HEADING INDICATOR, degree))%!03d! deg %{:7}%((A:Autopilot heading lock dir, degrees))%!03d! deg %{:8}%((A:Airspeed indicated, knots))%!3d! kts %{:9}%((A:Kohlsman setting hg, inHg))%!5.2f! %{:10}%((A:Indicated Altitude, feet))%!5d! ft %{:11}%((A:Eng1 N1 RPM, percent))%!3d!%%% %{:12}%((A:NAV1 OBS,degrees))%!03.0f! deg %{:13}%((A:NAV2 OBS,degrees))%!03.0f! deg %{:14}%((A:Eng1 Transmission Pressure, psi))%!3d! psi %{:15}%((A:ENG1 TRANSMISSION TEMPERATURE,celsius))%!3d! c %{:16}%((A:Rotor rpm pct:1,percent) d 0 == ?)%!03d!%%% %{:17}%((A:ENG1 TURBINE TEMPERATURE,celsius))%!4d! c %{:18}%((A:Eng1 torque percent, percent))%!3d!%%% %{:19}%((A:Vertical Speed, feet per minute))%!4d! fpm %{end} </Macro> <!-- "Title Display" List of possible titles for the 5 small menu windows --> <Macro Name ="TitDisp"> %(@1)%{case} %{:0}Ready %{:1}ADF %{:2}E Oil P %{:3}E Oil T %{:4}Fuel %{:5}Fuel P %{:6}HDG %{:7}H Bug %{:8}IAS %{:9}Khols %{:10}MSL %{:11}N1 %{:12}OBS 1 %{:13}OBS 2 %{:14}T Oil P %{:15}T Oil T %{:16}RPM %{:17}TOT %{:18}TQ %{:19}VSI %{:20}INOP %{end} </Macro> <!-- Write the title text to each of the 3 large windows --> <Element> <Position X ="0" Y ="12"/> <FormattedText X="300" Y="110" Bright="Yes" Font="arial" FontSize="14" Adjust="Center" Color="#101010" LineSpacing="14" Tabs="0L,63C,149C,236C"> <String> t @TitDisp((L:1L,number)) t @TitDisp((L:2L,number)) t @TitDisp((L:3L,number)) </String> </FormattedText> </Element> <!-- Write the variable gauge values to the 3 large windows --> <Element> <Position X ="0" Y ="26"/> <FormattedText X="300" Y="110" Bright="Yes" Font="arial" FontSize="14" Adjust="Center" Color="#101010" LineSpacing="14" Tabs="0L,63C,149C,236C"> <String> t @VarDisp((L:1L,number)) t @VarDisp((L:2L,number)) t @VarDisp((L:3L,number)) </String> </FormattedText> </Element> <!-- Assign titles to the 5 small menu windows depending on scroll position --> <Element> <Position X ="0" Y ="72"/> <FormattedText X="300" Y="110" Bright="Yes" Font="arial" FontSize="14" Adjust="Center" Color="#101010" LineSpacing="14" Tabs="0L,62C,103C,150C, 196C, 238C"> <String> t @TitDisp(1 (L:ScrollPos,number) + ) t @TitDisp(2 (L:ScrollPos,number) + ) t @TitDisp(3 (L:ScrollPos,number) + ) t @TitDisp(4 (L:ScrollPos,number) + ) t @TitDisp(5 (L:ScrollPos,number) + ) </String> </FormattedText> </Element> <Mouse> <!-- Increment scroll position of the small menu windows by 5, effictively turning the page --> <Area Name ="Decrement" Top="74" Left ="267" Height="8" Width ="14"> <Cursor Type="Hand" /> <Tooltip>Scroll Up</Tooltip> <Click Repeat="Yes"> (L:ScrollPos,number) 13 <= if{ (L:ScrollPos,number) 5 + (>L:ScrollPos,number) } els{ 0 (>L:ScrollPos,number) } </Click> </Area> <!-- Decriment scroll postion of the small menu windows by 5, effectively turning the page --> <Area Name="Increment" Top="73" Left ="18" Height="8" Width ="14" > <Cursor Type="Hand" /> <Tooltip>Scroll Down</Tooltip> <Click Repeat="Yes"> (L:ScrollPos,number) 1 >= if{ (L:ScrollPos,number) 5 - (>L:ScrollPos,number) } els{ 15 (>L:ScrollPos,number) } </Click> </Area> <!-- Arms large window 1 so that it's active and ready to be assigned a gauge to repeat.--> <Area Name="Increment" Top="56" Left ="39" Height="10" Width ="46" > <Cursor Type="Hand" /> <Tooltip>Set Display 1</Tooltip> <Click Repeat="No"> 1 (>L:SetDisp,number) </Click> </Area> <!-- Arms large window 2 so that it's active and ready to be assigned a gauge to repeat.--> <Area Name="Increment" Top="56" Left ="126" Height="10" Width ="46" > <Cursor Type="Hand" /> <Tooltip>Set Display 2</Tooltip> <Click Repeat="No"> 2 (>L:SetDisp,number) </Click> </Area> <!-- Arms large window 3 so that it's active and ready to be assigned a gauge to repeat.--> <Area Name="Increment" Top="56" Left ="213" Height="10" Width ="46" > <Cursor Type="Hand" /> <Tooltip>Set Display 3</Tooltip> <Click Repeat="No"> 3 (>L:SetDisp,number) </Click> </Area> <!-- Menu Choice button 1 --> <Area Name="Increment" Top="87" Left ="56" Height="8" Width ="14" > <Visible> 0 (L:SetDisp,number) =! </Visible> <Cursor Type="Hand" /> <Tooltip>Select</Tooltip> <Click Repeat="No"> @assign(1) </Click> </Area> <!-- Menu Choice button 2 --><Area Name="Increment" Top="87" Left ="97" Height="8" Width ="14" > <Visible> 0 (L:SetDisp,number) =! </Visible> <Cursor Type="Hand" /> <Tooltip>Select</Tooltip> <Click Repeat="No"> @assign(2) </Click></Area><!-- Menu Choice button 3 --> <Area Name="Increment" Top="87" Left ="143" Height="8" Width ="14" > <Visible> 0 (L:SetDisp,number) =! </Visible> <Cursor Type="Hand" /> <Tooltip>Select</Tooltip> <Click Repeat="No"> @assign(3) </Click> </Area> <!-- Menu Choice button 4 --><Area Name="Increment" Top="87" Left ="190" Height="8" Width ="14" > <Visible> 0 (L:SetDisp,number) =! </Visible> <Cursor Type="Hand" /> <Tooltip>Select</Tooltip> <Click Repeat="No"> @assign(4) </Click></Area><!-- Menu Choice button 5 --> <Area Name="Increment" Top="87" Left ="232" Height="8" Width ="14" > <Visible> 0 (L:SetDisp,number) =! </Visible> <Cursor Type="Hand" /> <Tooltip>Select</Tooltip> <Click Repeat="No"> @assign(5) </Click> </Area> </Mouse></Gauge>

Share this post


Link to post
Share on other sites
Help AVSIM continue to serve you!
Please donate today!

Why is it that we always spot errors *after* we post? LOLYes, I see the goof with ADF. I meant to subrtact in the second line but, oddly enough, the dnor causes it to work just fine as is. I'll get rid of the IF setup and simply add them and use dnor. The goal of that is to see what the adf card is spun to, so that it tells you what is "up".I was looking over the way I wrote to the windows by using a variable to go through the cases... correct me if I'm wrong, but didn't I just use a macro / case setup to emulate an array? It can return text, images, variables and even call other macros.I'm not gloating. I'm slightly confused. I didn't conciously set out to build an array but it hit me that this sort of complex case statement that is fed a variable to get a value works in a way that is so close to an array that I can't tell the difference.Then again, I barely qualify as a hobbyist coder... so who am I to judge?Thoughts? Comments?ThanksScott / Vorlin

Share this post


Link to post
Share on other sites

Scott,I see your XML learning curve is improving fast :-)I couldn't examine the code in deep, though it looks pretty nice!At first sight I notice you are not using registers at all (s0,s1..l0,l1).For example, this macro can be optimized as follows:(L:SetDisp, number) sp0(L:ScrollPos,number) sp1@1 l1 + sp2l0 1 == if{ l2 (>L:1L,number) } l0 2 == if{ l2 (>L:2L,number) } l0 3 == if{ l2 (>L:3L,number) } 0 (>L:SetDisp,number) An example of using bool math to make a cycling increment from 0 to 15:(L:ScrollPos,number) d 5 + r 15 != * (>L:ScrollPos,number)*********************I'm not gloating. I'm slightly confused. I didn't conciously set out to build an array but it hit me that this sort of complex case statement that is fed a variable to get a value works in a way that is so close to an array that I can't tell the difference.*******************{case} tag applies only to strings, and is different from structure, which is used only when handling bitmaps. There is also a "value1 value2 value3 nCant Testvalue case" construction that may be used in the stack and performs a similar action as {case}.As for array implementation, notice that we can't make use of "real" array coding, which should be something like:(index) sp0 :0 (lVar1{l0}) (>lVar2{l0}) l0 < 100 if{ l0 ++ sp0 g0 }An assignment of 100 var values in a loop. But of course we don't have the possibility to use (LVar{n}) :-(Tom

Share this post


Link to post
Share on other sites

Tom,First, thanks for the feedback. A lot of this learning curve is directly attributable to many people and credit should be given where it's due. Many thanks to you, Jan, Jon, Jordan Moore, Steve Hanley and Bill... and I don't want to forget to mention Nick and Arnie, who contributed with their written work (as opposed to interactive posts).I realized earlier today (at work) that I mis-spoke regarding arrays because my structure has no push or pop ability at all... but then again, isn't that what we do with the stack? lolI'm sure an array *could* be constructed by assembling a lot of other commands to get the job done but it would be hard to set up... and I doubt that the results would be worth all the effort because there are always easier ways than building 600 lines of code to just be an array.I have a few new (new to me) ideas about remote data storage and dynamic retrieval and when I couldn't sleep at 3 AM last night I got a crazy idea about how to store and recall strings. I built the recall mechanism last night and I know from previous discussions here that a substring comp could be used to break a string into a format that could be stored and recalled within FS9.The sad thing is that I can't think of any real use for the silly thing where it would have advantages over simply typing out text. Maybe it could result in a slightly more streamlined way to select from pre-set strings to display... but it would only be more streamlined for the author to write, not for the processor to run. There's a lot of background work going on to make it function.Who knows, by the time I figure out a use for the silly thing, we'll probably have real strings anyway!Regarding sp0, sp1, l0, etc... (is the right term "stack pointers"?):I understand the concept but I need to take a few hours to really play with them and see what I can make happen with them. This feeds into my last point, but first a couple more..."(L:ScrollPos,number) d 5 + r 15 != * (>L:ScrollPos,number)"Nice... I wish I understood it enough to read it properly! This also feeds my last point..."{case} tag applies only to strings, and is different from structure, which is used only when handling bitmaps"Right, but a lot of people get confused by that because many beginners often only know that the tag is available to them, not the structure. Such was my case...."value1 value2 value3 nCant Testvalue case" Man, I was thinking of flying or watching TV tonight... now look what you did. I'll be up half the night running down info on that! LOL"But of course we don't have the possibility to use (LVar{n})"Yes, the ability to dynamically set variables inside of var names and tag attributes would really suprecharge this whole way of doing things. We've been saying it a lot but I wonder how hard it really is for MS to rewrite the parser to handle that. It may not be feasable or it may already be in development... which means a LOT of error testing to make sure it won't explode.Last point:Ton, you mentioned that there is no single SDK or tute that you know of for these structures (case loop value1 etc etc)... do you know of a few that I could learn a little from each?Particularly, I'm digging into the loop structure and will be going into depth on the stack variables... as I also ferret out info on the Value{n}.Thanks for all the help so far! (and any other tips on what to research next)Scott / Vorlin

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this