<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>TURBU Tech &#187; Delphi</title>
	<atom:link href="http://tech.turbu-rpg.com/category/delphi/feed" rel="self" type="application/rss+xml" />
	<link>http://tech.turbu-rpg.com</link>
	<description>My thoughts on Delphi programming in general, and particularly on the technical aspects of developing the TURBU engine and editor.</description>
	<lastBuildDate>Fri, 27 Jan 2012 19:53:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Job opportunities at WideOrbit</title>
		<link>http://tech.turbu-rpg.com/387/job-opportunities-at-wideorbit</link>
		<comments>http://tech.turbu-rpg.com/387/job-opportunities-at-wideorbit#comments</comments>
		<pubDate>Thu, 12 Jan 2012 14:13:55 +0000</pubDate>
		<dc:creator>Mason Wheeler</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[employment]]></category>
		<category><![CDATA[Personal]]></category>

		<guid isPermaLink="false">http://tech.turbu-rpg.com/?p=387</guid>
		<description><![CDATA[Just thought I&#8217;d throw this one out there.  My employer, WideOrbit, is currently hiring.  We&#8217;ve got multiple development positions open for both Delphi and C#/Silverlight skillsets.  (SQL experience, especially with MS SQL Server, really helps too.)  At WideOrbit we build industry-leading software for managing broadcast media.  If you live in the USA, there&#8217;s a pretty [...]]]></description>
			<content:encoded><![CDATA[<p>Just thought I&#8217;d throw this one out there.  My employer, WideOrbit, is currently hiring.  We&#8217;ve got multiple development positions open for both Delphi and C#/Silverlight skillsets.  (SQL experience, especially with MS SQL Server, really helps too.)  At WideOrbit we build industry-leading software for managing broadcast media.  If you live in the USA, there&#8217;s a pretty good chance your favorite station is running on WideOrbit software, and we built it in Delphi.  (Mostly.)</p>
<p>Our development office is in Lynnwood, Washington, (about half an hour from Seattle,) and on-site work is preferred, though some exceptions do (infrequently) get made on a case-by-case basis.  It&#8217;s a good location, right across the street from a major mall (plenty of places to go for lunch!), with good pay and working conditions.  The office has a friendly, engineer-centric culture, and it really helps that the manager is a former coder and the boss still is one.  No pointy hair here!</p>
<p>Only those who know what they&#8217;re doing need apply.  The developers take an active part in the interview process, and we&#8217;ve got really high standards.  We understand that the only way to develop good software is with good developers, and we try hard to make sure that that&#8217;s all we get.  But if you&#8217;re good and you can demonstrate that you know what you&#8217;re doing, you&#8217;re likely to get an offer.</p>
<p>If anyone&#8217;s interested, send me a resume at <a href="mailto:mwheeler@wideorbit.com ">mwheeler@wideorbit.com </a>and I&#8217;ll see about getting you an interview.</p>
]]></content:encoded>
			<wfw:commentRss>http://tech.turbu-rpg.com/387/job-opportunities-at-wideorbit/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>RTTI Script basic examples</title>
		<link>http://tech.turbu-rpg.com/385/rtti-script-basic-examples</link>
		<comments>http://tech.turbu-rpg.com/385/rtti-script-basic-examples#comments</comments>
		<pubDate>Sun, 13 Nov 2011 21:56:57 +0000</pubDate>
		<dc:creator>Mason Wheeler</dc:creator>
				<category><![CDATA[Delphi]]></category>

		<guid isPermaLink="false">http://tech.turbu-rpg.com/?p=385</guid>
		<description><![CDATA[After a few requests for examples and an assertion in the comments that noting actually compiles or runs, I&#8217;ve updated the repository a little. I&#8217;ve fixed a few bugs in the parser, and updated the executor to support the Environment object.  I added an Examples folder with two simple Hello World projects.  They both display [...]]]></description>
			<content:encoded><![CDATA[<p>After a few requests for examples and an assertion in the comments that noting actually compiles or runs, I&#8217;ve updated <a href="http://code.google.com/p/rtti-script/source/checkout">the repository</a> a little.<span id="more-385"></span></p>
<p>I&#8217;ve fixed a few bugs in the parser, and updated the executor to support the Environment object.  I added an Examples folder with two simple Hello World projects.  They both display a message box with a simple greeting.  The message box, of course, is not built in to the scripting system, so it has to be imported from the Delphi project.  These two sample programs demonstrate the two ways to do this: through external unit registration and with an Environment object.</p>
<p>The rsCompiler unit provides a class called TrsTypeImporter that&#8217;s used to import new types, variables, constants and routines (hmm&#8230; maybe I should change the name to just TrsImporter?) to make the compiler aware of them.  To register a new external unit, call RegisterStandardUnit on the compiler.  It takes two parameters: a unit name and an anonymous reference to a procedure that takes a TrsTypeImporter as an argument.  The first time a unit with that name is used in the script, the compiler will call the method reference, providing an importer to register things with the compiler.  A unit named &#8220;system&#8221; is always used, so if you want to import things that will always be available to the script, call RegisterStandardUnit and use &#8220;system&#8221; as the unit name.</p>
<p>Any units registered with the compiler also have to be registered with the script executor by a similar process.  The interface for the executor&#8217;s RegisterStandardUnit system is not stable yet, but it currently allows you to register your standalone routines in the callback.  I&#8217;ll add support for registering classes and external variables soon.</p>
<p>The second, simpler way to do imports is through the Environment object.  The second sample program shows how this works.  You declare a class and register it with the compiler, and every public method and property on it will be available to the script engine as if they were global routines and variables declared in the &#8220;system&#8221; import.  Then you register an instance of the class with the script executor before loading the program.  (It&#8217;s important to note that the Environment has to be registered with the compiler <strong>before</strong> compiling, and with the script executor <strong>before</strong> loading the program.)</p>
<p>It&#8217;s possible to use both systems together, of course.  If you want to break up your external routines into groups, you could declare and register multiple external units, but still have a group of globally-available methods in an Environment object.</p>
<p>Hopefully these examples will show people how to get started.  I&#8217;ll add some more examples as needed and when I get some more features ready.</p>
]]></content:encoded>
			<wfw:commentRss>http://tech.turbu-rpg.com/385/rtti-script-basic-examples/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>RTTI Script alpha release</title>
		<link>http://tech.turbu-rpg.com/382/rtti-script-alpha-release</link>
		<comments>http://tech.turbu-rpg.com/382/rtti-script-alpha-release#comments</comments>
		<pubDate>Fri, 11 Nov 2011 16:06:57 +0000</pubDate>
		<dc:creator>Mason Wheeler</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[RTTI]]></category>
		<category><![CDATA[Scripting]]></category>

		<guid isPermaLink="false">http://tech.turbu-rpg.com/?p=382</guid>
		<description><![CDATA[Way back at the start of this year, I wrote about how I&#8217;d been working on a new Object Pascal-based script engine built around Delphi&#8217;s extended RTTI system.  And then it got real quiet, because more immediate concerns took priority for me.  But I&#8217;ve gotten to the point in my game engine development where I [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://tech.turbu-rpg.com/284/dynamic-class-creation-moving-beyond-the-theoretical">Way back at the start of this year</a>, I wrote about how I&#8217;d been working on a new Object Pascal-based script engine built around Delphi&#8217;s extended RTTI system.  And then it got real quiet, because more immediate concerns took priority for me.  But I&#8217;ve gotten to the point in my game engine development where I really need to put in the scripting system, so I spent the last couple weeks finishing up the implementation and tuning the performance a little, and now I&#8217;ve got an alpha version ready.  If anyone would like to try it out, they can find it <a href="http://code.google.com/p/rtti-script/source/checkout">on Google Code</a>.</p>
<p><span id="more-382"></span>Note: <strong>This is an alpha version</strong>.  There are probably plenty of bugs in it.  There are still features I haven&#8217;t gotten around to implementing.  The sight of the code would probably send Barry Kelly fleeing from the room, screaming in horror.  So use at your own risk, and I take no responsibility if this causes your system to crash, your data to come out all wrong, or <a href="http://www.catb.org/~esr/jargon/html/N/nasal-demons.html">demons to fly out your nose</a>.  Specifically, the <strong>program</strong> keyword is not implemented yet, (only units,) <strong>var</strong> parameters don&#8217;t work yet, and a handful of features aren&#8217;t implemented in the script executor.</p>
<p>Having said that, here&#8217;s a few cool features I&#8217;ve come up with:</p>
<ul>
<li><strong>Class creation:</strong>  Defining a new class inside the script code is not supported yet, but the basic framework is there, and script units implement new classes with their routines as methods, accessible to the script executor through the RTTI system.  I&#8217;ll add class creation pretty soon.</li>
<li><strong>Automatic registration:</strong> Ever try to register a class with the script engine in PascalScript?  It&#8217;s a painful process involving generating a registration unit that basically redeclares your entire class, and then has to be kept in sync or things break.  (And if you get the dependency order wrong, it fails silently,  leading to weird errors further down the line.)  I figured that was way too complicated, so for RTTIScript, all you have to do is register a class reference, and it uses the RTTI system to figure out the internal members and dependencies for you.</li>
<li><strong>Execution environment:</strong> You&#8217;ll often have a bunch of little standalone routines and global variables that you want to import into a script to have available at all times, to provide an interface between the script and your program.  So I introduced the concept of the &#8220;environment:&#8221; You create a class and register it with the compiler, and it treats all the class&#8217;s public methods and properties as globals for the script.  (This also means that you can use property getters and setters to have the script&#8217;s interaction with its &#8220;global variables&#8221; invoke side effects.)</li>
<li><strong>Script saving:</strong> I know <a href="http://delphitools.info/2010/10/26/why-no-bytecode-format/">Eric Grange thinks that a fast compiler is good enough</a> and a bytecode version of a script is not necessary, but I don&#8217;t agree.  By his own tests, even a very fast script compiler can take 2 seconds to compile a 100,000 line script.  I&#8217;ve actually got an example of one that big in a project that the author wants to convert over once the TURBU project is ready.  Adding a two-second lag into the loading process and making the player wait while a level loads, which should feel instantaneous, is unacceptable.  I don&#8217;t have script saving implemented yet, but it&#8217;s definitely on the to-do list.</li>
</ul>
<p>Anyway, the alpha version is available for any <del>guinea pigs</del> curious developers out there who&#8217;d like to take a look at it.  It requires Delphi XE, it&#8217;s pretty fast, and when I get the rest of the features set up it&#8217;s going to be awesome!  Feel free to check it out, and to <a href="http://code.google.com/p/rtti-script/issues/list">submit a bug report</a> if you find some errors. (Which I&#8217;m sure plenty of people will.)</p>
]]></content:encoded>
			<wfw:commentRss>http://tech.turbu-rpg.com/382/rtti-script-alpha-release/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>A handle leak in TWinControl?</title>
		<link>http://tech.turbu-rpg.com/375/a-handle-leak-in-twincontrol</link>
		<comments>http://tech.turbu-rpg.com/375/a-handle-leak-in-twincontrol#comments</comments>
		<pubDate>Wed, 26 Oct 2011 03:07:41 +0000</pubDate>
		<dc:creator>Mason Wheeler</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Delphi XE]]></category>
		<category><![CDATA[Memory Management]]></category>

		<guid isPermaLink="false">http://tech.turbu-rpg.com/?p=375</guid>
		<description><![CDATA[For the TURBU engine, I&#8217;ve got a custom control that allows me to embed an OpenGL rendering context on a form.  I was working on some new features, and I downloaded gDEBugger, an OpenGL debugging tool, to help out.  One of the things it told me is that my rendering contexts were leaking. They shouldn&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>For the TURBU engine, I&#8217;ve got a custom control that allows me to embed an OpenGL rendering context on a form.  I was working on some new features, and I downloaded gDEBugger, an OpenGL debugging tool, to help out.  One of the things it told me is that my rendering contexts were leaking.<span id="more-375"></span></p>
<p>They shouldn&#8217;t be.  I create the renderer in CreateWnd and I destroy it in DestroyWnd, which should get called as part of the component destruction process.  But as it turns out, DestroyWnd is not actually called anywhere!</p>
<p>By tracing through the VCL code, it looks like DestroyWnd is supposed to get called from a call stack that looks something like this:</p>
<p>TMyControl.DestroyWnd //virtual<br />
TWinControl.DestroyHandle<br />
TWinControl.RemoveControl<br />
TControl.SetParent(nil)<br />
TControl.Destroy</p>
<p>But earlier in the form destruction process, TWinControl.Remove gets called.  It does not call RemoveControl on the control being removed, and at the end of the routine, it says:</p>
<p>AControl.FParent := nil;</p>
<p>By directly setting the field to nil instead of calling SetParent(nil), it makes it so that when SetParent(nil) is called, the entire body of code gets short-circuited, so that RemoveControl is never called.  In fact, it&#8217;s not just my control.  I put a breakpoint on the first line of TWinControl.DestroyHandle, ran the program, and closed it, which generates and then frees almost 30 TWinControl descendants.  <em>The breakpoint was never hit.</em></p>
<p>I&#8217;m seeing this in Delphi XE.  I haven&#8217;t tested it in any other version, but from what I can see, it appears that any VCL control created in XE will never call DestroyHandle during component destruction, leading to all window handles (and other resources, such as my rendering contexts) being leaked.</p>
<p>Can anyone confirm this, or say if it affects other versions?  I didn&#8217;t see this in QC, so <a href="http://qc.embarcadero.com/wc/qcmain.aspx?d=100455">I wrote up a bug report.</a>  Please vote for it, especially if you work on a program with lots of complex forms and have users who would be, shall we say, unamused to suddenly hit an &#8220;out of resources&#8221; error for no good reason&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://tech.turbu-rpg.com/375/a-handle-leak-in-twincontrol/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Wish list: Slicing syntax</title>
		<link>http://tech.turbu-rpg.com/370/wish-list-slicing-syntax</link>
		<comments>http://tech.turbu-rpg.com/370/wish-list-slicing-syntax#comments</comments>
		<pubDate>Fri, 16 Sep 2011 17:47:41 +0000</pubDate>
		<dc:creator>Mason Wheeler</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Wish List]]></category>

		<guid isPermaLink="false">http://tech.turbu-rpg.com/?p=370</guid>
		<description><![CDATA[I&#8217;ve been doing a lot of string processing work lately.  Delphi has a lot of strengths, but unfortunately string manipulation really isn&#8217;t one of them.  It gets really messy really quickly if you&#8217;re trying to do anything complicated.  Extracting substrings out of strings quickly degenerates into a mess of difficult-to-read Copy calls.  It would sure [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been doing a lot of string processing work lately.  Delphi has a lot of strengths, but unfortunately string manipulation really isn&#8217;t one of them.  It gets really messy really quickly if you&#8217;re trying to do anything complicated.  Extracting substrings out of strings quickly degenerates into a mess of difficult-to-read Copy calls.  It would sure be nice if there was a better way.<span id="more-370"></span></p>
<p>There is a better way, by the way.  Python has it; it&#8217;s called &#8220;slicing.&#8221;  You know how in Delphi, you can use array[subscript] notation to get a single item out of an array?  Well in Python you can use an extended version of that to get a subrange (a slice) out of an array.  For example:</p>
<div class="codesnip-container" >
<div class="python codesnip" style="font-family:monospace;">mystring = <span class="st0">&quot;Python string slicing&quot;</span><br />
mystring<span class="br0">&#91;</span><span class="nu0">7</span>:<span class="nu0">13</span><span class="br0">&#93;</span></div>
</div>
<p>returns &#8220;string&#8221;.  (In Python, strings start at index 0.)  Also, you don&#8217;t need a value on both sides of the colon.  If you don&#8217;t provide one, it translates to the beginning/end of the array, as appropriate.  So &#8220;mystring[:6]&#8221; returns &#8220;Python&#8221; and &#8220;mystring[14:]&#8221; returns &#8220;slicing&#8221;.</p>
<p>Now, using a colon here isn&#8217;t very Pascal-ish.  Colons are for variable declarations.  But we do have a range operator that&#8217; s used with arrays: the double dot.  Wouldn&#8217;t it be nice to be able to do stuff like this in Delphi?</p>
<div class="codesnip-container" >
<div class="delphi codesnip" style="font-family:monospace;">name <span class="sy1">:</span><span class="sy3">=</span> <span class="st0">&#8216;Mason Wheeler&#8217;</span><span class="sy1">;</span><br />
firstname <span class="sy1">:</span><span class="sy3">=</span> name<span class="br0">&#91;</span><span class="sy1">..</span>5<span class="br0">&#93;</span><span class="sy1">;</span><br />
lastname <span class="sy1">:</span><span class="sy3">=</span> name<span class="br0">&#91;</span>6<span class="sy1">..</span><span class="br0">&#93;</span><span class="sy1">;</span></div>
</div>
<p>The compiler could translate this syntax to calls to Copy easily enough.  Also, they could improve on the concept a little.  If you feed Python a negative number in a slicing expression, it will error out.  But if Delphi could automatically translate myArray[..-5] into myArray[..high(myArray) - 5], grabbing everything except the last  X number of elements would be that much easier.</p>
<p>Any thoughts?</p>
]]></content:encoded>
			<wfw:commentRss>http://tech.turbu-rpg.com/370/wish-list-slicing-syntax/feed</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>DelphiLive keynote overview</title>
		<link>http://tech.turbu-rpg.com/365/delphilive-keynote-overview</link>
		<comments>http://tech.turbu-rpg.com/365/delphilive-keynote-overview#comments</comments>
		<pubDate>Tue, 13 Sep 2011 20:25:30 +0000</pubDate>
		<dc:creator>Mason Wheeler</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Delphi XE2]]></category>
		<category><![CDATA[DelphiLive!]]></category>

		<guid isPermaLink="false">http://tech.turbu-rpg.com/?p=365</guid>
		<description><![CDATA[I just got out of the DelphiLive keynote, presented by Michael Swindell and various other members.  As you can imagine, it was mostly about XE2 and demoing the new technologies, with a lot of talk about FireMonkey and using it for cross-platform development.  Here&#8217;s what really caught my notice: Michael Swindell opened it up.  He [...]]]></description>
			<content:encoded><![CDATA[<p>I just got out of the DelphiLive keynote, presented by Michael Swindell and various other members.  As you can imagine, it was mostly about XE2 and demoing the new technologies, with a lot of talk about FireMonkey and using it for cross-platform development.  Here&#8217;s what really caught my notice:<span id="more-365"></span></p>
<p>Michael Swindell opened it up.  He was talking about the recent advances in UX (user experience) technology throughout the computer industry, and he explained how FireMonkey is designed to provide a modern interface and user experience.  He had a very interesting story about a dentist visit a few years back.  He went in one day and found that the dentist&#8217;s office was modernizing a lot.  All the medical records were being computerized, moving out of the file cabinets.  He was really impressed when they showed him the new system, especially as the software came from a Delphi shop.  When he went in to talk with the dentist, all his patient records were up there on a big screen, and he was really proud of what they&#8217;d done with Delphi.  Then the dentist tried to show him a new feature and, as Michael put it, &#8220;all the pride turned to shame.&#8221;</p>
<p>He had to grab a mouse and try to use it with one hand, clicking around through the interface, all while trying to hold a miniature camera inside Michael&#8217;s mouth with the other, and it was a big, clumsy mess.  It would have been a lot easier for him if he&#8217;d had a touch-based system on a tablet, or example.</p>
<p>He mentioned that a lot of new interface and display technology is starting to show up on the market.  Samsung, for example, has just started to mass-produce transparent LCD screens.  (He mentioned the movies <em>Avatar</em> and <em>Minority Report</em> as examples of transparent LCD screens in use, which kinda bugged me.  I wish people would stop talking about &#8220;<em>Minority Report</em> interfaces&#8221; as if they were something realistic, because they&#8217;re anything but.  Sure, they look cool in movies, but there&#8217;s a good reason why all successful human interface devices have always required little wrist movement, minimal elbow movement and zero shoulder movement to operate.  Trying to run a real-life &#8220;<em>Minority Report</em> interface&#8221; would wear your arms out very quickly.)</p>
<p>He also mentioned GPUs.  He said that all computers from desktops to smartphones have had GPUs as standard features for the last decade, and they&#8217;ve got more processing power than your CPU, but they generally sit idle.  He said that finding ways to use the power of the GPU is a major focus for Embarcadero.  All the FireMonkey visuals are drawn with the GPU, and they&#8217;re looking into ways to do general-purpose computing on the GPU with Delphi, for a later version.  <a href="http://en.wikipedia.org/wiki/CUDA">CUDA</a> was mentioned a few times as an example of the sort of things that can be done with a GPU, which I find interesting.  CUDA and OpenCL, CUDA&#8217;s non-NVIDIA competitor, both use script languages that look like someone took C and beat it with an ugly stick.  If they could come up with a Pascal-based GPGPU script language, that would be awesome!</p>
<p>After Michael, John Thomas spoke for a while, talking about FireMonkey.  He called FireMonkey &#8220;a full application stack&#8221; that makes it very easy to simply recompile and run on a new platform.  But unlike other cross-platform solutions, FireMonkey a full native code framework; no VMs to slow down execution and limit what you can do with the system.  He also mentioned that all FireMonkey controls are drawn with vector graphics, leveraging the GPU, so everything scales properly. (Even at high DPI! Finally!)  He also mentioned that FireMonkey &#8220;is not a game engine,&#8221; despite all the heavy graphical focus, but it&#8217;s a general-purpose application development framework.  I found that interesting because of what happened next.</p>
<p>Next came a bunch of FireMonkey demos by Anders Ohlsson.  He showed various instances of graphics and 3D objects rotating and moving around on-screen.  One very noticeable issue with the demos was that when he made the window larger, everything got slower.  He mentioned that this was because the animation was linked to the Application.OnIdle event.  I found this a bit funny because &#8220;FireMonkey is not a game engine,&#8221; but if it was, they would have a <em>game timer</em> available, which you can hook into Application.OnIdle to decouple animation from the system &#8220;heartbeat&#8221; and provide a constant rate of speed even with varying levels of processing power.  (I talked to him afterwards and explained the basic principle, and he came back about half an hour later to show me everything running nice and smooth and at a consistent rate on his demos, so that&#8217;s cool.  Maybe someone will make a game timer component for FireMonkey.)</p>
<p>He also showed off an impressive collection of GPU-based shaders that can be applied to FireMonkey objects in real time.  There are shaders that can add color effects, distortions, or transitions from one image to another, and they can be &#8220;stacked&#8221; to apply multiple shaders to the same object or scene.</p>
<p>I went to look at the shader language code that implements the shaders, though, and I was very disappointed to see that they were not implemented with readability in mind.  There are 3 versions of each shader, one for DirectX, one for OpenGL, and one for OpenGL ES (for mobile devices).  The DirectX ones are implemented as byte arrays of compiled shader code, and the GL ones are in ARB (low-level &#8220;shader assembly code&#8221;).  The GLES shaders are in GLSL (a higher-level &#8220;GL Shader Language&#8221;,) but written in a highly unreadable style.  I asked in Q&amp;A if they had deliberately obfuscated the shaders, which makes them hard to read and study and would certainly make it harder for third parties to create new shader effects.  Michael Swindell assured me that that was certainly not the objective, and said he&#8217;d look into it and try to ensure that the shaders were easier to work with in the future.</p>
<p>They talked about a few other things related to mobile development, but it was really the FireMonkey stuff that stood out and caught everyone&#8217;s attention.  As Nick Hodges said yesterday when a bunch of us were talking, FireMonkey is conceptually the correct solution for Delphi cross-platform development, and a lot better than the QT-based idea they were working on last year.  Time will tell how well they&#8217;ll do with maturing it and promoting it, but for the moment I&#8217;m cautiously optimistic for the future of Delphi and the FireMonkey framework.</p>
]]></content:encoded>
			<wfw:commentRss>http://tech.turbu-rpg.com/365/delphilive-keynote-overview/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>XE2: TValue is much faster now</title>
		<link>http://tech.turbu-rpg.com/363/xe2-tvalue-is-much-faster-now</link>
		<comments>http://tech.turbu-rpg.com/363/xe2-tvalue-is-much-faster-now#comments</comments>
		<pubDate>Wed, 07 Sep 2011 17:35:58 +0000</pubDate>
		<dc:creator>Mason Wheeler</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Delphi XE2]]></category>
		<category><![CDATA[RTTI]]></category>

		<guid isPermaLink="false">http://tech.turbu-rpg.com/?p=363</guid>
		<description><![CDATA[About a year and a half ago, I reported on how slow the original implementation of TValue in Delphi 2010 was, touching off a storm of comments and various other blog posts as other Delphi community members conducted similar experiments.  One thing that came out of it was a suggestion by Robert Love on how [...]]]></description>
			<content:encoded><![CDATA[<p>About a year and a half ago, <a href="http://tech.turbu-rpg.com/100/tvalue-is-very-slow">I reported on how slow the original implementation of TValue in Delphi 2010 was</a>, touching off a storm of comments and various other blog posts as other Delphi community members conducted similar experiments.  One thing that came out of it was a suggestion by Robert Love on how to improve performance by adding code to optimize for the most common cases.<span id="more-363"></span></p>
<p>I expanded on his idea and sent a suggested implementation to Barry Kelly.  Unfortunately, it didn&#8217;t make it into XE, but it&#8217;s in XE2 now.  It&#8217;s not exactly the code I suggested&#8211;a few things have changed in the way TValue works internally since D2010, and there&#8217;s at least one bugfix that I can see&#8211;but the basic idea is there.  When storing values into a TValue and retrieving them again, there&#8217;s special code to set and retrieve the most common types directly, without having to go into the generic RTTI-based (much slower) conversion routines.</p>
<p>I reran the timing test under XE2, and the results were much better this time:</p>
<p>Variants: 2140<br />
TValues: 2895</p>
<p>Still about 30% slower than Variants, but at least it&#8217;s not 2000% slower anymore.  Thanks, Barry, and thanks to Robert too for the original suggestion!</p>
]]></content:encoded>
			<wfw:commentRss>http://tech.turbu-rpg.com/363/xe2-tvalue-is-much-faster-now/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>XE2: New Delphi, same old broken installer</title>
		<link>http://tech.turbu-rpg.com/360/xe2-new-delphi-same-old-broken-installer</link>
		<comments>http://tech.turbu-rpg.com/360/xe2-new-delphi-same-old-broken-installer#comments</comments>
		<pubDate>Thu, 01 Sep 2011 18:06:16 +0000</pubDate>
		<dc:creator>Mason Wheeler</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Delphi XE2]]></category>
		<category><![CDATA[Installation]]></category>

		<guid isPermaLink="false">http://tech.turbu-rpg.com/?p=360</guid>
		<description><![CDATA[Since D2009 at least, I&#8217;ve never managed to get a new Delphi release to install correctly on the first try.  Each time, it&#8217;s been the same basic problem.  Each time, I&#8217;ve contacted Embarcadero about it and asked them to fix it.  Unfortunately, they still haven&#8217;t. I got my SA notification and went to install Delphi [...]]]></description>
			<content:encoded><![CDATA[<p>Since D2009 at least, I&#8217;ve never managed to get a new Delphi release to install correctly on the first try.  Each time, it&#8217;s been the same basic problem.  Each time, I&#8217;ve contacted Embarcadero about it and asked them to fix it.  Unfortunately, they still haven&#8217;t.<span id="more-360"></span></p>
<p>I got my SA notification and went to install Delphi XE2 today.  I&#8217;m a SA holder for Delphi Professional, which is what I got a serial number for, which I entered when the installer prompted me for it.  But that&#8217;s not what it installed.  See, if you&#8217;ve had a previous installation of a different SKU level, (a demo, for example, which always seems to be Architect level,) it will disregard the serial number you enter (even though it makes sure that you enter a valid serial!) and install the feature set for what the leftover license file specified.</p>
<p>I&#8217;ve seen a lot of bugs in a lot of software in my day, but there have been very few that <em>mystify</em> me as much as this one.  I don&#8217;t understand how it is possible to screw this up.  Taking input directly from the user and acting on it is the most basic principle of software design there is!  It&#8217;s the first thing any of us learn, usually even before &#8220;simpler&#8221; programs such as Hello World.  You prompt the user for input, and you act on it.  But somehow, the Delphi installer prompts the user for input, and then&#8230; disregards it and acts on something completely different if it&#8217;s available?  What is this I don&#8217;t even</p>
<p>How?!?  This is not an easy mistake to make; you really have to go out of your way to screw something this simple up!  (To add insult to injury, the License Manager tool conveniently provided by Embarcadero, presumably for managing your licenses, can find the invalid licenses, and there&#8217;s a Delete menu item, but it&#8217;s always grayed out.  I&#8217;ve never figured out anything that will actually enable the Delete option.)</p>
<p>It gets worse.  The installer doesn&#8217;t really understand the implications of choosing not to install things.  For example, I chose not to install the iOS development stuff because I have no use for it.  It still spent several minutes downloading the package, which is quite large and whatever server it&#8217;s downloading from doesn&#8217;t have the world&#8217;s greatest bandwidth.</p>
<p>And it will still display and require you to agree to EULAs for bundled third-party components you tell it not to install.  I can&#8217;t help but wonder about the legal ramifications to that&#8230;</p>
<p>Dear Embarcadero,</p>
<p>Your installer sucks.  Please fix it.  It&#8217;s the first impression a new customer gets of the quality of your engineering, even before using the new product, and it makes Delphi look bad.</p>
<p>Sincerely,</p>
<p>Everyone who has to put up with it</p>
]]></content:encoded>
			<wfw:commentRss>http://tech.turbu-rpg.com/360/xe2-new-delphi-same-old-broken-installer/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Odd timing</title>
		<link>http://tech.turbu-rpg.com/351/odd-timing</link>
		<comments>http://tech.turbu-rpg.com/351/odd-timing#comments</comments>
		<pubDate>Wed, 25 May 2011 22:35:33 +0000</pubDate>
		<dc:creator>Mason Wheeler</dc:creator>
				<category><![CDATA[Delphi]]></category>

		<guid isPermaLink="false">http://tech.turbu-rpg.com/?p=351</guid>
		<description><![CDATA[I got an email this morning from Embarcadero, a pretty straightforward marketing letter that probably everyone on SA for Delphi received.  But one thing caught my eye: 64-bit is scheduled to be released this August. That&#8217;s not particularly unexpected, since that&#8217;s when the new releases tend to come out.  But it does confirm one thing [...]]]></description>
			<content:encoded><![CDATA[<p>I got an email this morning from Embarcadero, a pretty straightforward marketing letter that probably everyone on SA for Delphi received.  But one thing caught my eye:</p>
<blockquote><p>64-bit is scheduled to be released this August.</p></blockquote>
<p>That&#8217;s not particularly unexpected, since that&#8217;s when the new releases tend to come out.  But it does confirm one thing I thought was kind of strange when <a href="http://tech.turbu-rpg.com/341/delphi-live-2011-announcement">I got the DelphiLive! 2011 Call For Papers email</a> a few weeks ago.<span id="more-351"></span></p>
<p>The conference is scheduled for mid-September, which means that for the first time, it&#8217;s going to be held <em>after</em> the year&#8217;s new Delphi release instead of before it.  That&#8217;s a pretty sharp contrast with last year, where the keynote address was basically the official RAD Studio XE release announcement&#8230;</p>
<div id="_mcePaste" class="mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow: hidden;"><span style="font-family: Arial; font-size: x-small;">64-bit is scheduled to be released <span id="lw_1306336956_0" class="yshortcuts" style="border-bottom: 2px dotted #366388; cursor: pointer; background: none repeat scroll 0% 0% transparent;">this August.</span> </span></div>
]]></content:encoded>
			<wfw:commentRss>http://tech.turbu-rpg.com/351/odd-timing/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>How default settings can slow down FastMM</title>
		<link>http://tech.turbu-rpg.com/345/how-default-settings-can-slow-down-fastmm</link>
		<comments>http://tech.turbu-rpg.com/345/how-default-settings-can-slow-down-fastmm#comments</comments>
		<pubDate>Sat, 21 May 2011 04:48:22 +0000</pubDate>
		<dc:creator>Mason Wheeler</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Memory Management]]></category>
		<category><![CDATA[Optimization]]></category>

		<guid isPermaLink="false">http://tech.turbu-rpg.com/?p=345</guid>
		<description><![CDATA[One of the biggest challenges in working on the TURBU engine has been minimizing load times.  Some large projects have a whole lot of data to work with, which could take the better part of a minute to load if I tried to load it all up front.  No one wants to sit and wait [...]]]></description>
			<content:encoded><![CDATA[<p>One of the biggest challenges in working on the TURBU engine has been minimizing load times.  Some large projects have a whole lot of data to work with, which could take the better part of a minute to load if I tried to load it all up front.  No one wants to sit and wait for that, so I&#8217;ve pared down the loading so that only the stuff that&#8217;s needed right away gets loaded from the project database right at startup.</p>
<p>And yet, on one of my larger test projects, that wasn&#8217;t enough.  One of the things that has to be loaded upfront was map tile data, so that the maps can draw.  Unfortunately, this project has over 200 different tilesets, and it was taking quite a while to load that much data.  I&#8217;ve got a RTTI-based deserializer that can turn dataset records into objects, but it was taking a completely unreasonable 3.3 seconds to read the tile data.</p>
<p><span id="more-345"></span>Profiling said that most of the delay&#8211;close to 60%&#8211;was coming from FastMM&#8217;s FastFreeMem calling something in ntdll.dll.  It didn&#8217;t say what, and I didn&#8217;t figure I needed to poke around inside the memory manager.  I&#8217;d be better off making sure there weren&#8217;t so many calls into FastFreeMem, right?</p>
<p>So I poked around in the deserializer code and found several places in inner loops where strings were being created and disposed of quite unnecessarily.  I fixed the code so that that wouldn&#8217;t happen, optimizing out all the unnecessary FreeMem calls.  That should have fixed things up, I figured.  My reward was a measly 0.4 seconds, down from 3.3 to 2.9, with the bulk of the time <em>still</em> taking place in ntdll.</p>
<p>So I poked around in the FastFreeMem code a little, and was surprised to run across this:</p>
<div class="codesnip-container" >
<div class="delphi codesnip" style="font-family:monospace;"><span class="sy2">@</span>LockBlockTypeLoop<span class="sy1">:</span><br />
mov eax<span class="sy1">,</span> <span class="re0">$100</span><br />
<span class="coMULTI">{Attempt to grab the block type}</span><br />
lock cmpxchg TSmallBlockType<span class="br0">&#40;</span><span class="br0">&#91;</span>ebx<span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy1">.</span><span class="me1">BlockTypeLocked</span><span class="sy1">,</span> ah<br />
je <span class="sy2">@</span>GotLockOnSmallBlockType<br />
<span class="co2">{$ifndef NeverSleepOnThreadContention}</span><br />
<span class="coMULTI">{Couldn&#8217;t grab the block type &#8211; sleep and try again}</span><br />
push ecx<br />
push edx<br />
push InitialSleepTime<br />
call <span class="kw3">Sleep</span><br />
pop edx<br />
pop ecx<br />
<span class="coMULTI">{Try again}</span><br />
mov eax<span class="sy1">,</span> <span class="re0">$100</span><br />
<span class="coMULTI">{Attempt to grab the block type}</span><br />
lock cmpxchg TSmallBlockType<span class="br0">&#40;</span><span class="br0">&#91;</span>ebx<span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy1">.</span><span class="me1">BlockTypeLocked</span><span class="sy1">,</span> ah<br />
je <span class="sy2">@</span>GotLockOnSmallBlockType<br />
<span class="coMULTI">{Couldn&#8217;t grab the block type &#8211; sleep and try again}</span><br />
push ecx<br />
push edx<br />
push AdditionalSleepTime<br />
call <span class="kw3">Sleep</span><br />
pop edx<br />
pop ecx<br />
<span class="coMULTI">{Try again}</span><br />
jmp <span class="sy2">@</span>LockBlockTypeLoop<br />
<span class="coMULTI">{Align branch target}</span><br />
nop<br />
nop<br />
<span class="co2">{$else}</span><br />
<span class="coMULTI">{Pause instruction (improves performance on P4)}</span><br />
rep nop<br />
<span class="coMULTI">{Try again}</span><br />
jmp <span class="sy2">@</span>LockBlockTypeLoop<br />
<span class="coMULTI">{Align branch target}</span><br />
nop<br />
<span class="co2">{$endif}</span></div>
</div>
<p>So when it tries to lock the memory block to free some memory, unless a special &#8220;NeverSleepOnThreadContention&#8221; compiler flag is set, it&#8217;ll call the Winapi Sleep function, giving up the entire timeslice (several milliseconds) because it&#8217;s blocked by an operation that will take a few dozen lines of ASM to complete.</p>
<p>I looked for this option in FastMM4Options.inc, and found the following explanation:</p>
<blockquote><p><span style="color: #008000;"><em>{Enable this option to never put a thread to sleep if a thread contention occurs. This option will improve performance if the ratio of the number of active threads to the number of CPU cores is low (typically &lt; 2). With this option set a thread will enter a &#8220;busy waiting&#8221; loop instead of relinquishing</em><em> its timeslice when a thread contention occurs.}</em></span></p></blockquote>
<p>So sleeping the thread instead of spinlocking can be helpful when there are a high number of threads running.  But there&#8217;s no code to detect this.  It&#8217;s never call Sleep or always call Sleep, with the decision hardcoded in at compile time.  I wonder if it would be possible to always spinlock for a certain number of cycles first and see if that helps, before calling Sleep?</p>
<p>Anyway, it turns out that that was my problem.  I was doing some other data-intensive loading in a background thread, and the memory allocations were clashing with each other.  When I set the NeverSleepOnThreadContention flag and rebuilt, the load time for tile data dropped to a far more acceptable 1.1 seconds.</p>
]]></content:encoded>
			<wfw:commentRss>http://tech.turbu-rpg.com/345/how-default-settings-can-slow-down-fastmm/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

