tag:blogger.com,1999:blog-43507773491856820042024-03-05T03:12:17.471-08:00Abstract Pathtumtumtumhttp://www.blogger.com/profile/08707154189579608918noreply@blogger.comBlogger38125tag:blogger.com,1999:blog-4350777349185682004.post-18939054756441741762012-08-18T03:11:00.000-07:002012-08-18T03:11:13.507-07:00Dock appearing when running VMWare Fusion in fullscreen<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
In OSX Lion, you can make the dock appear in full screen apps by moving your mouse to the bottom of the screen and then moving it down against the bottom twice. This can be annoying in VMWare Fusion as you quite often can do this accidentally when trying to switch tasks in the task bar. Paste this into the Terminal to prevent this behaviour:<br />
<br />
<br /></div>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>defaults write com.apple.Dock autohide-delay -float 10 && killall Dock
</code></pre>
</div>
tumtumtumhttp://www.blogger.com/profile/08707154189579608918noreply@blogger.com0tag:blogger.com,1999:blog-4350777349185682004.post-39815138307435272712012-08-09T09:20:00.000-07:002012-08-09T10:10:34.170-07:00How much memory does a C# string take up?<div dir="ltr" style="text-align: left;" trbidi="on">
I've seen various answers on the web and they're mostly wrong or make wrong assumptions (<a href="http://www.dotnetperls.com/string-memory">this page</a> for example assumes the overhead is 20 bytes based on only a couple of tests). The answer is a bit more complex but actually makes a lot of sense when you investigate what happens in the .NET runtime.<br />
<div>
<br /></div>
<div>
Let's assume a 32bit system.</div>
<div>
<br /></div>
<div>
A C# string is a reference type. Every reference type has an 8 byte header. The first 4 bytes are used for the lockbits (to support the C# lock statement). The second 4 bytes are a pointer to the object type. The object type in turn contains the object vtable. In reality not all the bits are used in the header are needed for either of these fields since. For example, the object type pointer is aligned to a 4 byte boundary so the lower two bits can be ignored and reused by the garbage collector for marking the object in its mark-and-sweep cycle. That's 8 bytes minimum to just have an empty object (System.Object is 8 bytes). </div>
<div>
<br /></div>
<div>
X = 8 + ...</div>
<div>
<br /></div>
<div>
C# strings store their length. The length is a 4 byte integer (giving a maximum theoretical string length of 2^32).</div>
<div>
<br /></div>
<div>
X = 8 + 4 + ...</div>
<div>
<br /></div>
<div>
To speed up marshalling to native code, all .NET strings are additionally NULL terminated with a unicode null terminator. Without this NULL terminator, all strings passed to Win32 APIs would need to be copied. With the NULL terminator, API calls that take unicode strings can simply be given a pointer to the .NET string (after the string is pinned). That's 2 bytes.</div>
<div>
<br /></div>
<div>
X = 8 + 4 + 2 + ...</div>
<div>
<br /></div>
<div>
<div>
Then you need to store the characters. Each .NET char takes 2 bytes.</div>
<div>
<br />
X = 8 + 4 + 2 + (2 * LEN)</div>
<div>
But that's not the whole story. The .NET garbage collector allocates memory with 32 bit alignment . In other words, the total amount of memory allocated at a time will always be multiple of 4 (4, 8, 16, 20, 24, 32, 36 etc). This theoretically means that every reference type can be referenced in .NET with 30 bits rather than 32 bits. Every field that is a reference type in .NET is aligned. Read more about data alignment here: http://en.wikipedia.org/wiki/Data_structure_alignment</div>
<div>
<br /></div>
<div>
So the final answer is:</div>
<div>
<br /></div>
<div>
X = (8 + 4 + 2 + (2 * LEN)) + 4 - 1) / 4 * 4</div>
<div>
<br />
In .NET prior to version 4, .NET strings had an extra field named "m_arrayLength" which was never used. This made strings at least 4 bytes longer. This field was removed in 4.0.<br />
<br />
Did you know that in Java, there is a <i>buffer pointer </i>(in C# the buffer comes straight after the string length) and an <i>offset</i> field used to store an offset within the string buffer. This allows the java.lang.String.substring(int, int) method to operate on O(1) time rather than O(n) time like .NET. The new string returned simply points to the origin string's buffer and the offset is taken into account with all operations. This has the unfortunate side-effect whereby a string of 1 character that is the result of a substring call can take up 1MB of memory because its originator string was 1MB.</div>
</div>
</div>tumtumtumhttp://www.blogger.com/profile/08707154189579608918noreply@blogger.com0tag:blogger.com,1999:blog-4350777349185682004.post-9072123058388331822012-07-20T15:09:00.002-07:002012-07-25T06:37:36.448-07:00Why do Android animations stutter when iOS animations are so smooth?<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="color: #333333; font-family: 'Helvetica Neue', Helvetica, Arial, default; font-size: 13px; line-height: 15px; text-align: -webkit-auto;">The underlying issue is the different animation models on Android and iOS. iOS uses CoreAnimation, an API created by the iPhone team for the original iPhone that was back ported to the desktop OSX. CoreAnimation is a retained mode graphics strategy. Microsoft WP7 also uses retained mode. Google's Android uses what is known as immediate mode graphics.</span><br />
<div npdkey="h5165qqq0.7f3ebj0eu0vsra4i" style="color: #333333; font-family: 'Helvetica Neue', Helvetica, Arial, default; font-size: 13px; line-height: 15px; margin: 0px; padding: 0px; text-align: -webkit-auto;">
<div npdkey="h5165qwl0.ak789xv5pa0v0a4i" style="margin: 0px; padding: 0px;">
<br npdkey="h5165vqy0.oq5kn4xnxapds4i" style="margin: 0px; padding: 0px;" /></div>
<div npdkey="h5165py90.d5vh61gi9jurf6r" style="margin: 0px; padding: 0px;">
All GUIs generally work the same way. There is a main thread with a loop that processes messages from a queue. Messages can range from "move view to this location" or "user has performed a touch at location". The whole point is that it is a <u npdkey="h515y36o0.vzfuya7ye916pqfr" style="margin: 0px; padding: 0px;">queue</u> so every message generally gets processed one at a time and in a first come first serve order.<br />
<br />
For the majority of UI toolkits, including those found on iOS and Android, accessing and modifying objects must be done in the main thread. Despite sometimes being called the UI thread, it is usually also the main thread and often is responsible for not just painting, changing colours, moving objects but also for loading files, decoding images, handling network responses etc.<br />
<div npdkey="h515y8hq0.bv9ncdq8fmwmte29" style="margin: 0px; padding: 0px;">
<br npdkey="h515y8hq0.xpmqk980fb76i529" style="margin: 0px; padding: 0px;" /></div>
<div npdkey="h515y8el0.pg48xji14z9i19k9" style="margin: 0px; padding: 0px;">
In Android, if you want to animate an object and make it move an object from location1 to location2, the animation API figures out the intermediate locations (tweening) and then queues onto the main thread the appropriate move operations at the appropriate times using a timer. This works fine except that the main thread is usually used for many other things -- painting, opening files, responding to user inputs etc. A queued timer can often be delayed. Well written programs will always try to do as many operations as possible in background (non main) threads however you can't always avoid using the main thread. Operations that require you to operate on a UI object always have to be done on the main thread. Also, many APIs will funnel operations back to the main thread as a form of thread-safety. It is usually almost impossible to keep all operations on the main thread down to 1/60th of a second in order to allow animations to be processed smoothly. Even if Google could manage to get their code to do just that, it doesn't mean third party Application writers will be able to.<br />
<br />
In iOS operations on UI objects also must be done on the main thread with the exception of animation operations done via CoreAnimation. CoreAnimation runs on a background thread and is able to directly manipulate, move, recolor and reshape UI objects on a background (CoreAnimation) thread. Compositing, rendering is also performed in this thread. It does this through a combination of hardware and software, providing very smooth and fast animations. From the main thread you can basically issue a call to CallAnimation and tell it to move object1 from location1 to location2. This animation will continue to run even if the main thread is blocked performing another operation. This is why animations will almost never stutter on iOS.<br />
<div npdkey="h515y3bw0.gsl6gw895z6c4n29" style="margin: 0px; padding: 0px;">
<br npdkey="h515y5zx0.vmuu7h5qu6cac3di" style="margin: 0px; padding: 0px;" /></div>
<div npdkey="h515y38t0.gb2lr45brh3t0529" style="margin: 0px; padding: 0px;">
Think of the iOS model this way: The main thread manages application data and UI application state (UI application state includes things such as the strings to be displayed in a ListView etc) but issues physical UI state change requests to a separate and dedicated high priority CoreAnimation thread (physical states include things such as colour, position and shape). All physical state changes can be animated and CoreAnimation will also perform the tweening for you (like the Android animation APIs). Non animated physical state changes will be issued directly by CoreAnimation and the main thread (not the CoreAnimation thread) will block until those are performed. Animated physical state changes that are issued by the main thread will be performed asynchronously by the CoreAnimation thread. Because physical UI state and <u npdkey="h515y36o0.ubfk3cjxteuq5mi" style="margin: 0px; padding: 0px;">only</u> physical UI state is managed by the CoreAnimation thread, the main thread can be blocked or busy but the CoreAnimation thread will still continue to not only accurately render the last known state of the UI (as issued by the main thread) but also continue to render any pending or incomplete animated UI physical state changes as requested by the main thread.<br />
<br />
In Windows Vista, Microsoft introduced desktop composition whereby the OS maintained a separate pixel buffer for every window. This meant that even if an application hung, the last state of the window (how it looked) is still rendered rather than just being drawn as white (the OS partially managed the state of the pixels in the window). CoreAnimation goes beyond this and offloads much of the UI work traditionally managed by the main thread including managing the state of not just the pixels (like Vista) but of higher level </div>
<div npdkey="h5165hu90.7o06bkoegwvu0udi" style="margin: 0px; padding: 0px;">
concepts such as widgets, widget locations, widget colours etc. </div>
<div npdkey="h5165jfd0.5zll9s4v4j6pqfr" style="margin: 0px; padding: 0px;">
<br npdkey="h5165kvt0.kvwnz0kcejdims4i" style="margin: 0px; padding: 0px;" /></div>
<div npdkey="h5165j0p0.3cgokp7yt78n0zfr" style="margin: 0px; padding: 0px;">
iOS and Android use completely different software architectures for performing animations. Apple probably put more focus on creating something like CoreAnimation because Apple are a lot more OCD about design and user experience than most software companies. I'm sure Steve would of had a few words with the iOS architects if scrolling stuttered when reading an email because an image on the email needed to be loaded. Humans aren't computers. Often the perception of performance is more important than the actual timed performance. An email that takes 50ms longer to load won't be as noticable as a a touch screen that doesn't instantly respond and move when a user slides their finger over it.<br />
<br />
There is nothing too wrong with the Android animation model. It's the way many toolkits work including Flash which was definitely very animation heavy. I would say the iOS model makes the overall user experience nicer and offloads one more worry for the developer back to the operating system. I'm sure Google will continue to recognise the importance of animation on touch screen devices and continue to accelerate (or rearchitecture) Android in coming releases.<br />
<br />
A 5 year old 1st generation iPhone will perform smoother and more reliable animations than the latest quad core Samsung Android phone. It's a software design problem and not something you can throw more cores at (not least of which because the main thread will only ever run on one core!). Don't believe people when they excuse stutter and lag as "oh just the Android Java garbage collector". Modern compactng, generational garbage collectors generally aren't the cause of the kind of stutter you see on Android.<br />
<br />
For the moment, you will never see something as simple as a loading wheel stutter in iOS. I hope this explains why :-)</div>
</div>
</div>
</div>
</div>tumtumtumhttp://www.blogger.com/profile/08707154189579608918noreply@blogger.com0tag:blogger.com,1999:blog-4350777349185682004.post-322678456947096222012-06-02T07:50:00.000-07:002012-06-06T05:28:44.019-07:00Audjustable AudioPlayer/AudioStreamer component for iOS<div dir="ltr" style="text-align: left;" trbidi="on">
I've written a new AudioPlayer/AudioStreamer for iOS. It's improved upon Matt Mallagher's AudioStreamer by adding queueing, gapless playback, pre-buffering and a simple but extensible data source model (it works with more than HTTP).<br />
<br />
You can find it at Google Code:<br />
<br />
<a href="http://code.google.com/p/audjustable">http://code.google.com/p/audjustable</a><br />
<br /></div>tumtumtumhttp://www.blogger.com/profile/08707154189579608918noreply@blogger.com2tag:blogger.com,1999:blog-4350777349185682004.post-73203332115141655982011-10-19T18:48:00.001-07:002011-10-19T19:01:03.367-07:00Playing back VC-1 (WVC-1) videos with DXVA in Windows Media Centre 7After a lot of messing around with codecs, I've successfully gotten VC-1 videos to playback using DXVA hardware acceleration in Windows Media Centre on Windows 7. CPU usage is 8%-15% on a 2.13Ghz Core 2 Duo. This is down from around 80%-90%. GPU usage is around 10% on an NVidia GT440.<br /><br />Don't bother with the Microsoft DMO codecs for VC-1 as they don't use DXVA (at least they don't with my NVidia GT440) and use more CPU time than software based ffdshow.<br /><br />The ffdshow DXVA enabled codec for VC-1 seems to crash on the VC-1 streams I tried.<div><br />Solution:<br />Download Media Player Classic MPHC Stand Alone filters from <a href="http://sourceforge.net/projects/mpc-hc/files/">here</a>. Make sure you you download the 64bit version if you're using 64bit Windows Media Centre.<br />Extract MPCVideoDec.ax from the zip file to a safe location and then register it from the command prompt using "regsvr32 MPCVideoDec.ax".<br />Use <a href="http://www.codecguide.com/windows7_preferred_filter_tweaker.htm">Win7DSFilterTweaker</a> and select "MPCVideoDec" under xx-bit decoders/VC-1.</div><div><br /></div><div>Everything should work straight after that (no reboot required). If you encounter any problems then you can use the DSFilterTweaker to switch back to the Microsoft decoder and "regsvr32 /u MPCVideoDec.ax" to deregister the MPC codec.</div><div><br /></div>tumtumtumhttp://www.blogger.com/profile/08707154189579608918noreply@blogger.com0tag:blogger.com,1999:blog-4350777349185682004.post-12278593468810257072010-12-01T16:39:00.001-08:002010-12-01T16:40:46.296-08:00mflow betaWe're beta testing our new web based product offering at <a href="http://beta.mflow.com">beta.mflow.com</a>.<br /><br />Give it a go! :-)<div><br /></div><div>Try listening to <a href="http://beta.mflow.com/user/tum">my music recommendations</a>!</div>tumtumtumhttp://www.blogger.com/profile/08707154189579608918noreply@blogger.com0tag:blogger.com,1999:blog-4350777349185682004.post-15809068143477070212010-11-26T08:22:00.001-08:002010-11-26T08:27:38.917-08:00Gah, browser bugs<div>After an hour of debugging I tracked down a bug due to how Firefox handles Ajax calls.</div><div><br /></div><div>All Ajax calls generally come with a <span class="Apple-style-span" >X-Requested-With: XMLHttpRequest</span> header to indicate that a call is an Ajax call.</div><div><br /></div><div>If the response of the call is a 302 (redirect), then browsers will make an additional call to the new URL but in FireFox, this second call does not contain the X-Requested-With header.</div>tumtumtumhttp://www.blogger.com/profile/08707154189579608918noreply@blogger.com0tag:blogger.com,1999:blog-4350777349185682004.post-33203172126014942902010-11-13T10:46:00.001-08:002010-11-13T10:47:57.203-08:00Web Designers vs Web Programmers<br /> <a href="http://www.wix.com/" mce_href="http://www.wix.com/" title="Website Builder"><img width="80%" src="http://www.landingpages.co.il/wix/web-designers-vs-developers.png" mce_src="http://www.landingpages.co.il/wix/web-designers-vs-developers.png" border="0" alt="free website builder" title="free website" /></a></p> <p>Web Designers vs Web Developers is brought to you by Wix.com <br/>Use creative design to make a <a href="http://www.wix.com" mce_href="http://www.wix.com">Free Website</a><br /> You are most welcome to share this infographic with your audience.</p> <p>tumtumtumhttp://www.blogger.com/profile/08707154189579608918noreply@blogger.com0tag:blogger.com,1999:blog-4350777349185682004.post-52551148632600760282010-05-29T16:58:00.000-07:002010-05-29T17:12:17.641-07:00Perfect crimeSo, there's a tiny logic bug in someone's code that you need to fix but the code has changed quite significantly and you don't want to have to go back through subversion logs?<div><br /></div><div><ol><li>Download the existing dll from the production server</li><li>Disassmble the dll using ildasm (ildasm /out:code.msil code.dll)</li><li>Use notepad to insert the fix you need in MSIL. Ildasm conveniently pads line numbers in the disassembled code so if you're lucky you can insert code without having to change any existing line number references.</li><li>Reassemble the code and deploy (ilasm /DLL code.msil)</li><li>Try not to act surprised that all those years of writing compiler and reflection.emit code came in handy yet again! </li><li>Hope no-one notices.</li></ol><div><span class="Apple-style-span" style="font-family:monospace;font-size:100%;"><span class="Apple-style-span" style=" white-space: pre;font-size:13px;"><span class="Apple-style-span" style="font-family:Georgia, serif;font-size:130%;"><span class="Apple-style-span" style=" white-space: normal;font-size:16px;"><br /></span></span></span></span></div></div><pre class="csharpcode"><span class="rem">// Original C#</span><br /><br />ViewData[<span class="str">"CODE"</span>] = <span class="kwrd">string</span>.IsNullOrEmpty(id)<br />? GetCookieValue(<span class="str">"CODE"</span>) : id.ToUpper();<br /><br /><span class="rem">// Original IL</span><br /><br />IL_001b: ldarg.0<br />IL_001c: ldstr <span class="str">"InviteCode"</span><br />IL_0021: call instance <span class="kwrd">string</span> GetCookieValue(<span class="kwrd">string</span>)<br />IL_0022: dup<br />IL_0023: starg 1<br />IL_0026: callvirt instance <span class="kwrd">void</span> set_Item(<span class="kwrd">string</span>, <span class="kwrd">object</span>)<br /><br /><span class="rem">// Fixed C#</span><br /><br />id = <span class="kwrd">string</span>.IsNullOrEmpty(id)<br />? GetCookieValue(<span class="str">"CODE"</span>) : id.ToUpper();<br /><br />ViewData[<span class="str">"CODE"</span>] = id;<br /><br /><span class="rem">// Fixed C# (more compact)</span><br /><br />ViewData[<span class="str">"CODE"</span>] = <span class="kwrd">string</span>.IsNullOrEmpty(id)<br />? id = GetCookieValue(<span class="str">"CODE"</span>) : id.ToUpper();<br /><br /><span class="rem">// Fixed IL</span><br /><br />IL_001b: ldarg.0<br />IL_001c: ldstr <span class="str">"InviteCode"</span><br />IL_0021: call instance <span class="kwrd">string</span> GetCookieValue(<span class="kwrd">string</span>)<br />IL_0022: dup<br />IL_0023: starg 1<br />IL_0026: callvirt instance <span class="kwrd">void</span> set_Item(<span class="kwrd">string</span>, <span class="kwrd">object</span>)</pre>tumtumtumhttp://www.blogger.com/profile/08707154189579608918noreply@blogger.com1tag:blogger.com,1999:blog-4350777349185682004.post-23331702542202930302010-04-16T05:41:00.001-07:002010-04-16T12:01:14.172-07:00mflow launches publically with new features and new website<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.mflow.com/Download/Index/TN736X"><img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 256px; height: 256px;" src="http://www.abstractpath.com/weblog/uploaded_images/Black256-703543.png" border="0" alt="" /></a><br /><br /><a href="http://www.mflow.com/Download/Index/TN736X">Click</a> on the image to get an account with £1 free credit.<br /><br />If you already have an account, apply the promo code <b><span class="Apple-style-span" style="font-family:'lucida grande';">TN736X </span></b>in your account settings.<br /><br /><br /><div><br /></div><div><br /></div><div><br /></div><div><br /><object width="360" height="240"><param name="movie" value="http://www.youtube.com/v/Bpclb9KKb4I&hl=en_US&fs=1&"><param name="allowFullScreen" value="true"><param name="allowscriptaccess" value="always"><embed src="http://www.youtube.com/v/Bpclb9KKb4I&hl=en_US&fs=1&" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="360" height="240"></embed></object></div>tumtumtumhttp://www.blogger.com/profile/08707154189579608918noreply@blogger.com0tag:blogger.com,1999:blog-4350777349185682004.post-25723324206627982702010-04-13T14:47:00.001-07:002010-06-02T05:58:56.228-07:00About Thong Nguyen<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSdhHim6otBTuR6SyNh2VWVOjatSogMJt9mEd3QsDGWzfIhauzA8d1ygMjGEe1khtkZTQk8M8HNj3q0Y1zYojxakUi-VwlBvQ3XPNN_xGlveITObSq94bLH-66M8GDSGYv70rr1dPOM6s/s1600/tum.jpg"><img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 200px; height: 184px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSdhHim6otBTuR6SyNh2VWVOjatSogMJt9mEd3QsDGWzfIhauzA8d1ygMjGEe1khtkZTQk8M8HNj3q0Y1zYojxakUi-VwlBvQ3XPNN_xGlveITObSq94bLH-66M8GDSGYv70rr1dPOM6s/s320/tum.jpg" border="0" alt="" id="BLOGGER_PHOTO_ID_5459746426750362898" /></a><div><b>Name</b></div><div>Thong Nguyen</div><div><b>Born</b></div><div>December 24th 1979<br /><a href="http://en.wikipedia.org/wiki/Cam_Ranh_Bay">Cam Ranh</a>, Khánh Hòa, Vietnam</div><div><b>Home Town</b></div><div><a href="http://en.wikipedia.org/wiki/Christchurch">Christchurch</a>, New Zealand<br /><div><b>Current Location</b></div><div>London, United Kingdom</div></div><div><b>Current Job</b></div><div>CTO at <a href="http://www.mflow.com/" target="_blank">mflow</a></div><div><br /></div><div><br /></div><div><a href="http://uk.linkedin.com/in/tumtumtum"><img src="http://static03.linkedin.com/img/logos/logo_linkedin_88x22.png" style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 88px; height: 22px;" border="0" alt="" /></a></div><div><br /></div><div><br /></div>tumtumtumhttp://www.blogger.com/profile/08707154189579608918noreply@blogger.com5tag:blogger.com,1999:blog-4350777349185682004.post-63668975170325152022010-03-25T05:41:00.001-07:002010-03-25T05:43:31.258-07:00Visual Studio Find In Files Stops workingThis happens randomly and is really annoying. It usually requires Visual Studio to fix. However, there is a better solution which I found on this <a href="http://bloggingabout.net/blogs/edward/archive/2005/01/31/2136.aspx">this blog</a>. You just need to press Ctrl+Scrollock. I guess this happens to me because I regularly press Ctrl+Break and must accidentally hit the ScrollLock key.tumtumtumhttp://www.blogger.com/profile/08707154189579608918noreply@blogger.com0tag:blogger.com,1999:blog-4350777349185682004.post-75771445280769598532010-03-06T16:05:00.000-08:002010-03-06T16:15:45.839-08:00Simple C++ SmartPtr<PRE><FONT COLOR="#990000">namespace</FONT> Neon<B><FONT COLOR="#663300"><br />{</FONT></B><FONT COLOR="#990000"><br /> template</FONT><B><FONT COLOR="#663300"><</FONT></B><FONT COLOR="#990000">class</FONT> T<B><FONT COLOR="#663300">></FONT></B><FONT COLOR="#990000"><br /><br /> class</FONT> SmartPtr<B><FONT COLOR="#663300"><br /> {</FONT></B><FONT COLOR="#990000"> <br /> private</FONT><B><FONT COLOR="#663300">:</FONT></B><br /><br /> T<B><FONT COLOR="#663300"> *</FONT></B>ptr<B><FONT COLOR="#663300">;</FONT></B><FONT COLOR="#990000"><br /><br /> mutable volatile</FONT><FONT COLOR="#FF6633"> long</FONT><B><FONT COLOR="#663300"> *</FONT></B>count<B><FONT COLOR="#663300">;</FONT></B><FONT COLOR="#990000"><br /><br /> public</FONT><B><FONT COLOR="#663300">:</FONT></B><FONT COLOR="#990000"><br /><br /> const</FONT><FONT COLOR="#FF6633"> long</FONT> refcount<B><FONT COLOR="#663300">()<br /> {</FONT></B><FONT COLOR="#FF0000"><br /><br /> return</FONT><B><FONT COLOR="#663300"> *</FONT></B><FONT COLOR="#990000">this</FONT><B><FONT COLOR="#663300">-></FONT></B>count<B><FONT COLOR="#663300">;<br /> }</FONT></B><FONT COLOR="#FF6633"><br /><br /> void</FONT> addref<B><FONT COLOR="#663300">()</FONT></B><FONT COLOR="#990000"> const</FONT><B><FONT COLOR="#663300"><br /><br /> {</FONT></B><FONT COLOR="#FF0000"><br /> if</FONT><B><FONT COLOR="#663300"> (</FONT></B>count<B><FONT COLOR="#663300"> ==</FONT></B><FONT COLOR="#999900"> 0</FONT><B><FONT COLOR="#663300">)<br /> {</FONT></B><FONT COLOR="#FF0000"><br /> return</FONT><B><FONT COLOR="#663300">;<br /> }</FONT></B><br /><br /> XInterlockedIncrement<B><FONT COLOR="#663300">(</FONT></B>count<B><FONT COLOR="#663300">); <br /> }</FONT></B><FONT COLOR="#FF6633"><br /><br /> void</FONT> deref<B><FONT COLOR="#663300">()<br /> {</FONT></B><FONT COLOR="#FF0000"><br /> if</FONT><B><FONT COLOR="#663300"> (</FONT></B>count<B><FONT COLOR="#663300"> ==</FONT></B><FONT COLOR="#999900"> 0</FONT><B><FONT COLOR="#663300">)<br /> {</FONT></B><FONT COLOR="#FF0000"><br /><br /> return</FONT><B><FONT COLOR="#663300">;<br /> }</FONT></B><FONT COLOR="#FF0000"><br /><br /> if</FONT><B><FONT COLOR="#663300"> (</FONT></B>XInterlockedDecrement<B><FONT COLOR="#663300">(</FONT></B>count<B><FONT COLOR="#663300">) ==</FONT></B><FONT COLOR="#999900"> 0</FONT><B><FONT COLOR="#663300">)<br /> {</FONT></B><FONT COLOR="#990000"><br /><br /> delete</FONT> count<B><FONT COLOR="#663300">;</FONT></B><FONT COLOR="#990000"><br /> delete</FONT> ptr<B><FONT COLOR="#663300">;<br /> }<br /> }</FONT></B><FONT COLOR="#FF6633"><br /> <br /> void</FONT> init<B><FONT COLOR="#663300">(</FONT></B>T<B><FONT COLOR="#663300"> *</FONT></B>ptr<B><FONT COLOR="#663300">,</FONT></B><FONT COLOR="#990000"> volatile</FONT><FONT COLOR="#FF6633"> long</FONT><B><FONT COLOR="#663300"> *</FONT></B>count<B><FONT COLOR="#663300">)<br /> {</FONT></B><FONT COLOR="#990000"><br /><br /> this</FONT><B><FONT COLOR="#663300">-></FONT></B>ptr<B><FONT COLOR="#663300"> =</FONT></B> ptr<B><FONT COLOR="#663300">;</FONT></B><FONT COLOR="#990000"><br /> this</FONT><B><FONT COLOR="#663300">-></FONT></B>count<B><FONT COLOR="#663300"> =</FONT></B> count<B><FONT COLOR="#663300">;<br /> }</FONT></B><br /><br /> <br /> SmartPtr<B><FONT COLOR="#663300">(</FONT></B>T<B><FONT COLOR="#663300"> *</FONT></B>ptr_p<B><FONT COLOR="#663300">,</FONT></B><FONT COLOR="#990000"> volatile</FONT><FONT COLOR="#FF6633"> long</FONT><B><FONT COLOR="#663300"> *</FONT></B>count<B><FONT COLOR="#663300">)<br /> {</FONT></B><br /><br /> init<B><FONT COLOR="#663300">(</FONT></B>ptr_p<B><FONT COLOR="#663300">,</FONT></B> count<B><FONT COLOR="#663300">);</FONT></B><FONT COLOR="#990000"><br /> this</FONT><B><FONT COLOR="#663300">-></FONT></B>addref<B><FONT COLOR="#663300">();<br /> }</FONT></B><br /><br /> SmartPtr<B><FONT COLOR="#663300">()<br /> {</FONT></B><FONT COLOR="#FF6633"><br /><br /> long</FONT><B><FONT COLOR="#663300"> *</FONT></B>count_p<B><FONT COLOR="#663300">;</FONT></B><br /><br /> count_p<B><FONT COLOR="#663300"> =</FONT></B><FONT COLOR="#990000"> new</FONT><FONT COLOR="#FF6633"> long</FONT><B><FONT COLOR="#663300">;<br /><br /> *</FONT></B>count_p<B><FONT COLOR="#663300"> =</FONT></B><FONT COLOR="#999900"> 1</FONT><B><FONT COLOR="#663300">;</FONT></B><br /><br /> init<B><FONT COLOR="#663300">((</FONT></B>T<B><FONT COLOR="#663300"> *)</FONT></B><FONT COLOR="#999900">0</FONT><B><FONT COLOR="#663300">,</FONT></B> count_p<B><FONT COLOR="#663300">);<br /> }</FONT></B><br /><br /> SmartPtr<B><FONT COLOR="#663300">(</FONT></B>T<B><FONT COLOR="#663300"> *</FONT></B>ptr_p<B><FONT COLOR="#663300">)<br /> {</FONT></B><FONT COLOR="#FF6633"><br /><br /> long</FONT><B><FONT COLOR="#663300"> *</FONT></B>count_p<B><FONT COLOR="#663300">;</FONT></B><br /><br /> count_p<B><FONT COLOR="#663300"> =</FONT></B><FONT COLOR="#990000"> new</FONT><FONT COLOR="#FF6633"> long</FONT><B><FONT COLOR="#663300">;<br /> *</FONT></B>count_p<B><FONT COLOR="#663300"> =</FONT></B><FONT COLOR="#999900"> 1</FONT><B><FONT COLOR="#663300">;</FONT></B><br /><br /> init<B><FONT COLOR="#663300">(</FONT></B>ptr_p<B><FONT COLOR="#663300">,</FONT></B> count_p<B><FONT COLOR="#663300">);<br /> }</FONT></B><br /> <br /> <br /> SmartPtr<B><FONT COLOR="#663300">(</FONT></B><FONT COLOR="#990000">const</FONT> SmartPtr<B><FONT COLOR="#663300"><</FONT></B>T<B><FONT COLOR="#663300">>&</FONT></B> ptr<B><FONT COLOR="#663300">)<br /> {</FONT></B><FONT COLOR="#990000"><br /><br /> this</FONT><B><FONT COLOR="#663300">-></FONT></B>init<B><FONT COLOR="#663300">(</FONT></B>ptr<B><FONT COLOR="#663300">.</FONT></B>ptr<B><FONT COLOR="#663300">,</FONT></B> ptr<B><FONT COLOR="#663300">.</FONT></B>count<B><FONT COLOR="#663300">);</FONT></B><FONT COLOR="#990000"><br /> this</FONT><B><FONT COLOR="#663300">-></FONT></B>addref<B><FONT COLOR="#663300">();<br /> }</FONT></B><FONT COLOR="#990000"><br /><br /> template</FONT><B><FONT COLOR="#663300"> <</FONT></B><FONT COLOR="#990000">typename</FONT> U<B><FONT COLOR="#663300">></FONT></B><br /> SmartPtr<B><FONT COLOR="#663300"><</FONT></B>U<B><FONT COLOR="#663300">></FONT></B> reinterpret<B><FONT COLOR="#663300">()<br /> {</FONT></B><br /> SmartPtr<B><FONT COLOR="#663300"><</FONT></B>U<B><FONT COLOR="#663300">></FONT></B> retval<B><FONT COLOR="#663300">;</FONT></B><br /><br /> retval<B><FONT COLOR="#663300">.</FONT></B>init<B><FONT COLOR="#663300">((</FONT></B>U<B><FONT COLOR="#663300"> *)</FONT></B><FONT COLOR="#990000">this</FONT><B><FONT COLOR="#663300">-></FONT></B>ptr<B><FONT COLOR="#663300">,</FONT></B><FONT COLOR="#990000"> this</FONT><B><FONT COLOR="#663300">-></FONT></B>count<B><FONT COLOR="#663300">);</FONT></B><br /><br /> retval<B><FONT COLOR="#663300">.</FONT></B>addref<B><FONT COLOR="#663300">();</FONT></B><FONT COLOR="#FF0000"><br /><br /> return</FONT> retval<B><FONT COLOR="#663300">;<br /> }<br /><br /> ~</FONT></B>SmartPtr<B><FONT COLOR="#663300">()<br /> {</FONT></B><br /> deref<B><FONT COLOR="#663300">();<br /> }</FONT></B><FONT COLOR="#990000"><br /><br /> inline operator</FONT> T<B><FONT COLOR="#663300"> *()<br /> {</FONT></B><FONT COLOR="#FF0000"><br /> return</FONT> ptr<B><FONT COLOR="#663300">;<br /> }</FONT></B><FONT COLOR="#990000"><br /> <br /> inline</FONT> T<B><FONT COLOR="#663300"> *</FONT></B><FONT COLOR="#990000">operator</FONT><B><FONT COLOR="#663300">&()<br /> {</FONT></B><FONT COLOR="#FF0000"><br /><br /> return</FONT> ptr<B><FONT COLOR="#663300">;<br /> }</FONT></B><FONT COLOR="#990000"><br /><br /> inline</FONT> T<B><FONT COLOR="#663300"> *</FONT></B><FONT COLOR="#990000">operator</FONT><B><FONT COLOR="#663300">->()<br /> {</FONT></B><FONT COLOR="#FF0000"><br /><br /> return</FONT> ptr<B><FONT COLOR="#663300">;<br /> }</FONT></B><FONT COLOR="#990000"><br /><br /> inline</FONT><FONT COLOR="#FF6633"> bool</FONT><FONT COLOR="#990000"> operator</FONT><B><FONT COLOR="#663300">==(</FONT></B><FONT COLOR="#990000">const</FONT> SmartPtr<B><FONT COLOR="#663300"><</FONT></B>T<B><FONT COLOR="#663300">> &</FONT></B>ptr<B><FONT COLOR="#663300">)<br /> {</FONT></B><FONT COLOR="#FF0000"><br /><br /> return</FONT> ptr<B><FONT COLOR="#663300">.</FONT></B>ptr<B><FONT COLOR="#663300"> ==</FONT></B><FONT COLOR="#990000"> this</FONT><B><FONT COLOR="#663300">-></FONT></B>ptr<B><FONT COLOR="#663300">;<br /> }</FONT></B><FONT COLOR="#990000"><br /><br /> inline</FONT><FONT COLOR="#FF6633"> bool</FONT><FONT COLOR="#990000"> operator</FONT><B><FONT COLOR="#663300">==(</FONT></B><FONT COLOR="#990000">const</FONT> T<B><FONT COLOR="#663300"> *</FONT></B>ptr_p<B><FONT COLOR="#663300">)<br /> {</FONT></B><FONT COLOR="#FF0000"><br /><br /> return</FONT> ptr_p<B><FONT COLOR="#663300"> ==</FONT></B> ptr<B><FONT COLOR="#663300">;<br /> }</FONT></B><FONT COLOR="#990000"><br /><br /> inline</FONT><FONT COLOR="#FF6633"> bool</FONT><FONT COLOR="#990000"> operator</FONT><B><FONT COLOR="#663300">!=(</FONT></B><FONT COLOR="#990000">const</FONT> SmartPtr<B><FONT COLOR="#663300"><</FONT></B>T<B><FONT COLOR="#663300">> &</FONT></B>ptr<B><FONT COLOR="#663300">)<br /> {</FONT></B><FONT COLOR="#FF0000"><br /><br /> return</FONT> ptr<B><FONT COLOR="#663300">.</FONT></B>ptr<B><FONT COLOR="#663300"> !=</FONT></B><FONT COLOR="#990000"> this</FONT><B><FONT COLOR="#663300">-></FONT></B>ptr<B><FONT COLOR="#663300">;<br /> }</FONT></B><FONT COLOR="#990000"><br /><br /> inline</FONT><FONT COLOR="#FF6633"> bool</FONT><FONT COLOR="#990000"> operator</FONT><B><FONT COLOR="#663300">!=(</FONT></B><FONT COLOR="#990000">const</FONT> T<B><FONT COLOR="#663300"> *</FONT></B>ptr_p<B><FONT COLOR="#663300">)<br /> {</FONT></B><FONT COLOR="#FF0000"><br /><br /> return</FONT> ptr_p<B><FONT COLOR="#663300"> !=</FONT></B> ptr<B><FONT COLOR="#663300">;<br /> }</FONT></B><FONT COLOR="#990000"><br /><br /> inline</FONT><FONT COLOR="#FF6633"> void</FONT><FONT COLOR="#990000"> operator</FONT><B><FONT COLOR="#663300">=(</FONT></B><FONT COLOR="#990000">const</FONT> T<B><FONT COLOR="#663300"> *</FONT></B>ptr_p<B><FONT COLOR="#663300">)<br /> {</FONT></B><FONT COLOR="#FF6633"><br /><br /> long</FONT><B><FONT COLOR="#663300"> *</FONT></B>count_p<B><FONT COLOR="#663300">;</FONT></B><br /><br /> deref<B><FONT COLOR="#663300">();</FONT></B><br /><br /> count_p<B><FONT COLOR="#663300"> =</FONT></B><FONT COLOR="#990000"> new</FONT><FONT COLOR="#FF6633"> long</FONT><B><FONT COLOR="#663300">;<br /> *</FONT></B>count_p<B><FONT COLOR="#663300"> =</FONT></B><FONT COLOR="#999900"> 1</FONT><B><FONT COLOR="#663300">;</FONT></B><br /><br /> <br /> init<B><FONT COLOR="#663300">(</FONT></B>ptr_p<B><FONT COLOR="#663300">,</FONT></B> count_p<B><FONT COLOR="#663300">);<br /> }</FONT></B><FONT COLOR="#990000"><br /><br /> inline</FONT><FONT COLOR="#FF6633"> void</FONT><FONT COLOR="#990000"> operator</FONT><B><FONT COLOR="#663300">=(</FONT></B><FONT COLOR="#990000">const</FONT> SmartPtr<B><FONT COLOR="#663300"><</FONT></B>T<B><FONT COLOR="#663300">> &</FONT></B>ptr<B><FONT COLOR="#663300">)<br /> {</FONT></B><br /><br /> ptr<B><FONT COLOR="#663300">.</FONT></B>addref<B><FONT COLOR="#663300">();</FONT></B><br /> deref<B><FONT COLOR="#663300">();</FONT></B> <br /> init<B><FONT COLOR="#663300">(</FONT></B>ptr<B><FONT COLOR="#663300">.</FONT></B>ptr<B><FONT COLOR="#663300">,</FONT></B> ptr<B><FONT COLOR="#663300">.</FONT></B>count<B><FONT COLOR="#663300">);<br /> }<br /> };<br />}</FONT></B><br /><br /></PRE>tumtumtumhttp://www.blogger.com/profile/08707154189579608918noreply@blogger.com0tag:blogger.com,1999:blog-4350777349185682004.post-21316191280898868022009-12-08T02:22:00.000-08:002010-03-23T12:30:07.827-07:00What I've been working on with a fantastic team for 18 months!<div><span class="Apple-style-span" style="font-family:arial;"><br /></span></div><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.mflow.com/"><img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 256px; height: 256px;" src="http://www.abstractpath.com/weblog/uploaded_images/Black256-703543.png" border="0" alt="" /><span class="Apple-style-span" style="font-family:arial;"><br /><br /><br /><br /><br /><br /><br /><br /><br /></span></a><div><span class="Apple-style-span" style="font-family:arial;"><br /></span></div><div><span class="Apple-style-span" style="font-family:arial;"><br /></span></div><div><span class="Apple-style-span" style="font-family:arial;"><br /></span></div><div><span class="Apple-style-span" style="font-family:arial;"><br /></span></div><div><span class="Apple-style-span" style="font-family:arial;"><br /></span></div><div><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.mflow.com/"><span class="Apple-style-span" style="font-family:arial;"><br /><br /></span></a></div><div><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.mflow.com/"><span class="Apple-style-span" style="font-family:arial;">http://www.mflow.com</span><br /></a><br /></div>tumtumtumhttp://www.blogger.com/profile/08707154189579608918noreply@blogger.com0tag:blogger.com,1999:blog-4350777349185682004.post-57554559610504508112009-04-16T08:30:00.000-07:002009-04-17T08:51:44.341-07:00MemCpy in C#<!-- code formatted by http://manoli.net/csharpformat/ -->Here's an example of implementing a fast equivalent of MemCpy in C# using DynamicMethods.<br /><pre class="csharpcode"><br /><span class="kwrd">using</span> System;<br /><span class="kwrd">using</span> System.Collections.Generic;<br /><span class="kwrd">using</span> System.Drawing;<br /><span class="kwrd">using</span> System.Drawing.Imaging;<br /><span class="kwrd">using</span> System.Linq;<br /><span class="kwrd">using</span> System.Reflection;<br /><span class="kwrd">using</span> System.Reflection.Emit;<br /><span class="kwrd">using</span> System.Runtime.InteropServices;<br /><span class="kwrd">using</span> System.Text;<br /><br /><span class="kwrd">namespace</span> Test<br />{<br /><span class="kwrd">public</span> <span class="kwrd">unsafe</span> <span class="kwrd">class</span> Program<br />{<br /> <span class="kwrd">public</span> <span class="kwrd">delegate</span> <span class="kwrd">void</span> MemCpyFunction(<span class="kwrd">void</span> *des, <span class="kwrd">void</span> *src, <span class="kwrd">uint</span> bytes);<br /><br /> <span class="kwrd">private</span> <span class="kwrd">static</span> <span class="kwrd">readonly</span> MemCpyFunction MemCpy;<br /><br /> <span class="kwrd">static</span> Program()<br /> {<br /> var dynamicMethod = <span class="kwrd">new</span> DynamicMethod<br /> (<br /> <span class="str">"MemCpy"</span>,<br /> <span class="kwrd">typeof</span>(<span class="kwrd">void</span>),<br /> <span class="kwrd">new</span> [] { <span class="kwrd">typeof</span>(<span class="kwrd">void</span> *), <span class="kwrd">typeof</span>(<span class="kwrd">void</span> *), <span class="kwrd">typeof</span>(<span class="kwrd">uint</span>) },<br /> <span class="kwrd">typeof</span>(Program)<br /> );<br /><br /> var ilGenerator = dynamicMethod.GetILGenerator();<br /><br /> ilGenerator.Emit(OpCodes.Ldarg_0);<br /> ilGenerator.Emit(OpCodes.Ldarg_1);<br /> ilGenerator.Emit(OpCodes.Ldarg_2);<br /><br /> ilGenerator.Emit(OpCodes.Cpblk);<br /> ilGenerator.Emit(OpCodes.Ret);<br /><br /> MemCpy = (MemCpyFunction)dynamicMethod<br /> .CreateDelegate(<span class="kwrd">typeof</span>(MemCpyFunction));<br /> }<br /><br /> <span class="kwrd">static</span> <span class="kwrd">void</span> Main(<span class="kwrd">string</span>[] args)<br /> {<br /> var point1 = <span class="kwrd">new</span> Point<br /> {<br /> X = 10,<br /> Y = 20<br /> };<br /><br /> var point2 = <span class="kwrd">new</span> Point();<br /><br /> MemCpy(&point2, &point1, (<span class="kwrd">uint</span>)<span class="kwrd">sizeof</span>(Point));<br /> }<br />}<br />}<br /></pre>tumtumtumhttp://www.blogger.com/profile/08707154189579608918noreply@blogger.com3tag:blogger.com,1999:blog-4350777349185682004.post-16812924722698755782008-09-09T01:16:00.000-07:002008-09-09T01:21:21.290-07:00iPhone 3G third party applications crashing on startup<span idspanfor="frame" mlb_idspanflag="true" style="border: 1px solid black; padding: 0px 3px; z-index: 500; font-size: xx-small; font-family: sans-serif; position: absolute; top: 0pt; left: 0pt; display: inline;">1</span>Sometimes third party applications (like Monkey Ball) will crash and return to the home screen after loading for only a few seconds. This problem appears to be related to an incomplete AppStore download. Rebooting the iPhone is often all that's required to fix the problem. If rebooting fails to work then loading up the App Store on the iPhone and downloading a free application or updating an existing one will almost always fix the problem. The last resort would be to do a full sync/backup with iTunes.<br /><br />I've never had to restore the iPhone firmware to fix this problem as one of the three previously mentioned problems will fix the issue.tumtumtumhttp://www.blogger.com/profile/08707154189579608918noreply@blogger.com1tag:blogger.com,1999:blog-4350777349185682004.post-28241522275092215442008-09-09T01:09:00.000-07:002008-09-09T01:29:02.088-07:00Fixing YouTube on a jailbreaked 2.02 iPhone 3G<span idspanfor="frame" mlb_idspanflag="true" style="border: 1px solid black; padding: 0px 3px; z-index: 500; font-size: xx-small; font-family: sans-serif; position: absolute; top: 0pt; left: 0pt; display: none;">1</span><span idspanfor="frame" mlb_idspanflag="true" style="border: 1px solid black; padding: 0px 3px; z-index: 500; position: absolute; top: 0pt; left: 0pt; display: inline;font-family:sans-serif;font-size:xx-small;" >1</span>Jailbreaking an iPhone 3G is relatively painless except that YouTube will often fail with a "cannot connect to youtube" error.<br /><br />There are numerous "fixes" around the internet but they all didn't work for me. The only way that seemed to work is:<br /><br /><ol><li>Delete the "%AppData%\Roaming\Apple Computer\Lockdown" directory from your computer (you may need to do this after jailbreaking anyway as iTunes may stop talking to your iPhone if you don't)</li><li>Install OpenSSH on your iPhone along with BossPrefs and then use BossPrefs to enable SSH.</li><li>Use WinSCP (or equivalent) and SSH into your iPhone using its current IP address. The username/password is root/alpine.</li><li>Browse to the /private/var/root directory and delete or rename the "lockdown" folder.</li><li>Shutdown your iPhone and make sure the USB cable is unplugged</li><li>Turn in your iPhone. Reinsert your SIM card and unlock it if necessary.</li><li>Your iPhone will request that you plug in your USB cable to activate the phone with an obvious looking picture.<br /></li><li>After the activation process is complete (it should only take few seconds after you plug in the USB cable and iTunes loads), YouTube should work again.</li></ol>It is important that the lockdown directory on both the PC and iPhone are deleted so that a full reactivation of the iPhone can be forced. Deleting only one or the other will cause a mismatch of keys and will not fix the issue.<br /><br /><span idspanfor="frame" mlb_idspanflag="true" style="border: 1px solid black; padding: 0px 3px; z-index: 500; position: absolute; top: 0pt; left: 0pt; display: inline;font-family:sans-serif;font-size:xx-small;" >1</span>tumtumtumhttp://www.blogger.com/profile/08707154189579608918noreply@blogger.com0tag:blogger.com,1999:blog-4350777349185682004.post-77501713371254422882008-09-09T01:06:00.000-07:002008-09-09T01:31:54.464-07:00Contractless IPhone 3G broadband in New Zealand:The guys at the Vodafone store will tell you that you need an iPhone contract to use 3G data on the iPhone. That's not entirely true. They preconfigure the iPhones to use the iphone.vodafone.net.nz APN but you can easily browse <a href="http://www.unlockit.co.nz/">to this website <span idspanfor="link" mlb_idspanflag="true" style="border: 1px solid grey; padding: 0px 3px; float: none; margin-left: 2px; z-index: 500; display: inline;font-family:sans-serif;font-size:xx-small;" >35</span></a>on your iPhone to reconfigure your iPhone to use the standard www.vodafone.net.nz or internet APN. With this setting you an opt to use Vodafone's $1 a day 3G data plan or their contractless monthly data plans.tumtumtumhttp://www.blogger.com/profile/08707154189579608918noreply@blogger.com0tag:blogger.com,1999:blog-4350777349185682004.post-61195782281100989942008-05-14T06:08:00.000-07:002008-05-15T10:20:12.774-07:00Converting Scooba Adapter from 110V to New Zealand 240VThe method is pretty similar to the Roomba adapter conversion and involves replacing a capacitor and varistor.<br /><br />Pictures:<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0198-791193.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0198-791126.jpg" alt="" border="0" /></a><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />The capacitor and varistor are circled.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0199-711733.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0199-711728.jpg" alt="" border="0" /></a><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />The two replacement components. a <a href="http://www.jaycar.co.nz/productView.asp?ID=RE6156&CATID=&keywords=100uf&SPECIAL=&form=KEYWORD&ProdCodeOnly=&Keyword1=&Keyword2=&pageNumber=&priceMin=&priceMax=&SUBCATID=">400V 100uF capacitor</a> and a <a href="http://www.jaycar.co.nz/productView.asp?ID=RN3400&CATID=&keywords=varistor&SPECIAL=&form=KEYWORD&ProdCodeOnly=&Keyword1=&Keyword2=&pageNumber=&priceMin=&priceMax=&SUBCATID=">275VAC varistor</a>.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0200-747105.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0200-747089.jpg" alt="" border="0" /></a><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />The board with the replacement components installed. The capacitor had to be mounted sideways in order to fit in the case. I used hot glue to keep it in place.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0201-747208.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0201-747145.jpg" alt="" border="0" /></a><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />The Scooba happily charging.tumtumtumhttp://www.blogger.com/profile/08707154189579608918noreply@blogger.com0tag:blogger.com,1999:blog-4350777349185682004.post-58700612398390404642008-05-14T04:34:00.000-07:002008-05-16T21:02:16.650-07:00Fixing a dead Roomba 500/570 (No Lights)I've had my Roomba 570 for almost two months. In that time, the little guy has been automatically vacuuming the house automatically everyday. A couple of weeks ago, I found him dead (no lights), in the morning, half way through a cleaning cycle. After picking him up he came back to life and then worked fine until two days ago.<br /><br />Two days ago, I found my Roomba dead again, half way through a cleaning cycle. He did not respond to any button presses and none of the indicator lights would come on. Resetting him did not work, nor did removing and replacing his battery. I opened him up and gave him a thorough clean (inside and out) with my standard vacuum. He worked again for 15 minutes and then died whilst emitting a a slow and unrecognisable musical sequence. This happened several more times during the day. The Roomba would die, only to come back to life after he was disassembled and cleaned. The Roomba would run, sometimes for an hour but often for only 10-15 minutes at a time before dying. One of the last times before he died, he moved eratically and again, played a musical sequence in an almost slow motion and drunken fashion.<br /><br />Eventually it seemed like my Robotic Vacuum was dead for good. No matter what I did, he would not respond to any button presses nor would he activate any indicator lights. The only thing I could think of that could cause this to happen would be a blown component or bad solder joint.<br /><br />I disassembled him all the way down to his main circuit board. I carefully went over his entire circuit board, looking for bad solder joints or blown components. I took special care to examine the FETs that drive the motors as well as the voltage regulators. The FETs looked undamaged and the regulators appeared to work because many of digital components chips were getting a 4.2V-5V supply (regulated down the battery's 14.4V supply). Nothing, it seemed, would bring back my Roomba.<br /><br />At 2am this morning, I pondered and wondered. What could possibly cause the Roomba to play music really slowly before it died? It was unlikely that a blown component or failed regulation circuit would cause that kind of failure.<br /><br />I came up with a theory. The crystal oscillator used as a clock generator for the Roomba's microcontroller (an ARM ARM7TDMI) relies on a piezoelectric crystal which can fail from heat, physical shock or simply poor construction.<br /><br />If the crystal oscillator on the Roomba main circuit board failed in such a way as to cause it to oscillate slower than its rated frequency then the Roomba's microcontroller (an ARM ARM7TDMI) would slow down accordingly. The Roomba's monitoring routines would notice some kind of problem (perhaps because of ms timings with other chips or interrupts) and try to play some said warning tones. The slower clock rate would cause those tones to be played with a lower fequency and longer duration.<br /><br />I opened up the Roomba yet again and examined the offending 8Mhz crystal connected to the ARM processor. The solder joints looked fine and the component looked undamaged. Connecting the battery was still not activating the Roomba. I then applied physical pressure to the crystal, connected the battery and was greeted with a hello musical sequence from the Roomba! With some experimentation (fiddling with the crystal) I was able to get the Roomba to start playing music really slowly (almost on demand). I was pretty sure I had found the cause of my Roomba's early death.<br /><br />The cause was hard to find but the fix was simple. I replaced the crystal on the board with a new <a href="http://www.jaycar.co.nz/productView.asp?ID=RQ5287&CATID=&keywords=crystal&SPECIAL=&form=KEYWORD&ProdCodeOnly=&Keyword1=&Keyword2=&pageNumber=&priceMin=&priceMax=&SUBCATID=">8Mhz crystal from jaycar</a>. My Roomba now runs like a champ! The crystal is slower than the maximum 32MHz that the processor can take so it would probably be possible to overclock the Roomba (!) though I imagine many of the routines are dependent on the crystal being 8MHz.<br /><br />From reading the iRobot forums, there are appears to be several other people who have had similar symptoms and at least one other <a href="http://forums.irobot.com/irobothome/board/message?board.id=80&thread.id=4980">person who has identical symptoms</a>. I'm left to wonder if iRobot has unknowingly used a bad run of crystals...<br /><br />Here are the pictures:<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0222-738882.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0222-738803.jpg" alt="" border="0" /></a><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />The top of the Roomba with its faceplate removed. The face plate can be removed carefully prying it off, starting from the edge closest to the dustbin. There are clips on the outer circumference as well as the inner circumference. The faceplate clips are quite tight so it will need careful but forceful tugs.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0221-714674.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0221-714660.jpg" alt="" border="0" /></a><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />The Roomba's bottom cover needs to be removed. Start by removing the side brush and unscrewing the four large screws. Once the bottom cover is removed, the 10 small screws on the bumper bar should also be removed.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0220-781533.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0220-781523.jpg" alt="" border="0" /></a><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />The Roomba with the bottom cover and battery removed.<br /><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0219-781460.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0219-781449.jpg" alt="" border="0" /></a><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />The Robot with its top cover removed. The crystal is under the control panel which can be removed by unscrewing another four screws. Unscrewing the left and right wheels on the bottom of the roomba will make it easier to work with the Roomba. Make sure you work on a bench and not the carpet as static discharges may damage or destroy components<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0210-716138.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0210-716079.jpg" alt="" border="0" /></a><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />The robot with the top cover and control panel removed. The crystal is the small metallic, cylindrical component to the right of the "iRobot" logo on the bottom right quadrant of the circuit board.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0225-715473.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0225-715459.jpg" alt="" border="0" /></a><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />A close up of the revision number and date as printed on the board.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0215-716231.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0215-716168.jpg" alt="" border="0" /></a><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />A close up of the offending component. The component was glued to the circuit board during manufacturing. The ARM processor is in the same area but on the opposite side of the board.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0218-714599.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0218-714582.jpg" alt="" border="0" /></a><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />Another view of the faulty crystal showing its legs and where it is soldered to the main board. The underside of the crystal has "8.000" engraved -- indicating that the crystal is an 8Mhz crystal.<br /><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0223-738963.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0223-738948.jpg" alt="" border="0" /></a><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />The replacement crystal. The packaging is different (rectangular but that doesn't matter).<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0228-715558.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0228-715543.jpg" alt="" border="0" /></a><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />The new crystal soldered to the board. I applied some hot glue (not pictured) to make sure the crystal won't move around and short out other components.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0229-776099.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0229-776089.jpg" alt="" border="0" /></a><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />I side shot of the new crystal. "8.000" means 8.000Mhz or 8MHz :-).tumtumtumhttp://www.blogger.com/profile/08707154189579608918noreply@blogger.com5tag:blogger.com,1999:blog-4350777349185682004.post-29359212924231558022008-05-13T11:06:00.000-07:002008-05-13T11:08:20.824-07:00Another video of my RobonovaSlightly more intelligent this time :-)<br /><br /><object width="425" height="355"><param name="movie" value="http://www.youtube.com/v/RnFXLfMBmgQ&hl=en"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/RnFXLfMBmgQ&hl=en" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"></embed></object>tumtumtumhttp://www.blogger.com/profile/08707154189579608918noreply@blogger.com4tag:blogger.com,1999:blog-4350777349185682004.post-60046439543440202142008-05-13T08:15:00.000-07:002008-05-13T08:16:59.794-07:00Video of my RN-1 walking autonomously<object width="425" height="355"><param name="movie" value="http://www.youtube.com/v/ar4Ao1aLECo&hl=en"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/ar4Ao1aLECo&hl=en" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"></embed></object>tumtumtumhttp://www.blogger.com/profile/08707154189579608918noreply@blogger.com1tag:blogger.com,1999:blog-4350777349185682004.post-20346719145334169982008-05-08T22:42:00.000-07:002008-05-08T22:57:03.212-07:00Modifying GWS voltage indicator to show voltage in bar modeThe OBI-02-5 is a 6V battery level indicator made up of 10 SMD LEDs driven by a LN3914N indicator driver. I wanted to use one of these on my RN-1 robot, not necessarily for the indicator but because all humanoid robots need cool looking LEDs :-).<br /><br />GWS make various versions for 4, 5 and 6 cell NiMH/Nicad cells(4.8V, 6V and 7.2V) specifically for RC applications. GWS ships the indicators configured to only light up one LED at a time. I wanted all indicator to light up like a BAR indicator rather than a dot/point indicator.<br /><br />The datasheet for the LM3914N shows that it is capable of displaying in bar mode. The mode selection pin (pin 9) needs to be hooked up to the V+ pin (pin 3).<br /><br />Pictures:<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0203-735808.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0203-735797.jpg" alt="" border="0" /></a><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />The indicator board from the front<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0202-735770.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0202-735760.jpg" alt="" border="0" /></a><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />The indicator board from the back<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0205-705758.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0205-705745.jpg" alt="" border="0" /></a><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />The back of the board after modification<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0208-712449.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0208-712361.jpg" alt="" border="0" /></a><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />RN-1 proudly displaying his lightstumtumtumhttp://www.blogger.com/profile/08707154189579608918noreply@blogger.com0tag:blogger.com,1999:blog-4350777349185682004.post-56442616975271360862008-05-02T20:05:00.000-07:002008-05-19T07:57:38.293-07:00Fixing Roomba 500/570 side brushes with stitchesThe Roomba 500 series side brush is infamous for amputating itself. Over time, the arms of the side brush weaken and break off very near the center hub. It's very hard to glue the arms back on since the surface area of the breakge point is very small but it looks like you could simple stich the arm back on using a small needle and thread.<br /><br />Here's some pictures of a side brush with an arm reattached using stitches!<br /><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0196-719893.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0196-719830.jpg" alt="" border="0" /></a><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />The side brush was first attached back to the hub with some superglue and left to dry for 15 minutes (aparently superglue can react with cotton and catch fire!). After the glue dried sufficiently, I used a small needle and thread and stitched the arm to the central hub. I didn't make too many stitches as I was concerned that too many needle holes would compromise the plastic.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0197-774685.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0197-774612.jpg" alt="" border="0" /></a>tumtumtumhttp://www.blogger.com/profile/08707154189579608918noreply@blogger.com1tag:blogger.com,1999:blog-4350777349185682004.post-70260245216383553622008-05-02T09:24:00.000-07:002008-05-02T09:41:09.622-07:00Robonova hip and ankle jointsI've got a <span class="blsp-spelling-error" id="SPELLING_ERROR_0">Robonova</span> RN-1 humanoid robot. It's a great robot but the use of a screws fitted into thin threaded brackets for the hip and ankles is a really bad design flaw in the <span class="blsp-spelling-error" id="SPELLING_ERROR_1">Robonova</span>.<br /><br />My <span class="blsp-spelling-error" id="SPELLING_ERROR_2">robonova's</span> hip/leg joints and leg/ankle joints failed within 2 weeks of building the robot. The joints <span class="blsp-spelling-corrected" id="SPELLING_ERROR_3">loosened</span> causing the robot to go off balance and fail many of his moves. The screws eventually came lose. Eventually some of the threaded holes in the brackets wore and became useless!<br /><br />I've replaced the screws with standard M2 (2mm) screws and matching nuts. The best nuts to use would have been <span class="blsp-spelling-error" id="SPELLING_ERROR_4">nyloc</span> nuts as they are less likely to come loose. My local fastener supplier was out of M2 <span class="blsp-spelling-error" id="SPELLING_ERROR_5">nyloc</span> nuts so I had to go with standard nuts (for now :-)).<br /><br />The advantage of using screws and nuts instead of just screws is that the threads in the bracket holes aren't required so you can utilise all 8 holes (4 threaded, 4 <span class="blsp-spelling-error" id="SPELLING_ERROR_6">unthreaded</span>) to create an extra strong joint!<br /><br />Here are some pictures:<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0192-718055.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0192-718051.jpg" alt="" border="0" /></a><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0193-718098.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0193-718090.jpg" alt="" border="0" /></a><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0195-776599.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://www.abstractpath.com/weblog/uploaded_images/SPM_A0195-776590.jpg" alt="" border="0" /></a>tumtumtumhttp://www.blogger.com/profile/08707154189579608918noreply@blogger.com1