<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2832016242820899544</id><updated>2011-09-20T09:56:02.099-07:00</updated><category term='job'/><category term='okcupid'/><category term='personal'/><category term='online dating'/><title type='text'>Saya Video Editor unofficial dev blog</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>66</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-5341458321816782203</id><published>2011-04-22T18:03:00.000-07:00</published><updated>2011-04-22T18:04:08.522-07:00</updated><title type='text'>Slowly advancing...</title><content type='html'>The resources panel has been redesigned, and now accepts Drag and Drop for quick importing of files. Multiple files can be imported on the same operation (that is, once I write the part for actually importing a file), and if accidentally you import 100 files, you're presented with a confirmation dialog.&lt;br /&gt;&lt;br /&gt;In other news, I've decided to switch the project file format from XML to JSON. It's just much easier to handle.&lt;br /&gt;&lt;br /&gt;Argh, there's so much to do, and I don't know where to start!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-5341458321816782203?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/5341458321816782203/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=5341458321816782203' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/5341458321816782203'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/5341458321816782203'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2011/04/slowly-advancing.html' title='Slowly advancing...'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-2749895084555410484</id><published>2010-11-22T20:00:00.000-08:00</published><updated>2010-11-22T20:00:13.180-08:00</updated><title type='text'>Status update</title><content type='html'>Just wanted to tell you people that I'm still alive, and the project's getting a healthy recovery. It's still very weak, but I'm gaining pace and some functions that were forgotten are being implemented right now.&lt;br /&gt;&lt;br /&gt;I hope to have a functional playback controller soon (still without codec support, unfortunately).&lt;br /&gt;&lt;br /&gt;Read the official blog for more info.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-2749895084555410484?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/2749895084555410484/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=2749895084555410484' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/2749895084555410484'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/2749895084555410484'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2010/11/status-update.html' title='Status update'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-5773567388950462503</id><published>2009-07-10T17:01:00.000-07:00</published><updated>2009-07-10T17:12:41.971-07:00</updated><title type='text'>Personal situations update: July 10, 2009</title><content type='html'>Hello. Just wanted to update you and tell you that Saya is NOT dead... by an inch.&lt;br /&gt;&lt;br /&gt;The depression came back, but this time I've really managed to overcome it. It has been a very chaotic month. I began to feel lonely and in desperate need to seek a girlfriend. My delusions had made me believe that I could never find a girlfriend (in part because of my own depression), but thanks to a huge effort involving courage, asking girls out through third parties and joining several social networking websites, my self-esteem has finally stabilized to a non-negligible positive value.&lt;br /&gt;&lt;br /&gt;On the other hand, I got a job! And a very good one. Not very good financially speaking, but one without excessive stress and which will allow me to occasionally work SOHO (at home).&lt;br /&gt;&lt;br /&gt;Today is one of those days. I got a terrible stomach sickness (I'll omit the gross details) today's morning, and I had to stay at home. Even with a huge pressure to have the work finished by this monday, I feel fine. I've also upgraded my copy of Code::Blocks (which now has a lot of very-needed features) allowing me to code without problems.&lt;br /&gt;&lt;br /&gt;This is where things are getting interesting. The combination of programming seriously while listening to my favorite music at home, has given me a second boost in the desire to keep working on Saya.&lt;br /&gt;&lt;br /&gt;Unfortunately, i have very little time left. But at least Saya is getting a ray of hope as an in-hiatus project. Don't despair!&lt;br /&gt;&lt;br /&gt;Maybe in a couple of months, if everything goes well, I'll be able to get back to work on the project.&lt;br /&gt;&lt;br /&gt;I'd also like to thank everyone for their kind words of support during my darkest hours. Thanks to you, and to everyone who prayed for me, I'm still alive, and kicking!&lt;br /&gt;&lt;br /&gt;Thank you all!&lt;br /&gt;&lt;br /&gt;Sincerely,&lt;br /&gt;Rick.&lt;br /&gt;&lt;br /&gt;P.S. Receiving some money would also help. If someone charitative wants to give a poor programmer some financial support, he's welcome to do so ;-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-5773567388950462503?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/5773567388950462503/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=5773567388950462503' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/5773567388950462503'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/5773567388950462503'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2009/07/personal-situations-update-july-10-2009.html' title='Personal situations update: July 10, 2009'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-3229688814582851950</id><published>2009-06-07T11:22:00.000-07:00</published><updated>2009-06-07T11:45:23.841-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='online dating'/><category scheme='http://www.blogger.com/atom/ns#' term='okcupid'/><category scheme='http://www.blogger.com/atom/ns#' term='job'/><title type='text'>The depression is over!</title><content type='html'>&lt;img style="display:block; margin:0px auto 10px; text-align:center;width: 400px; height: 319px;" src="http://1.bp.blogspot.com/_iBNw06Dsj6g/SiwJlXcRKvI/AAAAAAAAAFU/IicSa6T5qbM/s400/%5Blarge%5D%5BAnimePaper%5Dwallpapers_The-Melancholy-Of-Haruhi-Suzumiya_5acr3d_-edit557.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5344657395334327026" /&gt;&lt;br /&gt;&lt;center&gt;&lt;span style="font-weight:bold;"&gt;NEW LIFE, HERE I COME!&lt;/span&gt;&lt;/center&gt;&lt;br /&gt;&lt;br /&gt;A week ago I joined &lt;a href="www.okcupid.com"&gt;okcupid.com&lt;/a&gt;, an online dating site based on questionaires so that you can find your match based on politics, moral, hygiene, religion, common interests, sexual tastes, attitudes towards life and whatnot. Answering over 1000 multiple-choice questions has helped me know myself and boost my self-esteem. I no longer feel lonely or doomed to die abandoned by everyone. I go to bed with hope instead of pain, and wake up with joy instead of the burden of having to live another day.&lt;br /&gt;&lt;br /&gt;FINALLY, I am free!!&lt;br /&gt;&lt;br /&gt;If a nerd girl (otaku preferred) wants to become my girlfriend and lives in Mexico City, feel free to visit &lt;a href="http://www.okcupid.com/profile/kyon_df/"&gt;my dating profile&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Anyway. My current job is still going to be very demanding for the next two weeks. Maybe then I'll be able to resume work on Saya. &lt;br /&gt;&lt;br /&gt;Until then, so long!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-3229688814582851950?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/3229688814582851950/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=3229688814582851950' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/3229688814582851950'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/3229688814582851950'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2009/06/depression-is-over.html' title='The depression is over!'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_iBNw06Dsj6g/SiwJlXcRKvI/AAAAAAAAAFU/IicSa6T5qbM/s72-c/%5Blarge%5D%5BAnimePaper%5Dwallpapers_The-Melancholy-Of-Haruhi-Suzumiya_5acr3d_-edit557.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-8976564402165494917</id><published>2009-06-01T20:19:00.000-07:00</published><updated>2009-06-01T20:22:49.311-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal'/><category scheme='http://www.blogger.com/atom/ns#' term='job'/><title type='text'>First day at job</title><content type='html'>At least I got a new job, but I'm beginning to understand that phrase about earning the bread with one's sweat.&lt;br /&gt;&lt;br /&gt;The job was supposed to be from 9 to 6, but due to schedule reasons, I'll have to be from 8 to 7, AND 4 additional hours on weekends. At least for these two weeks.&lt;br /&gt;&lt;br /&gt;I don't think I'll be able to work on Saya for a while.&lt;br /&gt;&lt;br /&gt;I'm beginning to wonder if the project is doomed to failure due to lack of time. Sigh.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-8976564402165494917?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/8976564402165494917/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=8976564402165494917' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/8976564402165494917'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/8976564402165494917'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2009/06/first-day-at-job.html' title='First day at job'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-6709840187304355539</id><published>2009-05-29T16:35:00.000-07:00</published><updated>2009-05-29T16:37:50.907-07:00</updated><title type='text'>I GOT A JOB!!!</title><content type='html'>Expect a couple of weeks so I can stabilize, and I'll be working on Saya again. Now... what was I doing before I suspended activities? :(&lt;br /&gt;&lt;br /&gt;Anyway. Let's hope we haven't lost much time, and the Pitivi guys are really putting money into it. We cannot lose to them!!&lt;br /&gt;&lt;br /&gt;Thanks for your prayers, everyone.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-6709840187304355539?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/6709840187304355539/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=6709840187304355539' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/6709840187304355539'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/6709840187304355539'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2009/05/i-got-job.html' title='I GOT A JOB!!!'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-5850506764372326262</id><published>2009-05-28T21:19:00.000-07:00</published><updated>2009-05-28T23:13:33.504-07:00</updated><title type='text'>Need to check my vision...</title><content type='html'>Just this evening, I noticed that reading seemed to be more difficult for me. I noticed that straight lines look wavy on the center of my vision when I look through the right eye.&lt;br /&gt;&lt;br /&gt;I need to go to a doctor ASAP. Let's hope I don't wake up blind by tomorrow.&lt;br /&gt;&lt;br /&gt;Jesus.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update (one hour later):&lt;/b&gt; I got to bed and one hour later I realized my eye had been hurting a bit this day. I noticed because it stopped hurting. I can see normally again! :D&lt;br /&gt;&lt;br /&gt;Thank God!&lt;br /&gt;&lt;br /&gt;I guess I need to check myself for hypertension then.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-5850506764372326262?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/5850506764372326262/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=5850506764372326262' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/5850506764372326262'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/5850506764372326262'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2009/05/need-to-check-my-vision.html' title='Need to check my vision...'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-4595818411537049221</id><published>2009-05-28T16:33:00.000-07:00</published><updated>2009-05-28T16:35:18.296-07:00</updated><title type='text'>First commit in a while!</title><content type='html'>&lt;span style="font-style:italic;"&gt;Sashiburi&lt;/span&gt; guys. Long time, no see.&lt;br /&gt;&lt;br /&gt;I can't really say that Saya development has restarted. I'm still unemployed and I still feel depressed every once in a while (btw, looking for a girlfriend in Mexico city. Anyone?).&lt;br /&gt;&lt;br /&gt;In any case, I hope development will restart soon. There's a 50% chance that I get a new job this monday. Wish me luck!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-4595818411537049221?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/4595818411537049221/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=4595818411537049221' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/4595818411537049221'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/4595818411537049221'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2009/05/first-commit-in-while.html' title='First commit in a while!'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-9011053189888218486</id><published>2009-04-23T12:43:00.000-07:00</published><updated>2009-04-23T12:47:39.495-07:00</updated><title type='text'>Alergic to certain brands of orange juice...</title><content type='html'>For the past 2 or three weeks I've tried to concentrate on developing, but a mild-yet-annoying-as-hell headache always interrupts me just when I try to code, which is around 10 or 11AM.&lt;br /&gt;&lt;br /&gt;I just can't concentrate like that. I've tried taking antiacids (it happens to me, sometimes I get headaches when I get gastritis), painkillers, and I even began to fear it might be a tumor.&lt;br /&gt;&lt;br /&gt;Today I ran out of the orange juice that mom had purchased. And I didn't get a headache after breakfast today. WTF!?&lt;br /&gt;&lt;br /&gt;I feel like an idiot. Fearing cancer when in fact it was just a simple allergy. Stupid orange juice. Let's hope that tomorrow I can recover from these code-less weeks.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-9011053189888218486?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/9011053189888218486/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=9011053189888218486' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/9011053189888218486'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/9011053189888218486'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2009/04/alergic-to-certain-brands-of-orange.html' title='Alergic to certain brands of orange juice...'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-7893850938282540459</id><published>2009-04-08T20:24:00.000-07:00</published><updated>2009-04-08T20:29:58.879-07:00</updated><title type='text'>Restarting engine... vroom vroom... it works! :)</title><content type='html'>Finally! My first day of coding since a full month. Getting my brain to start after a full month of not seeing the code was like losing my way back in a maze. "Huh? Where did this go? What do I do now?"&lt;br /&gt;&lt;br /&gt;So I had to start with the simplest of things: The project panel. It only needed a tree and a context menu. Man, did I have to dig in the user manual to find it.&lt;br /&gt;&lt;br /&gt;But it worked! :) I'm fresh and ready to start coding again!&lt;br /&gt;&lt;br /&gt;... tomorrow :P&lt;br /&gt;&lt;br /&gt;On the other hand, I realized why it took me so long to start programming. It seems I have gastritis (or perhaps a stomach ulcer). If I stayed too much without eating, I began feeling hungry, dizzy and with headaches. So now I'm taking medications (omeprazole) to restore my stomach to pristine conditions. Since the first day of medications, I felt better and with more energy. Who would've thought?&lt;br /&gt;&lt;br /&gt;On the bad news, I'm STILL unemployed :( Let's hope I find a good job after Easter! :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-7893850938282540459?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/7893850938282540459/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=7893850938282540459' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/7893850938282540459'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/7893850938282540459'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2009/04/restarting-engine-vroom-vroom-it-works.html' title='Restarting engine... vroom vroom... it works! :)'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-5115477923857854731</id><published>2009-03-26T08:50:00.000-07:00</published><updated>2009-03-26T08:54:21.279-07:00</updated><title type='text'>The Exhaustion of Saya Developer: Book 2</title><content type='html'>It was two weeks of being sick. I was horribly bored and exhausted at the same time. Some friends of my family invited us to take a vacation, invitation which I accepted joyfully. We went to [place undisclosed for security reasons] and I had a good time. Finally, I returned home yesterday (with a horrible headache, btw).&lt;br /&gt;&lt;br /&gt;Now I'm finally resting and preparing myself to continue working on Saya (after a full month of interruptions) and to search for a new job next monday.&lt;br /&gt;&lt;br /&gt;Boy, what a month.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-5115477923857854731?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/5115477923857854731/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=5115477923857854731' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/5115477923857854731'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/5115477923857854731'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2009/03/exhaustion-of-saya-developer-book-2.html' title='The Exhaustion of Saya Developer: Book 2'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-7813055023403201417</id><published>2009-03-09T20:01:00.000-07:00</published><updated>2009-03-09T20:03:45.594-07:00</updated><title type='text'>Quit my job, got the flu...</title><content type='html'>Hi guys. I'd like to inform you that due to health reasons I'll be unable to work on Saya for the next few days (a horrible flu). Also I had to quit my job for health concerns (and other reasons I won't be detailing here).&lt;br /&gt;&lt;br /&gt;Still, thanks for your support. Sincerely,&lt;br /&gt;Rick.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-7813055023403201417?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/7813055023403201417/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=7813055023403201417' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/7813055023403201417'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/7813055023403201417'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2009/03/quit-my-job-got-flu.html' title='Quit my job, got the flu...'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-2297229184767940433</id><published>2009-03-04T21:20:00.000-08:00</published><updated>2009-03-09T20:05:43.194-07:00</updated><title type='text'>Converted Project Pane, first bugs appeared...</title><content type='html'>The good news: I managed to convert around 90% of the Project Pane (the tree window and popup menus still need conversion), and moved the code away from the main window.&lt;br /&gt;&lt;br /&gt;The bad news: The window state saving and loading routines seem buggy... the project pane is not shown when it should, so I had to comment the call that hides it when the main window is invisible.&lt;br /&gt;&lt;br /&gt;I do think I spotted the bug - Qt saves the window layout data in binary form, so I had to convert it to base64. However, I haven't tested if the state loading routines work after the change.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;(Update (March 9, 2009) : The window state saving/loading routines are now fixed!)&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I also spotted some functions that aren't called by the main menu. I need to fix them, too. But now the code seems much cleaner (I removed a lot of wxWidgets UI code that now is generated automatically by QtDesigner.&lt;br /&gt;&lt;br /&gt;After seeing how much the code is simplified, I can finally say that I don't regret switching to Qt.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-2297229184767940433?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/2297229184767940433/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=2297229184767940433' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/2297229184767940433'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/2297229184767940433'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2009/03/converted-project-pane-first-bugs.html' title='Converted Project Pane, first bugs appeared...'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-8220930831729299551</id><published>2009-02-22T09:58:00.001-08:00</published><updated>2009-02-23T17:44:27.134-08:00</updated><title type='text'>Qt's aboutToShow() signal: Did we find a bug?</title><content type='html'>While converting the wxWidgets code to Qt, I realized something. A QMenu's "aboutToShow()" signal is triggered around 30 TIMES whenever you open that menu. So my menu refreshing routines will be called that many times.&lt;br /&gt;&lt;br /&gt;The question is: How to work around it?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update (Feb 23, 2009, 19:35)&lt;/b&gt;: Alexandru wrote a sample application, and surprisingly for me, the application does NOT trigger the aboutToShow() signal a lot of times per menu, but rather, only once. Which means only one thing:&lt;br /&gt;&lt;br /&gt;The bug's mine. Now I need to check out what went wrong.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update (Feb 23, 2009, 19:43)&lt;/b&gt;: I see now what happened. The function I used to automate the connection creation was recursive, but I added the aboutToShow() connections on that same function, which, obviously, got called a lot of times.&lt;br /&gt;&lt;br /&gt;I moved the aboutToShow connections elsewhere, and problem solved :)&lt;br /&gt;&lt;br /&gt;Alexandru gets a trust point for helping me fix this bug. Yay!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-8220930831729299551?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/8220930831729299551/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=8220930831729299551' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/8220930831729299551'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/8220930831729299551'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2009/02/qts-abouttoshow-signal-did-we-find-bug.html' title='Qt&apos;s aboutToShow() signal: Did we find a bug?'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-6992065267101881270</id><published>2009-02-19T19:58:00.000-08:00</published><updated>2009-02-19T20:02:45.352-08:00</updated><title type='text'>Mom's feeling better, and progress has been made!</title><content type='html'>Good news people!&lt;br /&gt;&lt;br /&gt;The first, is that my mom is feeling better :). She's under treatment and the fever is gone. In a month we'll see how her kidney is doing.&lt;br /&gt;&lt;br /&gt;The second good news, is that the event handling code has been finished and the Welcome dialog is functional (but still ugly).&lt;br /&gt;&lt;br /&gt;The one-month goal for the Qt4 conversion deadline now seems possible. Stay tuned.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-6992065267101881270?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/6992065267101881270/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=6992065267101881270' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/6992065267101881270'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/6992065267101881270'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2009/02/moms-feeling-better-and-progress-has.html' title='Mom&apos;s feeling better, and progress has been made!'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-5457827437798440425</id><published>2009-02-15T17:28:00.000-08:00</published><updated>2009-02-15T17:39:00.904-08:00</updated><title type='text'>Alexandru's video demo.</title><content type='html'>Alexandru sent me a demo of filling an area of the screen with a determinate pattern of pixels. I modified his demo a bit so it would display random pixels, and so I could find out which bits corresponded to which color.&lt;br /&gt;&lt;br /&gt;After a while, here's what I got:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;#include &amp;lt;string.h&amp;gt;&lt;br /&gt;&lt;br /&gt;#include &amp;lt;X11/Xlib.h&amp;gt;&lt;br /&gt;#include &amp;lt;X11/Xutil.h&amp;gt;&lt;br /&gt;#include &amp;lt;X11/Xos.h&amp;gt;&lt;br /&gt;&lt;br /&gt;/*demo took from a saya example*/&lt;br /&gt;void fill_image(char *data, int w, int h, int bpp) {&lt;br /&gt; int x, y;&lt;br /&gt;&lt;br /&gt; char *adr;&lt;br /&gt; for (y=0; y&amp;lt;h; y++) {&lt;br /&gt;     for (x=0; x&amp;lt;w; x++) {&lt;br /&gt;         adr = data + (y * w + x) * bpp;&lt;br /&gt;&lt;br /&gt;         unsigned long pixel;&lt;br /&gt;//            if(!(x % 10)) {&lt;br /&gt;//                pixel = 0xFFFF0000;&lt;br /&gt;//            } else if (x &amp;amp; 1) {&lt;br /&gt;//                pixel = 0xFF00FF00;&lt;br /&gt;//            } else {&lt;br /&gt;//                pixel = 0XFFFFFFFF;&lt;br /&gt;//            }&lt;br /&gt;         unsigned int r = rand() &amp;amp; 255;&lt;br /&gt;         unsigned int g = rand() &amp;amp; 255;&lt;br /&gt;         unsigned int b = rand() &amp;amp; 255;&lt;br /&gt;         pixel = (b &amp;lt;&amp;lt; 24) | (g &amp;lt;&amp;lt; 16) | r &amp;lt;&amp;lt; 8;&lt;br /&gt;&lt;br /&gt;         *adr = pixel&amp;gt;&amp;gt;24;&lt;br /&gt;         *(adr + 1) = pixel&amp;gt;&amp;gt;16;&lt;br /&gt;         *(adr + 2) = pixel&amp;gt;&amp;gt;8;&lt;br /&gt;         *(adr + 3) = pixel;&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void clear_image(char *data, int w, int h, int bpp) {&lt;br /&gt; memset(data, 0xFF, w * h * bpp);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;int main() {&lt;br /&gt; Display *m_display;&lt;br /&gt; Window m_window;&lt;br /&gt; GC m_gc;&lt;br /&gt; Visual *m_visual;&lt;br /&gt; int m_screen;&lt;br /&gt; unsigned int m_width;&lt;br /&gt; unsigned int m_height;&lt;br /&gt; unsigned int m_x;&lt;br /&gt; unsigned int m_y;&lt;br /&gt;&lt;br /&gt; XImage *image;&lt;br /&gt;&lt;br /&gt; XEvent event;&lt;br /&gt;&lt;br /&gt; XSizeHints hints;&lt;br /&gt; XSetWindowAttributes attributes;&lt;br /&gt;&lt;br /&gt; int format;&lt;br /&gt; int offset;&lt;br /&gt; char *data;&lt;br /&gt; int bitmap_pad;&lt;br /&gt; int bytes_per_line;&lt;br /&gt;&lt;br /&gt; unsigned int depth;&lt;br /&gt; int bpp;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; if ((m_display = XOpenDisplay((char *)0)) == NULL) {&lt;br /&gt;     printf("cant open x connection\n");&lt;br /&gt;     return -1;&lt;br /&gt; }&lt;br /&gt; m_screen = XDefaultScreen(m_display);&lt;br /&gt;&lt;br /&gt; m_visual = DefaultVisual(m_display, m_screen);&lt;br /&gt;&lt;br /&gt; depth = XDefaultDepth(m_display, m_screen);&lt;br /&gt;&lt;br /&gt; /*list supported depth for demo purposes*/&lt;br /&gt; int count_return;&lt;br /&gt; int *depths = XListDepths(m_display, m_screen, &amp;amp;count_return);&lt;br /&gt; if (depths) {&lt;br /&gt;     int i;&lt;br /&gt;     printf("supported depths:\n");&lt;br /&gt;     for (i=0; i&amp;lt;count_return; i++) {&lt;br /&gt;         if (depths[i] == depth) {&lt;br /&gt;             printf("%d [default]\n", depths[i]);&lt;br /&gt;         } else {&lt;br /&gt;             printf("%d\n", depths[i]);&lt;br /&gt;         }&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     XFree(depths);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /*list pixmap formats for demo purposes*/&lt;br /&gt; XPixmapFormatValues defaultPixmapFormat;&lt;br /&gt; XPixmapFormatValues *pixmapFormats = XListPixmapFormats(m_display, &amp;amp;count_return);&lt;br /&gt; if (pixmapFormats) {&lt;br /&gt;     int i;&lt;br /&gt;     for (i=0; i&amp;lt;count_return; i++) {&lt;br /&gt;         printf("depth:            %d\n", (pixmapFormats + i)-&amp;gt;depth);&lt;br /&gt;         printf("bits_per_pixel:   %d\n", (pixmapFormats + i)-&amp;gt;bits_per_pixel);&lt;br /&gt;         printf("scanline_pad:     %d\n\n", (pixmapFormats + i)-&amp;gt;scanline_pad);&lt;br /&gt;         if (depth == (pixmapFormats + i)-&amp;gt;depth) {&lt;br /&gt;             memcpy(&amp;amp;defaultPixmapFormat, pixmapFormats + i, sizeof(XPixmapFormatValues));&lt;br /&gt;         }&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     XFree(pixmapFormats);&lt;br /&gt;&lt;br /&gt;     bpp = defaultPixmapFormat.bits_per_pixel / 8;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; m_width = 200;&lt;br /&gt; m_height = 100;&lt;br /&gt; m_x = 500;&lt;br /&gt; m_y = 500;&lt;br /&gt;&lt;br /&gt; attributes.event_mask = ExposureMask | KeyPressMask;&lt;br /&gt; attributes.background_pixel = BlackPixel(m_display, m_screen);&lt;br /&gt;&lt;br /&gt; /*depth 32 doesnt work !!*/&lt;br /&gt; m_window = XCreateWindow(m_display, XDefaultRootWindow(m_display), m_x, m_y,&lt;br /&gt;         m_width, m_height, 0, depth, InputOutput, m_visual, CWEventMask | CWBackPixel, &amp;amp;attributes);&lt;br /&gt;&lt;br /&gt; if (!m_window) {&lt;br /&gt;     printf("error creating window\n");&lt;br /&gt;     XCloseDisplay(m_display);&lt;br /&gt;     return -1;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /*set size hints for window*/&lt;br /&gt; hints.min_width = hints.max_width = m_width;&lt;br /&gt; hints.min_height = hints.max_height = m_height;&lt;br /&gt; hints.flags = PSize | PMinSize | PMaxSize;&lt;br /&gt; XSetWMNormalHints(m_display, m_window, &amp;amp;hints);&lt;br /&gt;&lt;br /&gt; /*set windows title*/&lt;br /&gt; XStoreName(m_display, m_window, "X11 Saya");&lt;br /&gt;&lt;br /&gt; /*create graphic context*/&lt;br /&gt; m_gc = XCreateGC(m_display, m_window, 0, NULL);&lt;br /&gt;&lt;br /&gt; /*display the window*/&lt;br /&gt; XMapWindow(m_display, m_window);&lt;br /&gt;&lt;br /&gt; offset = 0;&lt;br /&gt;&lt;br /&gt; /*alloc data buffer for storing image*/&lt;br /&gt; if ((data = (char *) malloc(m_width * m_height * bpp)) == NULL) {&lt;br /&gt;     printf("error malloc");&lt;br /&gt;     //free x structures&lt;br /&gt;     return -1;&lt;br /&gt; }&lt;br /&gt; memset(data, 0, m_width * m_height * bpp);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; bitmap_pad = 32;&lt;br /&gt; bytes_per_line = m_width * bpp;&lt;br /&gt;&lt;br /&gt; image = XCreateImage(m_display, m_visual, depth, ZPixmap, offset, data, m_width, m_height,&lt;br /&gt;                 bitmap_pad, bytes_per_line);&lt;br /&gt;&lt;br /&gt; if (image == NULL) {&lt;br /&gt;     printf("error creating image\n");&lt;br /&gt;     free(data);&lt;br /&gt;     return -1;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; int step = 1;&lt;br /&gt; while (1) {&lt;br /&gt;     XNextEvent(m_display, &amp;amp;event);&lt;br /&gt;     if (event.type == Expose) {&lt;br /&gt;//            printf("expose\n");&lt;br /&gt;         XClearWindow(m_display, m_window);&lt;br /&gt;//            if (step % 2 == 0) {&lt;br /&gt;//                clear_image(data, m_width, m_height, bpp);&lt;br /&gt;//            } else {&lt;br /&gt;             fill_image(data, m_width, m_height, bpp);&lt;br /&gt;//            }&lt;br /&gt;         XPutImage(m_display, m_window, m_gc, image, 0, 0, 0, 0, m_width, m_height);&lt;br /&gt;     } else if (event.type == KeyPress) {&lt;br /&gt;         /*size up the image*/&lt;br /&gt;&lt;br /&gt;         m_width += step*5;&lt;br /&gt;         m_height += step*5;&lt;br /&gt;&lt;br /&gt;         XDestroyImage(image);&lt;br /&gt;&lt;br /&gt;         data = (char *) malloc(m_width * m_height * bpp);&lt;br /&gt;         image = XCreateImage(m_display, m_visual, depth, ZPixmap, offset, data, m_width, m_height,&lt;br /&gt;                 bitmap_pad, 0);&lt;br /&gt;         if (image == NULL) {&lt;br /&gt;             printf("error creating image\n");&lt;br /&gt;             free(data);&lt;br /&gt;             return -1;&lt;br /&gt;         }&lt;br /&gt;&lt;br /&gt;         XResizeWindow(m_display, m_window, m_width, m_height);&lt;br /&gt;&lt;br /&gt;         step++;&lt;br /&gt;         if (step == 10)&lt;br /&gt;             break;&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; XDestroyImage(image);&lt;br /&gt;&lt;br /&gt; XFreeGC(m_display, m_gc);&lt;br /&gt;&lt;br /&gt; if (m_window) {&lt;br /&gt;     XDestroyWindow(m_display, m_window);&lt;br /&gt; }&lt;br /&gt; if (m_display) {&lt;br /&gt;     XCloseDisplay(m_display);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; return 0;&lt;br /&gt;}&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;And here's the result:&lt;br /&gt;&lt;br /&gt;&lt;img style="width: 208px; height: 128px;" src="http://4.bp.blogspot.com/_iBNw06Dsj6g/SZjCfrcPhwI/AAAAAAAAAEM/UKdREwscpBE/s1600/x11.png" alt="[x11.png]" border="0" /&gt;&lt;br /&gt;&lt;br /&gt;With some more effort, we'll be able to reproduce a computer-generated video in realtime. At least in X11, the windows driver will use other code. Thanks a lot, Alexandru! Keep up the good work!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-5457827437798440425?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/5457827437798440425/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=5457827437798440425' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/5457827437798440425'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/5457827437798440425'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2009/02/alexandrus-video-demo.html' title='Alexandru&apos;s video demo.'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_iBNw06Dsj6g/SZjCfrcPhwI/AAAAAAAAAEM/UKdREwscpBE/s72-c/x11.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-8944391769952294721</id><published>2009-02-14T13:19:00.000-08:00</published><updated>2009-02-14T13:21:45.254-08:00</updated><title type='text'>Mother's ill...</title><content type='html'>My mother got a kidney stone, and until she gets the stone removed I'll have to help her do the dialy chores, so I guess I won't have free time to work on Saya for the next 2 or 3 weeks.&lt;br /&gt;&lt;br /&gt;Sorry guys. I'll keep in touch.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-8944391769952294721?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/8944391769952294721/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=8944391769952294721' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/8944391769952294721'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/8944391769952294721'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2009/02/mothers-ill.html' title='Mother&apos;s ill...'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-4142885084870245286</id><published>2009-02-04T16:30:00.000-08:00</published><updated>2009-02-04T16:32:36.260-08:00</updated><title type='text'>My books finally arrived!</title><content type='html'>Herb Stutter: Exceptional C++&lt;br /&gt;&lt;br /&gt;and&lt;br /&gt;&lt;br /&gt;Hughes &amp;amp; Hughes: Professional Multicore Programming.&lt;br /&gt;&lt;br /&gt;Yay!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-4142885084870245286?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/4142885084870245286/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=4142885084870245286' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/4142885084870245286'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/4142885084870245286'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2009/02/my-books-finally-arrived.html' title='My books finally arrived!'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-3617502179202087871</id><published>2009-02-02T19:09:00.000-08:00</published><updated>2009-02-02T19:13:00.457-08:00</updated><title type='text'>Programmer's block</title><content type='html'>I hate it when this happens. The conversion to Qt might seem easy at a glance, but then you realize there's so much to do, and don't even know where to start.&lt;br /&gt;&lt;br /&gt;The worst part is that I had the whole day to program, and I couldn't do anything (well, I updated the website). What a waste.&lt;br /&gt;&lt;br /&gt;Anyway, finally I realized I should leave the main frame for the end, when the rest of the functionality is ported. So I'll start to work on the welcome dialog. Let's hope I can do that this week.&lt;br /&gt;&lt;br /&gt;Sigh.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-3617502179202087871?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/3617502179202087871/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=3617502179202087871' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/3617502179202087871'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/3617502179202087871'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2009/02/programmers-block.html' title='Programmer&apos;s block'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-3898972847388651672</id><published>2009-01-28T20:16:00.000-08:00</published><updated>2009-01-28T20:20:10.986-08:00</updated><title type='text'>Status update...</title><content type='html'>The only work I've been able to do on Saya this week is copying the Main Menu from wx to Qt, and that was on the weekend.&lt;br /&gt;&lt;br /&gt;The reason: I had to sleep at 3 o'clock on Monday and this has exhausted me. Probably I won't be able to work on Saya until Saturday after I've had a VERY GOOD sleep.&lt;br /&gt;&lt;br /&gt;On the other hand, this Friday we'll have the developers meeting. Two people will be joining the team, and two people will be leaving. Let's hope that I can finish the Qt conversion for the end-of-March meeting so we can move on.&lt;br /&gt;&lt;br /&gt;Wish me luck!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-3898972847388651672?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/3898972847388651672/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=3898972847388651672' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/3898972847388651672'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/3898972847388651672'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2009/01/status-update.html' title='Status update...'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-4549225806882355388</id><published>2009-01-19T21:07:00.000-08:00</published><updated>2009-01-19T21:09:23.165-08:00</updated><title type='text'>Report on the non-advance of the project.</title><content type='html'>My job's killing me. I haven't been able to work on Saya the last week, and I this week there will be only a 50/50 chance I can get to work on it.&lt;br /&gt;&lt;br /&gt;On the other hand, it seems I've managed to gather not one, but TWO volunteers. One will work on the mascot (yay! ^_^) and also has some Qt experience. The other one... I forgot, sorry.&lt;br /&gt;&lt;br /&gt;Wish me luck and some free time!&lt;br /&gt;&lt;br /&gt;Good night.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-4549225806882355388?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/4549225806882355388/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=4549225806882355388' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/4549225806882355388'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/4549225806882355388'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2009/01/report-on-non-advance-of-project.html' title='Report on the non-advance of the project.'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-2726838161868919973</id><published>2009-01-11T21:19:00.000-08:00</published><updated>2009-01-11T21:33:07.014-08:00</updated><title type='text'>Report on the Qt conversion</title><content type='html'>Hi everyone. Just a quick report on what I've been doing today.&lt;br /&gt;&lt;br /&gt;I've been having a hard time converting the application to Qt. Basically, I've had to take a decision: To adapt the C++ code directly to use the eventid#'s and get rid of Qt designer advantages, or workaround the autogenerated code by writing some wrapper functions and write LOTS, LOTS AND LOTS OF CODE.&lt;br /&gt;&lt;br /&gt;The advantages to the Qt designer are obvious. Easy code generation, forward compatibility, etc.&lt;br /&gt;But I've grown tired of how wxWidgets loads the UI using xml libraries. Is that REALLY necessary?&lt;br /&gt;&lt;br /&gt;I realized I wouldn't need to choose between the two. Why? Because Qt designer lets you see the generated code! :D&lt;br /&gt;&lt;br /&gt;I only have to copy/paste the code, just like I've been doing with wxFormBuilder. Also, I realized I didn't need to write a lot of code. Remember this?&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;int idFileOpen = XRCID("idFileOpen");&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;I can easily rewrite the Id registering functions into this:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;unsigned int idFileOpen = syActionEvent::RegisterId("idFileOpen","OnFileOpen()");&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Wait, what's that second string for?&lt;br /&gt;This is the beauty of thinking out of the box. We don't have to follow wxWidgets' model anymore! We're FREE To do whatever we want! So besides registering a numeric id for the File-Open event, I can also register the Qt slot name that gets triggered by the corresponding action!&lt;br /&gt;&lt;br /&gt;Later I only have to write a small function that recursively iterates over all QActions in the main menu, gets the corresponding Id, and connects to the slot at the same time.&lt;br /&gt;&lt;br /&gt;But all this thinking really made me get tired of the Qt conversion issue. Yes, I have to admit it, it's boring (coding without visual feedback isn't exactly a rollercoaster ride). So it's better if I rest for a bit and then later next week I'll go on with the conversion.&lt;br /&gt;&lt;br /&gt;Oyasumi nasai (good night).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-2726838161868919973?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/2726838161868919973/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=2726838161868919973' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/2726838161868919973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/2726838161868919973'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2009/01/report-on-qt-conversion.html' title='Report on the Qt conversion'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-4714735645760328245</id><published>2009-01-10T19:04:00.001-08:00</published><updated>2009-01-10T19:57:08.533-08:00</updated><title type='text'>Actions, events, slots, OH MY!</title><content type='html'>I've come to realize that Menu Event Handling in Qt is versatile, but it suffers from a fatal flaw:&lt;br /&gt;It relies on slots. In other words, if I have to run a specific event (like Opening a File), I need to call the object's specific slot either directly, or via a signal. For that I need to actually include the class' header file. And that's a no-no.&lt;br /&gt;&lt;br /&gt;So what am I gonna do? At this time I'm glad I implemented Saya's event system. With it, I can replicate the old "call an event with a specific ID" behavior. That's much better IMHO than having to include a huge header file.&lt;br /&gt;&lt;br /&gt;But before that, we need to create a new class: syActionEvent. Which basically is a reimplementation of wxWidgets' menu event.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update (Jan 10, 2008, 21:50):&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I just realized that to send a menu event you just have to allocate an action. So you'll end up&lt;br /&gt;with a series of action pointers. That would be the elegant solution - but isn't it more elegant to simply have a series of integer values, with no pointers allocated to them? So that's what we're doing in here. Yes, I know, we'll have to create the actions ANYWAY because that's how Qt works. But as I already said, I don't want to be tied to a specific event model. And using numeric id's for events is simpler, IMHO.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-4714735645760328245?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/4714735645760328245/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=4714735645760328245' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/4714735645760328245'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/4714735645760328245'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2009/01/actions-events-slots-oh-my.html' title='Actions, events, slots, OH MY!'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-2964296881402115264</id><published>2009-01-08T18:47:00.000-08:00</published><updated>2009-01-08T18:48:57.878-08:00</updated><title type='text'>GAAAAAAAAAAHHHHHHH!!!!!!</title><content type='html'>There's so much code to convert to Qt!!!! (sorry, had to get it out of my system)&lt;br /&gt;&lt;br /&gt;I need to take a break.&lt;br /&gt;&lt;br /&gt;(On the other hand, I'm so glad I decided to convert before advancing any further! :D )&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-2964296881402115264?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/2964296881402115264/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=2964296881402115264' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/2964296881402115264'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/2964296881402115264'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2009/01/gaaaaaaaaaahhhhhhh.html' title='GAAAAAAAAAAHHHHHHH!!!!!!'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-8046857744461875407</id><published>2009-01-08T16:29:00.000-08:00</published><updated>2009-01-08T17:14:01.648-08:00</updated><title type='text'>The MOC: Qt's lethal trap!</title><content type='html'>Having learned how cool the QT+Python combo is, it had never occurred to me that for C++ you need to go through a very different path to implement signals and slots with Qt.&lt;br /&gt;&lt;br /&gt;What are signals and slots? They're the coolest possible way to implement events. A slot is defined by a specific type of function (which receives a specific type of parameters). A signal is just a function. When you connect a signal and a slot (or various slots), all slots get triggered by the same signal.&lt;br /&gt;&lt;br /&gt;But to implement this in C++, the Qt guys chose to use a meta-object-compiler (MOC), which means you have to PREPROCESS your cpp file in order to compile it. UGH!&lt;br /&gt;&lt;br /&gt;I've been trying to find an alternative way, but all my attempts have failed. The code generated by the moc is both cryptic and hideous, worthy of an obfuscated C contest.&lt;br /&gt;&lt;br /&gt;But not everything is lost: After we change a c++ file, all we have to do is run the MOC on the file and redirect it to a moc header (which we will manually include by the cpp file). The trick is generating the moc file automatically.&lt;br /&gt;&lt;br /&gt;Enter Qmake.&lt;br /&gt;&lt;br /&gt;*disc scratch sound* NOOOOOOOOOOOOOO! I don't want to run Qmake, dammit! &lt;br /&gt;&lt;br /&gt;OK then, enter CMake.&lt;br /&gt;&lt;br /&gt;Ah, that's much better :)&lt;br /&gt;&lt;br /&gt;Guess what? CMake has built-in support for Qt's MOC! All you have to do is add some parameters to your CMake file, and voila... I think.&lt;br /&gt;&lt;br /&gt;Sigh. I didn't want to do this already, it's too soon! I don't want to be a father! (sob). Sorry, got carried away :P&lt;br /&gt;&lt;br /&gt;For now, I'll build the moc files by hand (which will suffice for now), and then, I'll add the necessary stuff when I make the move to CMake.&lt;br /&gt;&lt;br /&gt;This is Rick, and I approve this message.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-8046857744461875407?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/8046857744461875407/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=8046857744461875407' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/8046857744461875407'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/8046857744461875407'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2009/01/moc-qts-lethal-trap.html' title='The MOC: Qt&apos;s lethal trap!'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-3870080488637320605</id><published>2009-01-05T10:28:00.000-08:00</published><updated>2009-01-05T11:49:09.427-08:00</updated><title type='text'>It's official: We're moving to Qt4!</title><content type='html'>I finally made up my mind. After an e-mail conversation with one of the VLC developers, I was told that they submitted quite a few bug reports to wxWidgets, and they were all dismissed. I was also told that wxWidgets was very difficult to work with, and recommended to work with GTK, QT, or anything _else_ (wow, is wxWidgets that bad?).&lt;br /&gt;&lt;br /&gt;And my experience confirms it.&lt;br /&gt;&lt;br /&gt;Now, I tried the QT4 dialog designer, and once you get the hang of it (you need to use a right-click menu to put all the controls in a layout, there's no standard button for that), it's a bliss. But is it compatible with GPLv3? Version 4.3.4 and up are. Hurray! :)&lt;br /&gt;&lt;br /&gt;Sigh, so here goes YET ANOTHER month of changing existing code for arbitrary reasons. I'm lucky I had already adapted a lot of code from wxWidgets ;-).&lt;br /&gt;&lt;br /&gt;I'll close this announcement with a famous quote:&lt;br /&gt;&lt;br /&gt;"Chance favors the prepared mind".&lt;br /&gt;Louis Pasteur&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-3870080488637320605?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/3870080488637320605/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=3870080488637320605' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/3870080488637320605'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/3870080488637320605'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2009/01/its-official-were-moving-to-qt4.html' title='It&apos;s official: We&apos;re moving to Qt4!'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-6795055245698347949</id><published>2009-01-03T23:43:00.000-08:00</published><updated>2009-01-04T00:14:26.114-08:00</updated><title type='text'>VLC knows best.</title><content type='html'>I hadn't realized it, but turns out that VLC, my favorite video player (due to its stability, etc), uses wxWidgets!&lt;br /&gt;&lt;br /&gt;And I just found a Doxygen page documenting every single bit of it. Man, this thing is a masterpiece of art. I think I'm going to start stealing^H^H^H^H^H^H^H^H borrrowing code from VLC :).&lt;br /&gt;&lt;br /&gt;So far, I learned that VLC uses the following approaches to draw video:&lt;br /&gt;&lt;br /&gt;XV (hardware-accelerated Xvideo extension to the X11 server)&lt;br /&gt;X11 (100% software)&lt;br /&gt;GLX&lt;br /&gt;SDL&lt;br /&gt;&lt;br /&gt;All of these, in the form of plugins. Just what I was looking for.&lt;br /&gt;&lt;br /&gt;Unfortunately, that means one thing: My current framework design doesn't seem to be extensible enough. I wrote a VideoOutputDevice class, which was supposed to take care of this. But, how to integrate it with a hardwired set of video control widgets?&lt;br /&gt;&lt;br /&gt;VideoOutputDevice has a function to Set the size. And now I'm starting to see something else that I missed. Before now, I didn't actually NEED the VideoOutputDevice to remember the width and height - that was something that wxVideoPanel had. But now I'll need to specify not only the width and height, but also top and left (relative to the current screen), so that we can use any direct rendering plugins.&lt;br /&gt;&lt;br /&gt;I'll also need to add a registry of VideoOutputDevice classes, and generalize wxVideoOutputDevice into a more generic class. Or actually, add a new class: syBitmapSink. The only thing this class will do is to load data from a syBitmap. This way, we will be able to use a "Default" VideoOutputDevice, which on Flushing, will send the data to a syBitmapSink. And wxVideoPanel will be that sink.&lt;br /&gt;&lt;br /&gt;Since the object coordinates, width and height will change dynamically, the new VideoOutputDevice subclasses will have everything they need to perform the rendering. So it's all matter of which class gets instantiated on startup.&lt;br /&gt;&lt;br /&gt;Neat, huh? :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-6795055245698347949?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/6795055245698347949/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=6795055245698347949' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/6795055245698347949'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/6795055245698347949'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2009/01/vlc-knows-best.html' title='VLC knows best.'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-8765592984982784541</id><published>2009-01-03T19:19:00.000-08:00</published><updated>2009-01-03T19:48:59.106-08:00</updated><title type='text'>...and Pandora's Box was opened.</title><content type='html'>Oh my, look at all these bugs! Will the Playback framework will ever be completed?&lt;br /&gt;&lt;br /&gt;And just when I thought everything was going fine, I realized that playback had a lot of bugs and design flaws.&lt;br /&gt;&lt;br /&gt;* Playback didn't sleep at all, so it was caught in a loop waiting for the time when the next frame had to be painted. (fixed in my PC).&lt;br /&gt;&lt;br /&gt;* The current frame is reset exactly at 4.0 seconds from playback. This is a very curious behavior, but I haven't found out (yet) why it happens.&lt;br /&gt;&lt;br /&gt;* After pressing pause, pressing play resets the current frame to 0 again. And I don't know either why this happens. Sigh.&lt;br /&gt;&lt;br /&gt;* Rendering the current frame into the screen is SLOW AS HELL. Why? Because we're using wxWidgets events for painting, and that's just wrong. Rendering should be done IN THE RENDERING THREAD. But there's a problem... how do I paint directly to the client window from a thread? I need to research more about this.&lt;br /&gt;&lt;br /&gt;In any case, I'm glad I wrote one unit test for the time/frame conversion. I also wrote some other unit tests in the form of painting algorithms. The two bugs mentioned above were caught with a straight line painting video: A vertical line, whose x coordinates are equal to the current frame. I don't have the means to print a text in a bitmap, so I have to use what is available.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-8765592984982784541?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/8765592984982784541/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=8765592984982784541' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/8765592984982784541'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/8765592984982784541'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2009/01/and-pandoras-box-was-opened.html' title='...and Pandora&apos;s Box was opened.'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-611823304487991207</id><published>2009-01-02T20:13:00.001-08:00</published><updated>2009-01-02T20:20:54.598-08:00</updated><title type='text'>Video playback engine WORKS!</title><content type='html'>Finally I realized why the CPU hogging. I hadn't implemented the Video Output code (all video output was still done in the testing code, in the main thread :P ). But now we can play, pause, fast forward... reverse playback hasn't been tested yet. I need to modify the Demo Video code to see if it actually works (audio, on the other hand, hasn't been taken care of yet).&lt;br /&gt;&lt;br /&gt;On the other hand, a friend JUST recommended me to use the Xine engine. Sigh. Why didn't I find out earlier!! Still, xine only works partially on Windows... on CVS. Oh well, what can we do about it?&lt;br /&gt;&lt;br /&gt;This leds me to think about it. Why is it that when someone tries to make something that works, nobody helps him but everyone is eager to criticize? People from IRC laughed at me. Meanwhile, support and/or suggestions didn't come. Well, some people did help me, that's why they're on the team. But still, no experienced programmer. What am I supposed to do all alone? Oh, I forgot about the mailing list guys, they also provided valuable help. Unfortunately, everyone's working on his own project.&lt;br /&gt;&lt;br /&gt;If a good C++ programmer is reading this, PLEASE HELP! I can't do it all by myself! It's been more than 7 months already, and I'm still on my own. Maybe someone will help when the project advances further.&lt;br /&gt;&lt;br /&gt;See ya.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-611823304487991207?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/611823304487991207/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=611823304487991207' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/611823304487991207'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/611823304487991207'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2009/01/video-playback-engine-works.html' title='Video playback engine WORKS!'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-712743989534232516</id><published>2009-01-01T14:10:00.000-08:00</published><updated>2009-01-01T18:12:05.501-08:00</updated><title type='text'>It's alive, Igor!!! It's... having seizures?</title><content type='html'>After a lot of debugging and refactoring code, I finally got the Playback manager to work... and crash / hang.&lt;br /&gt;&lt;br /&gt;First of all, I had overlooked a lot of things while coding the playback framework. I hadn't been given a single opportunity to ACTUALLY test it. But now that it kinda works... the bugs/flaws started to appear, one after another.&lt;br /&gt;&lt;br /&gt;For starters, CPU utilization goes to 50% when PAUSED, and 30% when RUNNING. O.o&lt;br /&gt;Second, on exit, for some reason that I haven't determined yet, sometimes I get segfaults, and sometimes hangs.&lt;br /&gt;&lt;br /&gt;But at least I'm getting closer: The play/pause button interrupts and continues playback :)&lt;br /&gt;&lt;br /&gt;I'll commit the code to the SVN tree when these bugs get fixed.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update (Jan 1st, 2009):&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I *think* I know what's happening. It's during ~AVController(). The VideoInputDevice object generates a segfault when accessing one of its mutexes. But if we get a segfault, it means that this location is no longer valid. In other words, we're dealing with a dangling pointer. Which means that somehow, the VideoInputDevice already got deleted somewhere else. But when, and how?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update (Jan 1st, 2009, 19:55):&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Ah, I see what happened.&lt;br /&gt;&lt;br /&gt;AVController's destructor calls AVDevice::ShutDown(). But when InputMonitor (which is a subclass of AVDevice) deletes its Video Input Device on destruction, it fails to reset the pointer. So when ~AVController() calls ShutDown(), we're operating on an already-released object. In other words, in the destructor chain of InputMonitor, we deleted an object prematurely. The problem was easily fixed by simply commenting the deletion line.&lt;br /&gt;&lt;br /&gt;Also, there's no resource problem with ~InputMonitor, because it always uses the same InputDevice. Besides, InputMonitor only gets created and deleted once. So how is InputMonitor's FileVID object deleted?&lt;br /&gt;&lt;br /&gt;With a new class I created, AVDeviceRegistry. On deletion (that means the program's shutdown) it deletes all created AVDevices. And when an AVDevice is deleted, it unregisters itself from the list. Ta-da!&lt;br /&gt;&lt;br /&gt;Now that the app doesn't crash on exit anymore, we're ready to commit to SVN, and later fix the CPU-thrashing Issue. Yay!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-712743989534232516?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/712743989534232516/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=712743989534232516' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/712743989534232516'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/712743989534232516'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2009/01/its-alive-igor-its-having-seizures.html' title='It&apos;s alive, Igor!!! It&apos;s... having seizures?'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-4616229794693460206</id><published>2008-12-28T20:31:00.001-08:00</published><updated>2008-12-28T21:42:42.865-08:00</updated><title type='text'>First bugs found! :)</title><content type='html'>The good news: I found new bugs in the playback module.&lt;br /&gt;The bad news: I found new bugs in the playback module! :D&lt;br /&gt;&lt;br /&gt;When the AVController is paused, I haven't yet implemented a way to signal the main thread that it's paused. See, we have to check not one thread, but four. So that means we can't use a single flag, but four.&lt;br /&gt;&lt;br /&gt;The problem is, we need to detect different conditions:&lt;br /&gt;&lt;br /&gt;If the thread is invalid,&lt;br /&gt;if the thread is valid but paused,&lt;br /&gt;if the thread is running,&lt;br /&gt;if the thread has stopped.&lt;br /&gt;&lt;br /&gt;And this for each thread. But we need to check if the threads haven't aborted abruptly.&lt;br /&gt;&lt;br /&gt;At least we're closer to getting this to work.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update (28/Dec/2008, 11:41PM):&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The play/pause bug has been fixed now :). No more deadlocks! Now we're going to test the Demo (the blue colored figurines in the screenshots) using AVController. But that'll be for another day, I need to go to sleep, it's very late already.&lt;br /&gt;&lt;br /&gt;G'night.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-4616229794693460206?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/4616229794693460206/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=4616229794693460206' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/4616229794693460206'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/4616229794693460206'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/12/first-bugs-found.html' title='First bugs found! :)'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-6617691616725066752</id><published>2008-12-27T20:14:00.000-08:00</published><updated>2008-12-27T20:19:19.760-08:00</updated><title type='text'>Video Playback controls advancing...</title><content type='html'>Good news (as usual ;-), I've managed to tie the AVController class (actually, the AVPlayer class, which is a subclass of AVController) with the playback buttons.&lt;br /&gt;&lt;br /&gt;Whenever I press "play/stop", the AVPlayer instance receives a play or a stop event (a Saya event, not a wxWidgets event - this is what makes it important, because it makes our core classes still toolkit independent). Same goes when I press "fast forward", "fast rewind" buttons, etc.&lt;br /&gt;&lt;br /&gt;I'd post a screenshot, but a screenshot of a messagebox is pretty boring.&lt;br /&gt;&lt;br /&gt;In any case, now I have the tools to start testing the playback framework I've been working so hard during these 4 months.&lt;br /&gt;&lt;br /&gt;I'm so excited! I feel just like Dr. Frankenstein waiting for the thunder to bring my creature to life, mwahahahahah!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-6617691616725066752?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/6617691616725066752/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=6617691616725066752' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/6617691616725066752'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/6617691616725066752'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/12/video-playback-controls-advancing.html' title='Video Playback controls advancing...'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-1864351207423669795</id><published>2008-12-26T09:07:00.000-08:00</published><updated>2008-12-26T09:11:41.536-08:00</updated><title type='text'>The C++ Source: A wonderful C++ website</title><content type='html'>&lt;a href="http://www.artima.com/cppsource" target="_blank"&gt;The C++ Source&lt;/a&gt; is an online journal about C++ programming, it covers many advanced topics including advanced (and often below-the-radar) uses of C++ templates.&lt;br /&gt;&lt;br /&gt;I also read two very interesting articles:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.artima.com/cppsource/top_cpp_aha_moments.html" target="_blank"&gt;Top C++ Aha! moments"&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.artima.com/cppsource/top_cpp_publications.html" target="_blank"&gt;Top C++ non-book publications&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-1864351207423669795?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/1864351207423669795/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=1864351207423669795' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/1864351207423669795'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/1864351207423669795'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/12/c-source-wonderful-c-website.html' title='The C++ Source: A wonderful C++ website'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-2833475103397224126</id><published>2008-12-25T20:19:00.000-08:00</published><updated>2008-12-25T20:25:29.046-08:00</updated><title type='text'>First donation received, and wxSlider skipping problems.</title><content type='html'>First of all, thanks to Zarxrax from Doom9 for his generous donation to the project.&lt;br /&gt;&lt;br /&gt;That said, I'd like to complain about wxSlider. The wxWidgets code for the slider widget has this annoying behavior: If you click on anywhere in the slider, the slider reacts as if a pageup/pagedown had been pressed. I absolutely hate that. Sometimes I want to repeat or advance a DVD scene in VLC player, to have the player skip around 20 minutes or so because I didn't grab the slider control correctly. ARGH!&lt;br /&gt;&lt;br /&gt;This can be solved by making the page size to 1/50 of the total slider length. It's still not perfect, but that's the only workaround. But I'm definitely considering writing my own slider control. Now, where was that native widgets implementation I saw the other day on the web?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-2833475103397224126?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/2833475103397224126/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=2833475103397224126' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/2833475103397224126'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/2833475103397224126'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/12/first-donation-received-and-wxslider.html' title='First donation received, and wxSlider skipping problems.'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-6391502511564721259</id><published>2008-12-23T20:22:00.000-08:00</published><updated>2008-12-23T20:51:46.260-08:00</updated><title type='text'>A lot of advancements... behind the scenes.</title><content type='html'>Merry Christmas everyone!  I have good news, and not-so-good news.&lt;br /&gt;&lt;br /&gt;The good news is that a lot of work has been done on Saya. Especially the last 2 days, because I got sick and had to stay at home, so that gave me a lot of free time :P&lt;br /&gt;&lt;br /&gt;Here are some advancements that have been made:&lt;br /&gt;&lt;br /&gt;&lt;ol type="1"&gt;&lt;br /&gt;&lt;li&gt;Since I was asked to code Saya in QT4 (as opposed to wxWidgets), I've been working really hard on getting rid of wxWidgets dependencies. So that means I had to make a lot of wrappers, substitute classes, etc. These include but are not limited to:&lt;br /&gt;  &lt;ol type="a"&gt;&lt;br /&gt;  &lt;li&gt;A completely new, template-based, event handling system. Saya classes can now emit and receive their own events! Unfortunately there was no way to get around glib's (gtk) main_loop - but since even Qt made a wrapper around it, it's better to use what works. So I had to make a new wxWidgets event type to signal wxWidgets that a new Saya event has been queued. So far the only time I use an event is to signal the Main Frame that the currently-active project has changed.&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;A completely new syApp class: Saya is becoming more like a cross-platform toolkit (with more and more files in the core/ path) and less like an application, but that doesn't worry me. The point is that I managed to invoke the wxWidgets UI with a function from the plain old main() function. This also means that we could turn Saya into a non-graphical tool.&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;With the new syApp class (and its subclass wxSayaApp using wxWidgets), I no longer need the sayaEventHandler class, and I no longer need the main window to have its own functions for opening dialog boxes. All dialogs from now on are invoked by syApp. I even added a syFileSelector function. This also helped me remove some wxWidgets-specific includes.&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;The new syString class (a class encapsulating a const char*) does everything we need from wxString, including efficient concatenation, conversion from various numeric types, printf-like formatting, etc. And because I added some conditional includes, you can convert from/to wxString without having to call a function (the only exception is when a wxWidgets function needs a const wxChar*, you need to do the casting specifically: wxString(mystring).&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Along with the new syString class, serialization and de-serialization will become piece of cake when I get to implement it.&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;&lt;p&gt;The source code tree has been reorganized. Now we have the following directories:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;ui/ (all the code using wxWidgets, and our main application)&lt;br /&gt;&lt;br /&gt;saya/ (The directory for our video editing framework)&lt;br /&gt;&lt;br /&gt;saya/core (The directory for our generic cross-platform application framework)&lt;br /&gt;&lt;br /&gt;saya/timeline (The directory for our timeline-specific classes).&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;Some bugs in the ioCommon namespace (I really have to put my namespaces in order) have been fixed, like renaming / deleting a file.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Most classes have been moved to the private implementation parts, and this has helped me get rid of TONS of unnecessary includes. With these changes, we can recompile Saya (without -O2) from scratch in only 22 seconds.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Memory handling has been given special care: For temporary objects, now we use std::auto_ptr whenever possible.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;I've created the following classes: AVPlayer, InputMonitor, PreviewMonitor (well it's now coded yet, but it'll be a minor adaptation of InputMonitor). AVPlayer also inherits syEvtHandler, meaning it can catch events you send. I'm *very* close to actually being able to reproduce video thanks to this.&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;So that's the good news. The not-so-good news is that I haven't been able to get video playback to actually work... yet. It's a very steep curve, but I'm sure all my work hasn't been in vain. I promise that next year I'll actually have a workable media player for Saya.&lt;br /&gt;&lt;br /&gt;Merry Christmas, and happy new year!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-6391502511564721259?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/6391502511564721259/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=6391502511564721259' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/6391502511564721259'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/6391502511564721259'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/12/lot-of-advancements-behind-scenes.html' title='A lot of advancements... behind the scenes.'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-2356101099006868940</id><published>2008-12-19T16:54:00.001-08:00</published><updated>2008-12-19T17:01:33.682-08:00</updated><title type='text'>Building Saya with CMake... Coming soon!</title><content type='html'>Hello everyone. For some time i've been considering building Saya without requiring to install Code::Blocks and wxWidgets (which is a hassle for beta-testers - they just want to run a script and have it compile Saya so they can test it right away).&lt;br /&gt;&lt;br /&gt;Here's the  forum post which made me consider everything:&lt;br /&gt;&lt;a target="_blank" href="http://ubuntuforums.org/showthread.php?t=692692"&gt;http://ubuntuforums.org/showthread.php?t=692692&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;After giving a glimpse over various automation tools, two tools called my attention: SCons, and CMake.&lt;br /&gt;&lt;br /&gt;SCons is a tool supposedly cross-platform tool which I need to use at work. It uses python scripts. UGH, python! So, why did it call my attention? Because of its complexity and python requirements. In other words, it's a tool I would NOT like to use :)&lt;br /&gt;&lt;br /&gt;The alternative was CMake. We know CMake has support for Code::Blocks projects and workspaces (that's a plus!). But I was delighted when I realized that CMake is  the tool used to build KDE 4.&lt;br /&gt;&lt;a target="_blank" href="http://lwn.net/Articles/188693/"&gt;http://lwn.net/Articles/188693/&lt;/a&gt;&lt;br /&gt;Wow.&lt;br /&gt;&lt;br /&gt;The best part of using CMake is that the only thing you need is:&lt;br /&gt;a) Your compiler&lt;br /&gt;b) CMake&lt;br /&gt;&lt;br /&gt;Autotools and SCons, on the other hand, require you to install more scripting languages (i.e. perl, python) to make your file. This is REALLY what I like about CMake. It's lean.&lt;br /&gt;&lt;br /&gt;Next year I'll start to work on being able to compile Saya with CMake.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-2356101099006868940?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/2356101099006868940/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=2356101099006868940' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/2356101099006868940'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/2356101099006868940'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/12/building-saya-with-cmake-coming-soon.html' title='Building Saya with CMake... Coming soon!'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-4587032826034822216</id><published>2008-12-08T06:00:00.001-08:00</published><updated>2008-12-08T06:08:41.468-08:00</updated><title type='text'>Spammers starting to annoy me</title><content type='html'>There's an idiot who wants to promote his non-free video editing software on my blogs. This means I'll have to moderate all comments from now on. Which is a good thing, because now I'll find out who posts comments.&lt;br /&gt;&lt;br /&gt;Oh, just for your amusement, here's a copy of the e-mail I got from blogger:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;淑丽 has left a new comment on your post "Saya developers meeting #3 (2008-11-28): Summary o...":&lt;br /&gt;&lt;br /&gt;(VideoEditorSoft dot com - link de-httpified to prevent more spamming) provides free easy and popular Video Editor,&lt;br /&gt;Video Joiner,&lt;br /&gt;Video Splitter,&lt;br /&gt;Video Cutter,&lt;br /&gt;Video Clipper,&lt;br /&gt;Video Merger,&lt;br /&gt;DVD Video Editor,&lt;br /&gt;DVD Video Author.&lt;br /&gt;&lt;br /&gt;If you are looking for video Editor for Apple Mac OS X program, please refer to Mac Video Editor,&lt;br /&gt;Mac DVD Video Editor.&lt;br /&gt;&lt;br /&gt;Posted by 淑丽 to Saya Video Editor official Blog at December 7, 2008 9:49 PM &lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Just so you know, his profile id is available at http://www.blogger.com/profile/12311597430950642116 If he tries to post again, I'll notify blogger so they can kick him out. :)&lt;br /&gt;&lt;br /&gt;By the way, I really *DON'T* recommend downloading from his site, who knows if that thing's got a virus or something.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-4587032826034822216?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/4587032826034822216/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=4587032826034822216' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/4587032826034822216'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/4587032826034822216'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/12/spammers-starting-to-annoy-me.html' title='Spammers starting to annoy me'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-3356618958036866056</id><published>2008-12-07T07:04:00.000-08:00</published><updated>2008-12-07T07:15:35.282-08:00</updated><title type='text'>Got rid of some of the STL classes, reorganized stuff...</title><content type='html'>I was talking with the author of the uSTL about how to avoid STL code bloat, and I ended up asking him a question about strings. He told me that to concatenate strings I should use the ostringstream class for concatenations.&lt;br /&gt;&lt;br /&gt;So I began to replace the references to std::string in the timeline classes, and designed a new form to serialize them.&lt;br /&gt;&lt;br /&gt;I made a C++ wrapper for ostringstream so that I could later switch classes in case I needed to. Guess what, I did switch later. Because I also needed to design a std::string lightweight replacement (I've called it syString), I ended up adding methods to concatenate strings in an efficient way. I use the "size doubling" technique, up to a certain point, then the string only increases by amounts of 64K. I haven't tested this strategy well, but I may change the strategy in the future by adding a static parameter.&lt;br /&gt;&lt;br /&gt;I also reorganized the header files and cleaned up a lot of bloat. Some classes included the STL (I still need std::map and std::vector) for fixed types, so I moved the std inclusion to the CPP.&lt;br /&gt;&lt;br /&gt;I also fixed the precompiled headers inclusion, and removed a lot of unneeded wxWidgets includes from the GUI files.&lt;br /&gt;&lt;br /&gt;As a result of this optimization, I've cut compilation time by 33%, yay! :)&lt;br /&gt;&lt;br /&gt;Unfortunately, I stopped working on the playback engine, but I'll start. Playback functionality needs to be finished and tested ASAP.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-3356618958036866056?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/3356618958036866056/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=3356618958036866056' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/3356618958036866056'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/3356618958036866056'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/12/got-rid-of-some-of-stl-classes.html' title='Got rid of some of the STL classes, reorganized stuff...'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-8999711141737474158</id><published>2008-11-22T19:42:00.001-08:00</published><updated>2008-11-22T19:44:02.226-08:00</updated><title type='text'>Playback widgets status</title><content type='html'>The playback widgets have been uploaded to SVN, but they haven't been integrated into the project, as they need more work. But soon we'll be able to load and play a "dummy" video file. When playback is done, we'll move on to deal with the codec issues.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-8999711141737474158?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/8999711141737474158/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=8999711141737474158' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/8999711141737474158'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/8999711141737474158'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/11/playback-widgets-status.html' title='Playback widgets status'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-1150830614494878604</id><published>2008-11-16T18:46:00.001-08:00</published><updated>2008-11-16T18:51:34.903-08:00</updated><title type='text'>Slow but sure advances in the playback...</title><content type='html'>I've moved some of the private properties of classes VidProject and ProjectManager to the .cpp. This will allow me to skip recompiling some modules whenever add a private member to the classes.&lt;br /&gt;&lt;br /&gt;Also, I've managed to create my first instance of AVController (member of the hidden ProjectManagerData class). I hope to have the demo running on threads in the next few weeks.&lt;br /&gt;&lt;br /&gt;Also, Rigo is working on the playback controls using wxFormBuilder. Here's a sneak peek:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_iBNw06Dsj6g/SSDb9yfmAuI/AAAAAAAAADo/VyThNgEOP3U/s1600-h/AllInOnePlaybackControlWidgetGUI-Snapshotv2.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 200px; height: 145px;" src="http://4.bp.blogspot.com/_iBNw06Dsj6g/SSDb9yfmAuI/AAAAAAAAADo/VyThNgEOP3U/s200/AllInOnePlaybackControlWidgetGUI-Snapshotv2.png" alt="" id="BLOGGER_PHOTO_ID_5269453418596270818" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;When it's done, I'll add this control to the wxVideoPanel, and finally our editor will start to look like... a Video Editor :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-1150830614494878604?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/1150830614494878604/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=1150830614494878604' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/1150830614494878604'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/1150830614494878604'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/11/slow-but-sure-advances-in-playback.html' title='Slow but sure advances in the playback...'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_iBNw06Dsj6g/SSDb9yfmAuI/AAAAAAAAADo/VyThNgEOP3U/s72-c/AllInOnePlaybackControlWidgetGUI-Snapshotv2.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-549129332225313926</id><published>2008-11-14T13:54:00.001-08:00</published><updated>2008-11-14T13:55:07.504-08:00</updated><title type='text'>Playback widgets advancing...</title><content type='html'>Rigo, Jeff and me have been discussing the design and implementation of the widgets for playback control. Rigo's really pushing himself to work soon on it.&lt;br /&gt;&lt;br /&gt;I'll let you know when we have something working.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-549129332225313926?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/549129332225313926/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=549129332225313926' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/549129332225313926'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/549129332225313926'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/11/playback-widgets-advancing.html' title='Playback widgets advancing...'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-6769277333232068195</id><published>2008-11-14T13:45:00.000-08:00</published><updated>2008-11-14T13:53:08.496-08:00</updated><title type='text'>Finished the first "official" week in my new job!</title><content type='html'>Finally I've been given work to do other than reading manuals and documentation.&lt;br /&gt;&lt;br /&gt;I'm currently working for a web filtering company. They develop an all-in-one solution for filtering SPAM, viruses, porn, phishing sites etc.&lt;br /&gt;&lt;br /&gt;The good news:&lt;br /&gt;&lt;br /&gt;* The environment in here is very friendly. We're not forced to wear specific clothes, the time to eat is at the worker's discretion. It's very relaxing.&lt;br /&gt;&lt;br /&gt;* The methodologies followed are pretty neat: We have a wiki, we use Mantis issue tracker, have a subversion repo, there are coding guidelines, and some of the code have very interesting patterns. It's like my dream job! :D&lt;br /&gt;&lt;br /&gt;* Now that I've studied some of the code of the company's products, it's like every hacker's dream come true: TOTAL control over internet traffic, sending RST packets to block P2P traffic, (I won't discuss the morality of sending RST packets, that's up to the customers to apply them or not - but the appliances can be used at home, for companies intranets, etc -, man-in-the-middle eavesdropping for https transactions...&lt;br /&gt;&lt;br /&gt;Neo: Whoa.&lt;br /&gt;&lt;br /&gt;The bad news:&lt;br /&gt;&lt;br /&gt;* The schedule. You start working at 7AM :( This leaves me exhausted for the rest of the day, which unfortunately leaves me too tired to work on Saya. I really hope I can advance during the weekends.&lt;br /&gt;&lt;br /&gt;But I love it! And the pay's definitely worth it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-6769277333232068195?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/6769277333232068195/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=6769277333232068195' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/6769277333232068195'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/6769277333232068195'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/11/finished-first-official-week-in-my-new.html' title='Finished the first &quot;official&quot; week in my new job!'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-3476821679120459626</id><published>2008-11-04T18:47:00.000-08:00</published><updated>2008-11-04T18:50:24.588-08:00</updated><title type='text'>It's DLL time...</title><content type='html'>It's time to split the project into its components.&lt;br /&gt;&lt;br /&gt;Saya is originally meant to be a wxWidgets application running on top of two shared libraries: "libsaya", which handles all the editing, and "libsayacore" which does the very low-level multimedia stuff. libsaya depends on libsayacore, of course.&lt;br /&gt;&lt;br /&gt;For this I've had to do some wizardry and rename the vidproject/ directory into saya/, and move the iomgr/ directory into saya/core/ .&lt;br /&gt;&lt;br /&gt;Now, I really don't know how I'll do this shared libraries stuff, but I still can check the codeblocks source code :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-3476821679120459626?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/3476821679120459626/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=3476821679120459626' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/3476821679120459626'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/3476821679120459626'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/11/its-dll-time.html' title='It&apos;s DLL time...'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-3698893956360685345</id><published>2008-11-02T13:00:00.000-08:00</published><updated>2008-11-02T13:05:20.770-08:00</updated><title type='text'>First rule about the fight club...</title><content type='html'>you do not talk about the fight club.&lt;br /&gt;Second rule.. you DO NOT talk about the fight club.&lt;br /&gt;&lt;br /&gt;So, I joined the fight club. Actually it's more like a secret mailing list whose owners happen to be working on multimedia projects. Those might or might not include video editing. One of the current threads in the mailing list include comments and experiences about some open source multimedia toolkits, like MLT and gstreamer.&lt;br /&gt;&lt;br /&gt;Unfortunately I cannot give any more details of who the members are and what projects they're working on. But it's getting very interesting. Hopefully I will gain enough knowledge to perfect my own toolkit.&lt;br /&gt;&lt;br /&gt;I'll keep you posted.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-3698893956360685345?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/3698893956360685345/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=3698893956360685345' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/3698893956360685345'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/3698893956360685345'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/11/first-rule-about-fight-club.html' title='First rule about the fight club...'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-1462062981194756957</id><published>2008-10-22T21:54:00.000-07:00</published><updated>2008-10-22T21:58:26.450-07:00</updated><title type='text'>Back in the saddle again... kinda.</title><content type='html'>After nearly 3 weeks of not writing any code, I finished making some changes to VideoOutputDevice class. The class methods LoadVideoData and FlushVideoData are lock-free with respect to each other. This means that while I'm writing data into a bitmap, I can write the previous bitmap into the screen.&lt;br /&gt;&lt;br /&gt;In any case, tomorrow's my last day at my current job, and I really don't know how late i'll be returning from home. And this Friday I'll go visit my new job. I need to return early home because then we'll have the October meeting for the Saya devs.&lt;br /&gt;&lt;br /&gt;Let's hope my new job gives me enough time to work on the project. Wish me luck!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-1462062981194756957?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/1462062981194756957/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=1462062981194756957' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/1462062981194756957'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/1462062981194756957'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/10/back-in-saddle-again-kinda.html' title='Back in the saddle again... kinda.'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-4521511794483764005</id><published>2008-10-12T17:58:00.000-07:00</published><updated>2008-10-12T18:00:00.615-07:00</updated><title type='text'>Finished installing and customizing Mepis. Hurray!</title><content type='html'>I finished making the necessary modifications and software installations to my distro. You know what? I actually had to read the Saya-VE developers' guide for GNU/Linux :P. In any case, I already managed to compile and run Saya.&lt;br /&gt;&lt;br /&gt;Hurray! Now I can continue developing... on GNU/Linux. I won't be able to debug the Windows version until I install VirtualBox, tho.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-4521511794483764005?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/4521511794483764005/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=4521511794483764005' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/4521511794483764005'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/4521511794483764005'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/10/finished-installing-and-customizing.html' title='Finished installing and customizing Mepis. Hurray!'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-2233909705985655516</id><published>2008-10-10T19:17:00.000-07:00</published><updated>2008-10-10T19:48:25.826-07:00</updated><title type='text'>From PCLinuxOS to Mepis: Painful, but worth it!</title><content type='html'>If you've installed PCLinuxOS with an advanced partitioning, prepare for a painful surprise. SimplyMEPIS (up to 8.0 beta 2) doesn't let you install /usr, /var and /tmp into the partitions of your preference.&lt;br /&gt;&lt;br /&gt;Which means that once you've logged in, you need to enter the console (through ctrl-f1), mount the other partitions, delete their contents, cp -a /usr /your-usr-partition-mount-point, rename the other partition, edit fstab, etc. etc. etc.&lt;br /&gt;&lt;br /&gt;It's not something that you can do while in the LiveCD (I've tried to an extent and I failed miserably).&lt;br /&gt;&lt;br /&gt;Also, if you've used a non-standard file system such as XFS, just forget about it. You need to mkfs.ext3 the other partition (in this case, /tmp) and then proceed. Speaking about /tmp, an additional step is required: You need to delete /tmp, which is a symlink to /var/tmp.&lt;br /&gt;&lt;br /&gt;--&lt;br /&gt;&lt;br /&gt;But after I managed to do all that manual installation work so that I retain the structure of my partitions (which I carefully tuned), I'm actually enjoying it.&lt;br /&gt;&lt;br /&gt;For starters, you get nVidia support right out of the box. I booted the LiveCD in 1280x1024 with no problems whatsoever.&lt;br /&gt;&lt;br /&gt;The KDE provided with Mepis 8 is awesome. It's not KDE4, but 3.5.9, and that gives you stability. But this KDE is better configured than the one with PCLinuxOS 2007. I can pump the volume up and down with my multimedia keys. In PCLOS, I had to set up the mixer manually (not without the help of some friends on slashdot and irc) and add some lines in some obscure alsa config file.&lt;br /&gt;&lt;br /&gt;The kernel: PCLOS2007 ships with 2.6.19, and the latest upgrade is 2.6.22. Mepis 8 ships with 2.6.26, which also means support for tons of more wireless and external devices.&lt;br /&gt;&lt;br /&gt;Package management: The Synaptic package manager is also provided as default (yay!), but Mepis provides an excellent addition: The actual applet tells you how many upgrades are available. And finally, there's no "pay-for-upgrade" policy. The latest packages are already available for no additional price (like Firefox 3.0.3, which I just downloaded an hour ago), and the repositories are based on Debian, one of the most community-supported repos. Try to beat that, Tex!&lt;br /&gt;&lt;br /&gt;In short:&lt;br /&gt;&lt;br /&gt;If you're stuck in PClinuxOS and want to try a debian-based distro, the upgrade is painful (unless you happen to have installed in only one partition), and you need to delete your packages - for compatibility - anyway. But it's really worth the upgrade, provided you manage to install prettier themes. Personally, the default ones suck - but hey, it's a beta version. And no crashes! :)&lt;br /&gt;&lt;br /&gt;If you're undecided between PCLinuxOS and Mepis, go for Mepis. Nothing beats getting connected to the default Debian repos.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-2233909705985655516?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/2233909705985655516/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=2233909705985655516' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/2233909705985655516'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/2233909705985655516'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/10/from-pclinuxos-to-mepis-painful-but.html' title='From PCLinuxOS to Mepis: Painful, but worth it!'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-8381265652332528855</id><published>2008-10-09T21:35:00.000-07:00</published><updated>2008-10-09T22:20:40.373-07:00</updated><title type='text'>Mandriva, distro headaches... and Mepis 8.0 beta 2</title><content type='html'>Sigh. I only finished downloading the Mandriva 2008 ISO so I could burn it tonight and install it. I chose Mandriva because its configuration is the closest to PCLinuxOS.&lt;br /&gt;&lt;br /&gt;First bad news: I realized that I didn't download the most recent 2008.1, but the outdated 2008.0! ACK! 4 hours wasted.&lt;br /&gt;&lt;br /&gt;Second bad news: Mandriva 2009 is out, and yet, it has &lt;a href="http://wiki.mandriva.com/en/2009.0_Errata"&gt;lots of bugs&lt;/a&gt;. I'm not going to upgrade to a distro which freezes the GUI every now and then. What is this, Windows?. Also, I couldn't find the 2008.1 isos because the mandriva guys made them unavailable from the web. I had to use Google to find it. Now it's nearly 34% complete.&lt;br /&gt;&lt;br /&gt;Third bad news: 2008.1 also has some bugs, and it's definitely annoying that the guys don't have the time to release a 2008.2 with all the bugs fixed - and no new features. No, instead they chose to go for KDE 4, an unstable branch of the Linux kernel, and lots of bells and whistles. I don't want to cut my hand with a bleeding-edge distro. I want something that JUST WORKS!&lt;br /&gt;&lt;br /&gt;Therefore, I decided I'll use MEPIS.&lt;br /&gt;&lt;br /&gt;Why Mepis?&lt;br /&gt;&lt;br /&gt;1) It uses KDE! :D And the 3.5 branch! :D :D&lt;br /&gt;&lt;br /&gt;2) At first it used the Ubuntu repository, but now it switched to the latest Debian - can't be any more stable than that!&lt;br /&gt;&lt;br /&gt;3) It's a debian distro! Lots of packages are distributed as .debs.&lt;br /&gt;&lt;br /&gt;4) According to &lt;a href="http://forums.whirlpool.net.au/forum-replies-archive.cfm/388361.html"&gt;this Linux discussion&lt;/a&gt;, Mepis is even more stable than Mandriva. And &lt;a href="http://discuss.extremetech.com/forums/thread/1004403330.aspx"&gt;this other discussion&lt;/a&gt; gives me the impression that Mepis has surpassed Ubuntu.&lt;br /&gt;&lt;br /&gt;In fact, I would be going with Ubuntu (most popular distro these days), if not for &lt;a href="http://www.computerworld.com.au/index.php/id;885892575;pp;2;fp;2;fpid;4"&gt;their negligence towards KDE&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Ah, here's a &lt;a href="http://www.deviceguru.com/2008/09/29/mepis-linux-80-nears-release/"&gt;Mepis 8 review at deviceguru&lt;/a&gt;. Just what I was looking for. Hey, what do you know? The review's login screenshot says "Rick". Must be a sign ;-)&lt;br /&gt;&lt;br /&gt;For the impatient ones: &lt;a href="http://linuxtracker.org/index.php?page=torrent-details&amp;id=cb53466ff838388c1d9c656b5a3eec6517800372"&gt;MEPIS 8 beta 2 (32-bit) torrent&lt;/a&gt; - courtesy of linuxtracker.org&lt;br /&gt;&lt;br /&gt;I'm tired of waiting, I'll leave my computer on to finish the download.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-8381265652332528855?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/8381265652332528855/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=8381265652332528855' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/8381265652332528855'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/8381265652332528855'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/10/mandriva-distro-headaches-and-mepis-80.html' title='Mandriva, distro headaches... and Mepis 8.0 beta 2'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-6700253230603604127</id><published>2008-10-08T19:25:00.001-07:00</published><updated>2008-10-08T19:28:21.712-07:00</updated><title type='text'>Switching to Mandriva 2008.1</title><content type='html'>Tonight I'll make a bold step: I'll switch away from PCLinuxOS 2007, and move to Mandriva 2008.1 "one". The PCLinuxOS repositories are simply too small and too slow. Plus, Mandriva has the newest kernel.&lt;br /&gt;&lt;br /&gt;This will help me with a lot of things - for example, I can try out the latest version of Kdenlive (for research purposes and maybe for making 1 or 2 short AMVS ;-) ). I'll also be able to use the latest GIMP. I tried compiling it on PCLinuxOS, but I just can't figure out how to tell it to compile right.&lt;br /&gt;&lt;br /&gt;Anyway, I'll need to back up the important Saya stuff. *GASP* I need to back up my media, too! :( Ugh! Good thing I have a fresh 8GB Flash drive around.&lt;br /&gt;&lt;br /&gt;If things don't go well, this may stall Saya development for a couple of weeks. Wish me luck! :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-6700253230603604127?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/6700253230603604127/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=6700253230603604127' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/6700253230603604127'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/6700253230603604127'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/10/switching-to-mandriva-20081.html' title='Switching to Mandriva 2008.1'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-7782393537639505106</id><published>2008-10-08T19:21:00.001-07:00</published><updated>2008-10-08T19:24:55.533-07:00</updated><title type='text'>I decided I'll use PortAudio</title><content type='html'>After a little research (actually a web search and a chat), I decided I'll be going to use PortAudio for the audio output. That should complete the components required for Audio Output.&lt;br /&gt;&lt;br /&gt;Speaking of audio, I need to deal with using a different number of channels for the input and the output. With the help of Stefano D'Angelo, of naspro.atheme.org, I managed a way to specify to the audio buffers some parameters for conversion. But I doubt I'll have that ready soon - first I need to complete the playback functionality. Later I'll worry about channel conversion.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-7782393537639505106?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/7782393537639505106/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=7782393537639505106' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/7782393537639505106'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/7782393537639505106'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/10/i-decided-ill-use-portaudio.html' title='I decided I&apos;ll use PortAudio'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-5543891241628873243</id><published>2008-10-07T19:29:00.000-07:00</published><updated>2008-10-07T21:17:38.689-07:00</updated><title type='text'>Google Tech Talks on Youtube!</title><content type='html'>I hadn't known this, but it turns out that Google has been posting their tech talks for more than a year.&lt;br /&gt;&lt;br /&gt;Two particular talks got me interested: The first, is a presentation made nearly a year ago about the new features in the &lt;a href="http://en.wikipedia.org/wiki/C%2B%2B0x"&gt;upcoming C++0x standard&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=ZAG5txfYnW4"&gt;http://www.youtube.com/watch?v=ZAG5txfYnW4&lt;/a&gt; (Warning: 1 hour video!)&lt;br /&gt;&lt;br /&gt;The next talk concerns us more - it's a fast lock-free implementation of a hash table. Hash tables are used in all kinds of programs, but if many threads try to access a hash table, they need to have exclusive access. With a lock-free hash table, you don't need exclusive access to add or remove an item from the table. In fact, you don't even need exclusive access to read the table!&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=k5FltpgKcVk"&gt;http://www.youtube.com/watch?v=k5FltpgKcVk&lt;/a&gt; (warning: another one-hour video!). Here's the &lt;a href="http://www.azulsystems.com/events/javaone_2007/2007_LockFreeHash.pdf"&gt;lock-free hash table presentation in PDF format&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;The Java source code is available on Sourceforge: &lt;a href="https://sourceforge.net/projects/high-scale-lib/"&gt;https://sourceforge.net/projects/high-scale-lib/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Enjoy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-5543891241628873243?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/5543891241628873243/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=5543891241628873243' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/5543891241628873243'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/5543891241628873243'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/10/google-tech-talks-on-youtube.html' title='Google Tech Talks on Youtube!'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-6791925123475343911</id><published>2008-10-02T07:14:00.001-07:00</published><updated>2008-10-02T07:19:02.765-07:00</updated><title type='text'>Fixed first thread bugs... and improving :)</title><content type='html'>I'm fond to announce that the threads module NOW WORKS! :D&lt;br /&gt;&lt;br /&gt;The first test made by Rigo was pretty simple, and I've added a few things here and there. But I've managed to get the module to be more stable than the wxWidgets implementation!&lt;br /&gt;&lt;br /&gt;For example, I've added a function that allows you to know if a thread is detached or not. If the thread was deleting itself, under wxWidgets, you could crash the system. The new implementation simply adds the thread to a detached threads list. So we now keep a joinable list and a detached list.&lt;br /&gt;&lt;br /&gt;Also, when deleting a detached thread, we remove it from the list (with carefully-placed mutexes) so that you can't really double-delete a thread, even if you try.&lt;br /&gt;&lt;br /&gt;I've also fixed a couple of bugs in the pause/resume methods (a stupid bug, I had used a sentry object but the object was never created, I had just invoked the constructor with no object to construct, doh :P ).&lt;br /&gt;&lt;br /&gt;So this means I'll now be able to keep working on the playback base module.&lt;br /&gt;&lt;br /&gt;In the future I have planned to make the modules separate shared libraries.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-6791925123475343911?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/6791925123475343911/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=6791925123475343911' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/6791925123475343911'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/6791925123475343911'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/10/fixed-first-thread-bugs-and-improving.html' title='Fixed first thread bugs... and improving :)'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-5672519498358754069</id><published>2008-09-24T22:22:00.000-07:00</published><updated>2008-09-24T22:34:37.935-07:00</updated><title type='text'>Memory barriers and SSE2</title><content type='html'>After reading that lock-free code would be unstable on multiprocessor machines (dual cores, etc.), I studied that there was a way to prevent such things from happening: Memory barriers.&lt;br /&gt;&lt;br /&gt;A memory barrier makes sure that all the data you've written to memory effectively goes to the memory and doesn't stay in the CPU Cache.&lt;br /&gt;&lt;br /&gt;Unfortunately, according to a &lt;a href="http://gcc.gnu.org/ml/gcc-bugs/2008-07/msg01046.html"&gt;recently reported GCC bug&lt;/a&gt;, GCC's instruction for memory barriers, __sync_synchronize(), is flawed in x86-64 processors (Pentium Core Duo, AMD 64 x2, etc) because it doesn't implement the instruction "mfence".&lt;br /&gt;&lt;br /&gt;mfence is an SSE2 instruction (SSE2 is available for Pentium-4 and later processors) that implements an efficient memory barrier. There are other implementations to do a memory barrier on x86 processors, which I won't mention here for reasons of space. So I replaced the __sync_synchronize() primitive with qprof's AO_nop_full(), which invokes a memory barrier, using mfence if available. Also, I added this function to all the atomic primitives, and also to the syAudioBuffer class.&lt;br /&gt;&lt;br /&gt;Now I can be 100% sure that the code won't crash. At least for multiprocessor-caused race conditions, anyway. ;-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-5672519498358754069?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/5672519498358754069/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=5672519498358754069' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/5672519498358754069'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/5672519498358754069'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/09/memory-barriers-and-sse2.html' title='Memory barriers and SSE2'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-7567685867009023677</id><published>2008-09-23T18:14:00.000-07:00</published><updated>2008-09-23T19:49:50.795-07:00</updated><title type='text'>"mutable" keyword, and Major rewrite in the core...</title><content type='html'>After redesigning the syAudioBuffer and implementing some stuff in the AudioOutputDevice, I realized that my assumption to use only one thread for reading and writing led me to write some very defective code, so I almost have to rewrite the entire thing. Fortunately I have finished doing so with AudioOutputDevice. But VideoOutputDevice, VideoInputDevice and AudioInputDevice are yet to be rewritten. Sigh.&lt;br /&gt;&lt;br /&gt;Additionally, I do need to redeclare the majority of functions as const. Fortunately, now I can do so freely because I have discovered the &lt;span style="font-weight:bold;"&gt;mutable&lt;/span&gt; keyword!&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;mutable&lt;/span&gt; allows you to allow some variables in the object to change, even if the modification resides inside a const function, or if the object was passed as "const". This way I can declare the thread synchronization variables as "mutable" and still enjoy the compile-time protection of &lt;span style="font-weight:bold;"&gt;const&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update (Sep 23, 2008):&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Finally some good results from the rewrite! I discovered a bug in syBitmapCopier that instead of copying the source to the destination, it copied the destination to the source!! :-S Yikes.&lt;br /&gt;&lt;br /&gt;It's nice how all these knowledge tidbits contribute to improve a programmers' level as a whole.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-7567685867009023677?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/7567685867009023677/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=7567685867009023677' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/7567685867009023677'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/7567685867009023677'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/09/mutable-keyword-and-major-rewrite-in.html' title='&quot;mutable&quot; keyword, and Major rewrite in the core...'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-7579205383069957808</id><published>2008-09-17T19:45:00.000-07:00</published><updated>2008-09-17T20:51:44.913-07:00</updated><title type='text'>Happy 17th birthday, Linux!</title><content type='html'>&lt;img style="float:left;margin-right:1em; margin-bottom:1em;" src="http://3.bp.blogspot.com/_iBNw06Dsj6g/SNHCH_lA4PI/AAAAAAAAADQ/V_dQFkCuOh8/s400/tux.jpg" style="border-color:#fff" alt="" id="BLOGGER_PHOTO_ID_5247188483444891890" /&gt;&lt;br /&gt;&lt;br /&gt;Some hours ago, Linux became &lt;a href="http://alexandrubucur.com/2008-09-17/17-years-linux"&gt;17 years old!&lt;/a&gt; I have to mention that after studying the kernel code (because that's what Linux is, a kernel, NOT an Operating System!), I realized that calling the different distributions "Linux" is wrong.&lt;br /&gt;&lt;br /&gt;Probably you'll say "aw man, not that Stallman crap again". Nope. It's actually the opposite. I've been having some annoying problems with the Linux DISTRIBUTION (which includes the kernel, the GNU operating system files, KDE and some other stuff) I'm using right now. But saying "aw man, my Linux isn't working" is WRONG. It's not the Kernel's fault! It's the stupid distro's fault.&lt;br /&gt;&lt;br /&gt;Because as I have studied the multithread code, the posix mutexes implementation, and read about the Completely Fair scheduler, I realized:&lt;br /&gt;&lt;br /&gt;Man, this kernel is one of the most beautiful things created by men. For starters, it implements posix threads, which have a beautiful and simple API compared to... eeew... Windows - trust me, I've been using this thing. &lt;br /&gt;&lt;br /&gt;Another example of Linux' beauty is one of the recent patches for the scheduling code, which was merged in 2.6.25. It implements something called &lt;a href="http://lwn.net/Articles/267968/"&gt;ticket spinlocks&lt;/a&gt;. To explain, a spinlock is an item that can only be possessed by only one thread at the same time. And all threads keep competing for it, and they never give up until they get it. Not a nanosecond of rest. Imagine a discounts sale on a women's clothing shop. Yes, it gets that ugly :P. &lt;br /&gt;&lt;br /&gt;But the latest patch makes each thread take a "ticket" and wait for its turn. When I read that I was like... whoa.... you just blew my mind. I didn't even SUSPECT things like this could be implemented! Even after 17 years, Linux (yes, the Kernel) is getting more and more beautiful.&lt;br /&gt;&lt;br /&gt;Now, repeat after me:&lt;br /&gt;&lt;br /&gt;Linux. Is. Beautiful.&lt;br /&gt;&lt;br /&gt;So now on my to-do list is to replace all the "Linux" references in Saya's website for "GNU/Linux", to give the Kernel (represented by that cute little penguin we call Tux :) ) the place it deserves.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;HAPPY BIRTHDAY, LINUX!&lt;br /&gt;&lt;br /&gt;As a gift, here's a cute paper tux to decorate your desk. By the way, you can edit the image to replace that logo with your favorite distro's logo. Enjoy the party :)&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_iBNw06Dsj6g/SNHPwwGMJUI/AAAAAAAAADY/E5vRwfKvxzw/s1600-h/tux.gif"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_iBNw06Dsj6g/SNHPwwGMJUI/AAAAAAAAADY/E5vRwfKvxzw/s400/tux.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5247203477314872642" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-7579205383069957808?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/7579205383069957808/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=7579205383069957808' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/7579205383069957808'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/7579205383069957808'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/09/happy-17th-birthday-linux.html' title='Happy 17th birthday, Linux!'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_iBNw06Dsj6g/SNHCH_lA4PI/AAAAAAAAADQ/V_dQFkCuOh8/s72-c/tux.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-2991207368661007452</id><published>2008-09-15T21:50:00.001-07:00</published><updated>2008-10-02T08:39:40.056-07:00</updated><title type='text'>New AVController design: Four threads, audio frames.</title><content type='html'>After not visiting the Audio Video playback/sync module for a while (due to my work with the threads and the API cleanup in the timeline model),I finally decided to print the source code. Believe it or not, it allows you to concentrate better and see the code as a whole. So it was like 20 to 30 pages, stapled per file for a better organization.&lt;br /&gt;&lt;br /&gt;Anyway - I studied the code for avcontroller.cpp, and I saw a fatal flaw in the premilinary design: There was only ONE worker thread, and I need four!&lt;br /&gt;&lt;br /&gt;Why?&lt;br /&gt;&lt;br /&gt;The code does more or less this: It tells the VideoInputDevice to send data to the VideoOutputDevice, which tells VideoOutputDevice to load the data. The problem is that VideoOutputDevice also Renders the data after loading it, instead of invoking a separate thread or something.&lt;br /&gt;&lt;br /&gt;So there's a sequence to load the video:&lt;br /&gt;&lt;br /&gt;1) VideoInputDevice fetchs the video from a file or whatever. This implies a HEAVY OVERHEAD as it can imply either decoding, or compositing.&lt;br /&gt;&lt;br /&gt;2) When the data is available, VideoInputDevice sends the data to the VideoOutputDevice.&lt;br /&gt;&lt;br /&gt;3) After receiving the data, VideoOutputDevice sends the data to the display or encoder.&lt;br /&gt;&lt;br /&gt;Which means, that while the decoder processes the input, the encoder is blocked. While this can be fine for Video, where you can just play the same frame over and over, it's NOT fine for audio where the buffer can simply go blank.&lt;br /&gt;&lt;br /&gt;And then I realized an even WORSE problem: There is no separation between Video and Audio processing time! It's all done with ONE thread!! So while the Video is trying to decode / process the video effects, the audio can run out of data.&lt;br /&gt;&lt;br /&gt;To solve this problem, we will use FOUR threads: Video In, Audio In, Video Out, and Audio Out. If one operation is blocked, it won't affect the others. Of course, if the video or audio simply run out of data we'll have to stay silent. But at least the Audio Input won't affect Video Ouput or viceversa.&lt;br /&gt;&lt;br /&gt;Another problem is that using Mutexes can get things slow, specially for audio. I've been researching for a while about lock-free data transfer, and I remember one guy saying something about audio FRAMES.&lt;br /&gt;&lt;br /&gt;What? O.O *blink blink* Frames in audio? O.O *blink blink*&lt;br /&gt;&lt;br /&gt;That's right. By splitting the buffer into separate small frames of time (say, 1000 samples) we can use a fixed buffer of POINTERS to those frames.&lt;br /&gt;&lt;br /&gt;This means: Instead of having this:&lt;br /&gt;&lt;br /&gt;[..........................................................]&lt;br /&gt;&lt;br /&gt;we have this:&lt;br /&gt;&lt;br /&gt;A [.....]&lt;br /&gt;B [.....]&lt;br /&gt;C [.....]&lt;br /&gt;D [.....]&lt;br /&gt;E [.....]&lt;br /&gt;F [.....]&lt;br /&gt;G [.....]&lt;br /&gt;H [.....]&lt;br /&gt;I [.....]&lt;br /&gt;J [.....]&lt;br /&gt;&lt;br /&gt;[ABCDEFGHIJ]&lt;br /&gt;&lt;br /&gt;So a thread can reserve one of the N frames of audio for buffering, and instead of having to avoid touching a HUGE GODZILLA chunk of data, we can just meddle around with one of the little godsukis. And the list which tells which order they should be played, can be a lock-free list (this means it will have thread-safe algorithms which do not require mutexes or any of that.&lt;br /&gt;&lt;br /&gt;Finally, with the lessons learned during the thread module's development, I can finally delete that awful sleep-based synchronization and start using semaphores and/or condition variables. I think I'll go for condition variables, as I can wake up the thread either when I need to send data, or when I need to stop it.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Edit (Oct 2,2008):&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The actual redesign didn't use audio frames, after all. It was much simpler to use a circular buffer with one sample per slot.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-2991207368661007452?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/2991207368661007452/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=2991207368661007452' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/2991207368661007452'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/2991207368661007452'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/09/new-avcontroller-design-four-threads.html' title='New AVController design: Four threads, audio frames.'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-4518463641354941043</id><published>2008-09-14T00:35:00.000-07:00</published><updated>2008-09-15T21:49:39.062-07:00</updated><title type='text'>Forward declarations: Not good enough?</title><content type='html'>It's widely known by C++ programmers that replacing classes instantiations with class pointers in your classes, allows you to do a forward declaration in your headers and save compilation time.&lt;br /&gt;&lt;br /&gt;Example:&lt;br /&gt;&lt;br /&gt;Bad:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;a.h:&lt;br /&gt;&lt;br /&gt;class A {&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;b.h:&lt;br /&gt;&lt;br /&gt;#include "a.h"&lt;br /&gt;class B {&lt;br /&gt;  A myvar;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Good:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;a.h:&lt;br /&gt;&lt;br /&gt;class A {&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;b.h:&lt;br /&gt;&lt;br /&gt;class A;&lt;br /&gt;class B {&lt;br /&gt;  A* myvar;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Then, in the CPP you do the #include. But this is NOT enough! Since most of my classes are pretty brief, due to the fact that some are template instantiations, I have not only to include in each .cpp the headers for all the classes and ALL the classes contained in those classes ad infinitum. OK, If I followed the first approach I would only "include one file", but that's not the point, since that "one file" would start an include chain. So it doesn't matter what I do, in each .cpp I always end up invoking all the .h files and end up with a gigantic object file.&lt;br /&gt;&lt;br /&gt;Let's see what this little code does:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;#include "smap.h"&lt;br /&gt;#include "avclip.h"&lt;br /&gt;#include "avtransition.h"&lt;br /&gt;#include "aveffect.h"&lt;br /&gt;#include "aveffects.h"&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;AVClip::AVClip()&lt;br /&gt;{&lt;br /&gt;    //ctor&lt;br /&gt;    m_Effects = new AVEffects;&lt;br /&gt;    m_EndingTransition = new AVTransition;&lt;br /&gt;    m_Markers = new SMapUintUint;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;AVClip::~AVClip()&lt;br /&gt;{&lt;br /&gt;    //dtor&lt;br /&gt;    delete m_Markers;&lt;br /&gt;    delete m_EndingTransition;&lt;br /&gt;    delete m_Effects;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;why do I need to include all the headers JUST TO CREATE AN OBJECT? Because by doing "m_Effects = new AVEffects", I call AVEffects::AVEffects(), and for that I need the include file. Which also ends up invoking svector.h, which also includes serializable.h and &lt;vector&gt;. Eew!!&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Enter forward declarations in the .cpp files!&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;To solve this problem, I created a class named AVClasses, which encapsulates object creation, deletion, serialization AND deserialization for ALL THE KNOWN CLASSES.&lt;br /&gt;&lt;br /&gt;avclasses.h:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;#include &lt;string&gt;&lt;br /&gt;&lt;br /&gt;class AVSettings;&lt;br /&gt;class FXParameterList;&lt;br /&gt;class AVEffectParamDeclaration;&lt;br /&gt;class AVEffectParamDeclarations;&lt;br /&gt;// ...&lt;br /&gt;&lt;br /&gt;class AVClasses {&lt;br /&gt;    public:&lt;br /&gt;&lt;br /&gt;        static void Create(AVSettings* &amp;ptr);&lt;br /&gt;        static void Create(FXParameterList* &amp;ptr);&lt;br /&gt;        static void Create(AVEffectParamDeclaration* &amp;ptr);&lt;br /&gt;        static void Create(AVEffectParamDeclarations* &amp;ptr);&lt;br /&gt;        // ...&lt;br /&gt;&lt;br /&gt;        static void Delete(AVSettings* &amp;ptr);&lt;br /&gt;        static void Delete(FXParameterList* &amp;ptr);&lt;br /&gt;        static void Delete(AVEffectParamDeclaration* &amp;ptr);&lt;br /&gt;        static void Delete(AVEffectParamDeclarations* &amp;ptr);&lt;br /&gt;        // ...&lt;br /&gt;&lt;br /&gt;        static std::string serialize(AVSettings* &amp;ptr);&lt;br /&gt;        static std::string serialize(FXParameterList* &amp;ptr);&lt;br /&gt;        static std::string serialize(AVEffectParamDeclaration* &amp;ptr);&lt;br /&gt;        static std::string serialize(AVEffectParamDeclarations* &amp;ptr);&lt;br /&gt;        // ...&lt;br /&gt;&lt;br /&gt;        static bool unserialize(AVSettings* &amp;ptr, const std::string&amp; s);&lt;br /&gt;        static bool unserialize(FXParameterList* &amp;ptr, const std::string&amp; s);&lt;br /&gt;        static bool unserialize(AVEffectParamDeclaration* &amp;ptr, const std::string&amp; s);&lt;br /&gt;        static bool unserialize(AVEffectParamDeclarations* &amp;ptr, const std::string&amp; s);&lt;br /&gt;        // ...&lt;br /&gt;};&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;This little toy hides the object creation, destruction and (un)serialization. Of course, the avclasses.cpp file will include ALL THE HEADERS. It's fun!&lt;br /&gt;&lt;br /&gt;avclasses.cpp:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;#include "avclasses.h"&lt;br /&gt;&lt;br /&gt;#include "avsettings.h"&lt;br /&gt;#include "fxparameterlist.h"&lt;br /&gt;#include "aveffectparamdeclaration.h"&lt;br /&gt;#include "aveffectparamdeclarations.h"&lt;br /&gt;// ... etc.&lt;br /&gt;&lt;br /&gt;void AVClasses::Create(AVSettings* &amp;ptr) { ptr = new AVSettings; }&lt;br /&gt;void AVClasses::Create(FXParameterList* &amp;ptr) { ptr = new FXParameterList; }&lt;br /&gt;void AVClasses::Create(AVEffectParamDeclaration* &amp;ptr) { ptr = new AVEffectParamDeclaration; }&lt;br /&gt;void AVClasses::Create(AVEffectParamDeclarations* &amp;ptr) { ptr = new AVEffectParamDeclarations; }&lt;br /&gt;// ...&lt;br /&gt;&lt;br /&gt;void AVClasses::Delete(AVSettings* &amp;ptr) { delete ptr; ptr = NULL; }&lt;br /&gt;void AVClasses::Delete(FXParameterList* &amp;ptr) { delete ptr; ptr = NULL; }&lt;br /&gt;void AVClasses::Delete(AVEffectParamDeclaration* &amp;ptr) { delete ptr; ptr = NULL; }&lt;br /&gt;void AVClasses::Delete(AVEffectParamDeclarations* &amp;ptr) { delete ptr; ptr = NULL; }&lt;br /&gt;// ...&lt;br /&gt;&lt;br /&gt;std::string AVClasses::serialize(AVSettings* &amp;ptr) { return ptr-&gt;serialize(); }&lt;br /&gt;std::string AVClasses::serialize(FXParameterList* &amp;ptr) { return ptr-&gt;serialize(); }&lt;br /&gt;std::string AVClasses::serialize(AVEffectParamDeclaration* &amp;ptr) { return ptr-&gt;serialize(); }&lt;br /&gt;std::string AVClasses::serialize(AVEffectParamDeclarations* &amp;ptr) { return ptr-&gt;serialize(); }&lt;br /&gt;// ...&lt;br /&gt;&lt;br /&gt;bool AVClasses::unserialize(AVSettings* &amp;ptr, const std::string&amp; s) { return ptr-&gt;unserialize(s); }&lt;br /&gt;bool AVClasses::unserialize(FXParameterList* &amp;ptr, const std::string&amp; s) { return ptr-&gt;unserialize(s); }&lt;br /&gt;bool AVClasses::unserialize(AVEffectParamDeclaration* &amp;ptr, const std::string&amp; s) { return ptr-&gt;unserialize(s); }&lt;br /&gt;bool AVClasses::unserialize(AVEffectParamDeclarations* &amp;ptr, const std::string&amp; s) { return ptr-&gt;unserialize(s); }&lt;br /&gt;// ...&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;I took a look at the filesize of the avclasses.o. It measures 579K! Half a meg!&lt;br /&gt;&lt;br /&gt;But now let's see what happens if I use AVClasses inside the previous AVClip.h:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;#include "avclip.h"&lt;br /&gt;#include "avclasses.h"&lt;br /&gt;&lt;br /&gt;AVClip::AVClip()&lt;br /&gt;{&lt;br /&gt;    //ctor&lt;br /&gt;    AVClasses::Create(m_Effects);&lt;br /&gt;    AVClasses::Create(m_EndingTransition);&lt;br /&gt;    AVClasses::Create(m_Markers);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;AVClip::~AVClip()&lt;br /&gt;{&lt;br /&gt;    //dtor&lt;br /&gt;    AVClasses::Delete(m_Effects);&lt;br /&gt;    AVClasses::Delete(m_EndingTransition);&lt;br /&gt;    AVClasses::Delete(m_Markers);&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;And the results are the following:&lt;br /&gt;&lt;br /&gt;Before:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;avclip.o: 105356 bytes.&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;After:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;avclip.o:  33136 bytes.&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Needless to say, compilation is almost instant!&lt;br /&gt;&lt;br /&gt;Yes, there is a drawback to all this. That extra call when creating the objects. But if we look at the AVClasses code, it's more like a jumptable, except for the serialization stuff, which would duplicate all the memory transfers. But that can be solved by simply modifying the code to pass a string by parameter instead of returning a string.&lt;br /&gt;&lt;br /&gt;So we save a lot of duplicate code in the object files for a tiny runtime penalty. Is it worth it? WAY YES!!!&lt;br /&gt;&lt;br /&gt;When I finish changing all the code in my files I'll tell you how much the compilation time disminished.&lt;br /&gt;&lt;br /&gt;Update: After changing lots of files to se this approach, I noticed that the gain in compilation time is only marginal. I wonder if the change is really worth it.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update (Sept 15, 2008):&lt;/b&gt; I finally realized that this is nonsense, it's not worth it, and just stupid. Also, I also made another realization: The current STL-based model is optimal in complexity.  I may not like the STL bloat, but the fact is that it keeps programming SIMPLE. I don't need t ocomplicate myself with more pointers and implement lots of "exceptions-to-the-rule" routines.&lt;br /&gt;&lt;br /&gt;So I reverted my SVN copy to the one before these changes and kept going. However, it was a good experiment to make, and this way I won't have to worry with yet another "what if I had..." thought. Now move along.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-4518463641354941043?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/4518463641354941043/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=4518463641354941043' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/4518463641354941043'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/4518463641354941043'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/09/forward-declarations-not-good-enough.html' title='Forward declarations: Not good enough?'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-2066543882939856009</id><published>2008-09-11T07:02:00.001-07:00</published><updated>2008-09-11T07:06:04.432-07:00</updated><title type='text'>Threads module FINISHED! (for real this time)</title><content type='html'>After moving all the private data to the CPP, cleaning up the API (that means it's stable now, unless I add new functions) and fixing a few things, I'm glad to announce that the Threads module is Finished!&lt;br /&gt;&lt;br /&gt;It costed me many hours of sleep, many e-mail exchanges with linux kernel experts, but finally, it's done.&lt;br /&gt;&lt;br /&gt;Now, back to the playback framework.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-2066543882939856009?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/2066543882939856009/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=2066543882939856009' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/2066543882939856009'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/2066543882939856009'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/09/threads-module-finished_11.html' title='Threads module FINISHED! (for real this time)'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-780445345914164984</id><published>2008-09-10T14:39:00.001-07:00</published><updated>2008-09-10T19:32:55.107-07:00</updated><title type='text'>Con Kolivas answers: Yield() is bad. VERY bad.</title><content type='html'>Con Kolivas, the mind behind the new Linux scheduler, answered a simple question for me.&lt;br /&gt;&lt;br /&gt;It's the same Sleep() vs. Yield() issue that has been debated for ages, but this time we've already discarded sleep, so the question was more Yield() vs. wait.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Question: What should I use to put a thread to sleep for a limited time if there's no work to be done? A semaphore, or a yield?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;b&gt;Answer:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Yield just drops the cpu for other processes and threads to go first. It does not specify who should go next, how many processes should use cpu next, nor does it say when to return. Let's say you yield and one nanosecond later the work is available. On a loaded system it's theoretically possible to yield for up to 10 seconds. That's 9.99* seconds too long that you've yielded. Alternatively, if the thread yields for .5 seconds and the work is available&lt;br /&gt;at .6 seconds, the yielding thread comes back and there is no work available, that thread now wastes cpu uselessly, checking for work and just yielding again for however long.&lt;br /&gt;&lt;br /&gt;With semaphores, you rely on the work actually being available before waking up the thread. There is no wasted cpu at all, and the thread is signalled very fast that it should now wake up.&lt;br /&gt;&lt;br /&gt;It takes more effort to keep track of where you've put your semaphores, who's waiting on what and so on, but in the long run the results are potentially much better. How big the gain is depends on how parallelisable your workloads are. Nonetheless, wasting cpu doing nothing when there is a signal mechanism to only wake things when there's work available is much better.&lt;br /&gt;&lt;br /&gt;Con&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Thanks a lot, Con! Now onto rewriting that userspace mutex again... *sigh*&lt;br /&gt;&lt;br /&gt;--&lt;br /&gt;Update: I forgot to thank Joseph Seigh of &lt;a href="http://sourceforge.net/projects/atomic-ptr-plus/"&gt;atomic-ptr-plus&lt;/a&gt;, he was the one who suggested using a semaphore in the first place.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-780445345914164984?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/780445345914164984/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=780445345914164984' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/780445345914164984'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/780445345914164984'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/09/scheduling-answers-yield-is-bad.html' title='Con Kolivas answers: Yield() is bad. VERY bad.'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-7670076648398291799</id><published>2008-09-08T23:42:00.000-07:00</published><updated>2008-09-09T14:06:16.810-07:00</updated><title type='text'>Mutexes revisited; Scheduling questions.</title><content type='html'>I finally completed implementing the sySafeMutex class.&lt;br /&gt;&lt;br /&gt;My locking routine was something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;bool SafeMutex::Lock() {&lt;br /&gt;bool success = false;&lt;br /&gt;while(!success) {&lt;br /&gt; success = TryLock();&lt;br /&gt; if(success) { break; }&lt;br /&gt; if(aborter &amp;amp;&amp;amp; aborter-&gt;MustAbort()) return false;&lt;br /&gt; Sleep(1); // Sleep for one millisecond&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The problem is that if in that sleep time the other thread uses the mutex, then we fall in a problem called Resource starvation; The thread that begins to sleep never gets the mutex because other threads get the lock while the sleeping thread missed it. So instead of sleeping for a huge millisecond I only sleep for one scheduling cycle:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;bool SafeMutex::Lock() {&lt;br /&gt;bool success = false;&lt;br /&gt;while(!success) {&lt;br /&gt; success = TryLock();&lt;br /&gt; if(success) { break; }&lt;br /&gt; if(aborter &amp;amp;&amp;amp; aborter-&gt;MustAbort()) return false;&lt;br /&gt; Yield(); // Sleep as little as possible&lt;br /&gt;}&lt;br /&gt;}&lt;/pre&gt;But the problem of resource starvation still threatens us; So what can we do? I added a tight loop that tries to lock the mutex for the first 30 iterations. A tight loop when trying to lock a mutex is called a &lt;span style="font-weight: bold;"&gt;spinlock&lt;/span&gt;. Spinlocks are very CPU-inefficient (they consume too much CPU), but if they're combined with sleeping, they make things more balanced.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;bool SafeMutex::Lock() {&lt;br /&gt;bool success = false;&lt;br /&gt;unsigned i = 0;&lt;br /&gt;while(!success) {&lt;br /&gt; success = TryLock();&lt;br /&gt; if(success) { break; }&lt;br /&gt; if(aborter &amp;amp;&amp;amp; aborter-&gt;MustAbort()) return false;&lt;br /&gt; if(++i&gt;=30) {&lt;br /&gt;     i = 0; Yield();&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;}&lt;/pre&gt;Now I thought: Let's make the last thread that used the Mutex wait more the next time:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;bool SafeMutex::Lock() {&lt;br /&gt;bool success = false;&lt;br /&gt;unsigned i = 0;&lt;br /&gt;bool waspenalized = false;&lt;br /&gt;while(!success) {&lt;br /&gt; if(!waspenalized &amp;amp;&amp;amp; m_LastThread == GetCurrentThreadId()) {&lt;br /&gt;    Yield();&lt;br /&gt;    waspenalized = true;&lt;br /&gt; }&lt;br /&gt; success = TryLock();&lt;br /&gt; if(success) { m_LastThread = GetCurrentThreadId(); break; }&lt;br /&gt; if(aborter &amp;amp;&amp;amp; aborter-&gt;MustAbort()) return false;&lt;br /&gt; if(++i&gt;=30) {&lt;br /&gt;     i = 0; Yield();&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;}&lt;/pre&gt;By penalizing the last thread who got the mutex with an additional Yield(), we avoid the situation of one thread getting the lock all the time. Unfortunately, this adds an unnecessary yield() &lt;span style="font-weight: bold;"&gt;every single time we try to get the lock&lt;/span&gt;!&lt;br /&gt;&lt;br /&gt;After I studied more, it turns out that mutexes, semaphores and all those synchronization primitives rely much more on thread scheduling than on simple tricks. For example, a Semaphore puts the first waiting thread next on the line for execution - this goes way beyond simple user implementations. But for our purposes, I think the proposed implementation (without the yield) will suffice.&lt;br /&gt;&lt;br /&gt;Update: I finally figured it out. Instead of penalizing the last winning thread BEFORE trying to lock the mutex, penalize it AFTER trying to lock it. This way, the other threads will try to spinlock the mutex, while the last winning thread will be sleeping. Let's extend that to the TWO last winning threads, and this is what we get:&lt;br /&gt;&lt;br /&gt;&lt;div style="width:500px;overflow-x:scroll;font-family:Courier New,Monospace;font-size:12px;line-height:13px"&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;bool sySafeMutex::Lock(syAborter* aborter) {&lt;br /&gt;    bool result = false;&lt;br /&gt;    unsigned int i = 0;&lt;br /&gt;    unsigned long id = syThread::GetCurrentId();&lt;br /&gt;    for(;;) {&lt;br /&gt;        result = TryLock(aborter);&lt;br /&gt;        if(result) { break; }&lt;br /&gt;        if(aborter &amp;&amp; aborter-&gt;MustAbort()) { break; }&lt;br /&gt;        // Scheduling strategy:&lt;br /&gt;        // After the first try, the last owner loses its chance of winning;&lt;br /&gt;        // After the 5th try, the previous-to-last owner loses its chance of winning;&lt;br /&gt;        // After the 50th try, all threads get the same chance of winning.&lt;br /&gt;        if((i &gt;= 50) || (id==m_LastOwner) || (id==m_LastOwner2 &amp;&amp; i &gt;= 5)) {&lt;br /&gt;            syThread::Yield();&lt;br /&gt;        } else {&lt;br /&gt;            ++i;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    return result;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void sySafeMutex::Unlock() {&lt;br /&gt;    unsigned int id = syThread::GetCurrentId();&lt;br /&gt;    if(m_Owner == id) {&lt;br /&gt;        if(m_Recursive &amp;&amp; m_LockCount &gt; 1) {&lt;br /&gt;            --m_LockCount;&lt;br /&gt;        } else {&lt;br /&gt;            // Set m_LockCount to 0.&lt;br /&gt;            m_LockCount = 0;&lt;br /&gt;            m_LastOwner2 = m_LastOwner;&lt;br /&gt;            m_LastOwner = id;&lt;br /&gt;            m_Owner = 0xFFFFFFFF;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-7670076648398291799?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/7670076648398291799/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=7670076648398291799' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/7670076648398291799'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/7670076648398291799'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/09/mutexes-revisited-scheduling-questions.html' title='Mutexes revisited; Scheduling questions.'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-8883097944575704725</id><published>2008-09-08T05:39:00.000-07:00</published><updated>2008-09-08T05:57:11.382-07:00</updated><title type='text'>The RAII parttern; Sentry classes</title><content type='html'>I just found &lt;a href="http://www.hackcraft.net/raii/"&gt;an amazing article&lt;/a&gt; on a seemingly unknown pattern in programming: RAII ( Resource Acquisition Is Initialization).&lt;br /&gt;&lt;br /&gt;Basically, it is a class whose constructor initializes some resources, and whose destructor frees them. This prevents problems such as memory leaking or keeping a file locked when an exception occurs.&lt;br /&gt;&lt;br /&gt;The concept can be generalized into "Sentry Classes". These classes perform an action on construction, and on destruction they clean up.&lt;br /&gt;&lt;br /&gt;I had wondered what would happen in one of my classes if something had raised an exception (code has to be exception safe, did you know?). We already had prepared for locked mutexes on exceptions with the class wxMutexLocker (or in our case, syMutexLocker, sySafeMutexLocker, etc).&lt;br /&gt;&lt;br /&gt;But what about flags? In VideoOutputDevice, there's a flag called m_Playing that tells us whenever we're sending a frame to the output buffer. What happens when (not if) an exception occurs during that?&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;void VideoOutputDevice::LoadVideoData(syBitmap* bitmap) {&lt;br /&gt; bool result = true;&lt;br /&gt;&lt;br /&gt; {&lt;br /&gt;     syMutexLocker mylocker(*m_mutex);&lt;br /&gt;     if(m_playing || MustAbort()) {&lt;br /&gt;         result = false;&lt;br /&gt;     } else {&lt;br /&gt;         m_playing = true;&lt;br /&gt;     }&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; if(result) {&lt;br /&gt;     LoadDeviceVideoData(bitmap);&lt;br /&gt;    // EXCEPTION OCCURS! The code is aborted and&lt;br /&gt;    // m_playing is never set to false! The whole class&lt;br /&gt;    // is rendered useless.&lt;br /&gt;     m_playing = false;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Eeew. Looks ugly, isn't it? Well. Pay attention to the new, improved version using Sentry classes:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;void VideoOutputDevice::LoadVideoData(syBitmap* bitmap) {&lt;br /&gt; sySafeMutexLocker lock(*m_Busy, this);&lt;br /&gt; if(lock.IsLocked()) {&lt;br /&gt;     syBoolSetter setter(m_Playing, true);&lt;br /&gt;     LoadDeviceVideoData(bitmap);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;What? That's it? Yes!! The sySafeMutexLocker tries to lock the safe mutex m_Busy. If successful, we set the m_Playing flag to true, and then proceed to Load the Data from bitmap.&lt;br /&gt;&lt;br /&gt;Whether or not an exception occurs in LoadDeviceVideoData, the setter is destroyed, setting m_Playing to its old value (which is false), and on the function exit, the safe mutex m_Busy is unlocked.&lt;br /&gt;&lt;br /&gt;Here's the code for syBoolSetter:&lt;br /&gt;&lt;pre&gt;/** @brief Class that sets a flag to a specific value during its lifetime. */&lt;br /&gt;class syBoolSetter {&lt;br /&gt; public:&lt;br /&gt;     /** Constructor */&lt;br /&gt;     syBoolSetter(bool&amp;amp; flag,bool newvalue);&lt;br /&gt;&lt;br /&gt;     /** Destructor. Sets the flag to its original value. */&lt;br /&gt;     ~syBoolSetter();&lt;br /&gt; private:&lt;br /&gt;     bool&amp;amp; m_Flag;&lt;br /&gt;     bool m_Old;&lt;br /&gt;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;syBoolSetter::syBoolSetter(bool&amp;amp; flag,bool newvalue) :&lt;br /&gt;m_Flag(flag) {&lt;br /&gt; m_Old = m_Flag;&lt;br /&gt; m_Flag = newvalue;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;syBoolSetter::~syBoolSetter() {&lt;br /&gt; m_Flag = m_Old;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;Simple, effective and elegant.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-8883097944575704725?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/8883097944575704725/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=8883097944575704725' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/8883097944575704725'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/8883097944575704725'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/09/raii-parttern-sentry-classes.html' title='The RAII parttern; Sentry classes'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-5709514062070880273</id><published>2008-09-07T17:08:00.000-07:00</published><updated>2008-09-07T17:19:12.360-07:00</updated><title type='text'>New addition to threads module: Atomic Operations.</title><content type='html'>I realized that I could simplify a lot of code in the Saya Core by replacing some mutexes with atomic operations. I decided to encapsulate them in a class named syAtomic. This makes Saya now requiring not only GCC compatibility, but also a 486 or greater CPU (I added  -march=486 to the compiler flags). Given the fact that most CPU's right now are Pentiums (and you'd certainly need a Pentium for video editing :P ), i'm sure there will be no problem with this.&lt;br /&gt;&lt;br /&gt;Regarding the simplification, here's an example: the VideoInputDevice class has a flag called m_IsBusy, which it sets and unsets whenever it's doing an operation. I realized that for all intents and purposes, this was, in fact, a mutex (with an auxiliary mutex to lock access). I also realized that the only thing I did when waiting for m_IsBusy was to check if an abort signal was sent.&lt;br /&gt;&lt;br /&gt;So I made my own class sySafeMutex (now possible thanks to the atomic operations), which, when a thread tries to lock it, instead of just waiting for the mutex to be unlocked, it periodically checks if an abort signal is sent (an syAborter* parameter is sent to the Lock() function). Additionally, I added another flag to optionally run the check in a tight loop for the first 3 milliseconds.  This will avoid wasted CPU cycles if the only thing we want is to change a variable.&lt;br /&gt;&lt;br /&gt;I'll also make more simplifications to the code of the a/v device classes. Stay tuned.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-5709514062070880273?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/5709514062070880273/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=5709514062070880273' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/5709514062070880273'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/5709514062070880273'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/09/new-addition-to-threads-module-atomic.html' title='New addition to threads module: Atomic Operations.'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-6300618190258469349</id><published>2008-09-06T12:55:00.001-07:00</published><updated>2008-09-06T12:57:22.626-07:00</updated><title type='text'>Threads module finished!!</title><content type='html'>Whew. I thought I would never finish this behemot. It's still not tested and some things MIGHT not compile on Windows, but that can be fixed with a tiny bit of code revision.&lt;br /&gt;&lt;br /&gt;Later I'll decide whether to add support for atomic functions or not.&lt;br /&gt;If anyone's an expert in multithreading and OS design, please help me debug this thing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-6300618190258469349?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/6300618190258469349/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=6300618190258469349' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/6300618190258469349'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/6300618190258469349'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/09/threads-module-finished.html' title='Threads module finished!!'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-5518648547499926618</id><published>2008-09-06T00:10:00.000-07:00</published><updated>2008-09-06T00:13:54.612-07:00</updated><title type='text'>Decided to rely on GCC features.</title><content type='html'>At first I wanted the project to be compilable by any compiler, but I have decided to stick with GCC (which is cross-platform, anyway), for two reasons:&lt;br /&gt;&lt;br /&gt;1) GCC provides 64-bit integers for C++, which I need for the timeline.&lt;br /&gt;2) It provides atomic operations, which are  VERY useful for efficient multithreading programming.&lt;br /&gt;&lt;br /&gt;I won't say more, since it's kinda late and I need sleep. Good night.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-5518648547499926618?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/5518648547499926618/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=5518648547499926618' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/5518648547499926618'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/5518648547499926618'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/09/decided-to-rely-on-gcc-features.html' title='Decided to rely on GCC features.'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-7773589782609660456</id><published>2008-09-03T23:03:00.001-07:00</published><updated>2008-09-03T23:12:16.678-07:00</updated><title type='text'>Lock-free algorithms part 2: CAS</title><content type='html'>Hello again. I'll finish this lock-free programming with three links:&lt;br /&gt;&lt;br /&gt;The first link is the Compare-and-swap atomic operation. It's atomic because most processors already have an instruction for it. Nothing can be more atomic than one cpu-instruction :)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Compare-and-swap"&gt;http://en.wikipedia.org/wiki/Compare-and-swap&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;In &lt;a href="http://en.wikipedia.org/wiki/Computer_science" title="Computer science"&gt;computer science&lt;/a&gt;, the &lt;b&gt;compare-and-swap&lt;/b&gt; &lt;a href="http://en.wikipedia.org/wiki/Central_processing_unit" title="Central processing unit"&gt;CPU&lt;/a&gt; instruction ("&lt;b&gt;CAS&lt;/b&gt;") (or the Compare &amp;amp; Exchange - CMPXCHG instruction in the &lt;a href="http://en.wikipedia.org/wiki/X86" title="X86" class="mw-redirect"&gt;x86&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Itanium" title="Itanium"&gt;Itanium&lt;/a&gt; architectures) is a special instruction that &lt;a href="http://en.wikipedia.org/wiki/Atomic_%28computer_science%29" title="Atomic (computer science)" class="mw-redirect"&gt;atomically&lt;/a&gt; compares the contents of a memory location to a given value and, if they are the same, modifies the contents of that memory location to a given new value. The result of the operation must indicate whether it performed the substitution; this can be done either with a simple &lt;a href="http://en.wikipedia.org/wiki/Boolean" title="Boolean"&gt;boolean&lt;/a&gt; response (this variant is often called compare-and-set), or by returning the value read from the memory location (&lt;i&gt;not&lt;/i&gt; the value written to it).&lt;/p&gt; &lt;p&gt;CAS is used to implement &lt;a href="http://en.wikipedia.org/wiki/Synchronization_%28computer_science%29#Process_synchronization" title="Synchronization (computer science)"&gt;synchronization primitives&lt;/a&gt; like &lt;a href="http://en.wikipedia.org/wiki/Semaphore_%28programming%29" title="Semaphore (programming)"&gt;semaphores&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Mutex" title="Mutex" class="mw-redirect"&gt;mutexes&lt;/a&gt;, as well as more sophisticated &lt;a href="http://en.wikipedia.org/wiki/Lock-free_and_wait-free_algorithms" title="Lock-free and wait-free algorithms"&gt;lock-free and wait-free algorithms&lt;/a&gt;. &lt;a href="http://en.wikipedia.org/wiki/Maurice_Herlihy" title="Maurice Herlihy"&gt;Maurice Herlihy&lt;/a&gt; (1991) proved that CAS can implement more of these algorithms than &lt;a href="http://en.wikipedia.org/wiki/Atomic_operation" title="Atomic operation"&gt;atomic&lt;/a&gt; read, write, and &lt;a href="http://en.wikipedia.org/wiki/Fetch-and-add" title="Fetch-and-add"&gt;fetch-and-add&lt;/a&gt;, and that, assuming a fairly large amount of memory, it can implement all of them &lt;sup id="cite_ref-0" class="reference"&gt;&lt;a href="http://en.wikipedia.org/wiki/Compare-and-swap#cite_note-0" title=""&gt;[1]&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;The second link is an article from Dr. Dobb's journal implementing a the aforementioned Hazard Pointers.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.ddj.com/cpp/184401890"&gt;http://www.ddj.com/cpp/184401890&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And finally, an algorithm from AT&amp;amp;T research to implement STL-compatible (well, more or less) vectors using Hazard Pointers:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.research.att.com/%7Ebs/lock-free-vector.pdf"&gt;http://www.research.att.com/~bs/lock-free-vector.pdf&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Enjoy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-7773589782609660456?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/7773589782609660456/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=7773589782609660456' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/7773589782609660456'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/7773589782609660456'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/09/lock-free-algorithms-part-2-cas.html' title='Lock-free algorithms part 2: CAS'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2832016242820899544.post-4919214166826792318</id><published>2008-09-03T20:45:00.000-07:00</published><updated>2008-09-03T21:24:13.707-07:00</updated><title type='text'>Lock-free algorithms and hazard pointers</title><content type='html'>And here I thought mutexes, critical sections, conditions and semaphores were all that would have to be learned about multithreaded programming. Turns out I was wrong.&lt;br /&gt;&lt;br /&gt;It all began with a guy on irc.freenode.net (his nick was dshs) asking how to do inter-thread synchronization for a multimedia project (I invited him to join the team, but he politely declined). He said something about "lock free queues". So I wikipediaed it and here's what I read:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;In contrast to algorithms that protect access to shared data with locks, &lt;b&gt;lock-free and wait-free algorithms&lt;/b&gt; are specially designed to allow multiple threads to read and write shared data concurrently without corrupting it. "Lock-free" refers to the fact that a thread cannot lock up: every step it takes brings progress to the system. This means that no synchronization primitives such as &lt;a href="http://en.wikipedia.org/wiki/Mutual_exclusion" title="Mutual exclusion"&gt;mutexes&lt;/a&gt; or &lt;a href="http://en.wikipedia.org/wiki/Semaphore_%28programming%29" title="Semaphore (programming)"&gt;semaphores&lt;/a&gt; can be involved, as a lock-holding thread can prevent global progress if it is switched out. "Wait-free" refers to the fact that a thread can complete any operation in a finite number of steps, regardless of the actions of other threads. All wait-free algorithms are lock-free, but the reverse is not necessarily true. An intuitive way of understanding the difference between wait- and lock-free algorithms is that a thread executing an operation of a lock-free algorithm may not be impeded if another thread's execution is prematurely halted, whereas if the algorithm was wait-free, the first thread may not be impeded even if the second thread is aggressively interfering with the shared state. &lt;p&gt;Lock-free algorithms are one kind of &lt;a href="http://en.wikipedia.org/wiki/Non-blocking_synchronization" title="Non-blocking synchronization"&gt;non-blocking synchronization&lt;/a&gt;.&lt;/p&gt;&lt;/blockquote&gt;As I kept reading, I learned that algorithms for lock-free stacks, queues and even vectors are already out there. It means that you can read and write all the stuff you want in a multithreaded environment, without having to use a single semaphore, mutex or condition. Wow.&lt;br /&gt;&lt;br /&gt;And that wasn't all. I just learned that a NEW algorithm called "&lt;a href="http://en.wikipedia.org/wiki/Hazard_pointer"&gt;Hazard pointers&lt;/a&gt;" was created for non-blocking synchronization,  in 2004.&lt;br /&gt;&lt;br /&gt;So here's the description of a Hazard Pointer, right from Wikipedia:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;In a &lt;a href="http://en.wikipedia.org/wiki/Thread_%28computer_science%29" title="Thread (computer science)"&gt;multithreaded&lt;/a&gt; &lt;a href="http://en.wikipedia.org/wiki/Computer_science" title="Computer science"&gt;computing&lt;/a&gt; environment, a &lt;b&gt;hazard pointer&lt;/b&gt; is an element used by a &lt;a href="http://en.wikipedia.org/wiki/Methodology" title="Methodology"&gt;methodology&lt;/a&gt; that allows the memory allocated to the &lt;a href="http://en.wikipedia.org/wiki/Node_%28computer_science%29" title="Node (computer science)"&gt;nodes&lt;/a&gt; of &lt;a href="http://en.wikipedia.org/wiki/Lock_%28computer_science%29" title="Lock (computer science)"&gt;lock-free&lt;/a&gt; dynamic shared &lt;a href="http://en.wikipedia.org/wiki/Object_%28computer_science%29" title="Object (computer science)"&gt;objects&lt;/a&gt; to be reclaimed. Using the methodology, each &lt;a href="http://en.wikipedia.org/wiki/Thread_%28computer_science%29" title="Thread (computer science)"&gt;thread&lt;/a&gt; keeps a &lt;a href="http://en.wikipedia.org/wiki/List_%28computing%29" title="List (computing)"&gt;list&lt;/a&gt; of hazard pointers indicating which nodes the thread may later access. This list can only be written to by the particular thread but can be read by any thread. When a thread wishes to remove a node, it places it on a private list and periodically scans the lists of all other threads for pointers referencing that node. If no such pointers are found the memory occupied by the node can be safely freed.&lt;/blockquote&gt;&lt;br /&gt;This was JUST four years ago! It's a revolution that could be comparable to fast genetic sequencing, and I'm only learning about it right now! Where have I been these years? Oh, right. Working.&lt;br /&gt;&lt;br /&gt;If you want to know more about Hazard pointers, you can read the &lt;a href="http://www.research.ibm.com/people/m/michael/ieeetpds-2004.pdf"&gt;Hazard Pointers Full Article (PDF)&lt;/a&gt;, courtesy of IBM Research.&lt;br /&gt;&lt;br /&gt;I don't know if this will be of use later for Saya, where we'll have to quickly deal with low-latency stuff. Probably I may need it for later.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2832016242820899544-4919214166826792318?l=saya-dev.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://saya-dev.blogspot.com/feeds/4919214166826792318/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2832016242820899544&amp;postID=4919214166826792318' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/4919214166826792318'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2832016242820899544/posts/default/4919214166826792318'/><link rel='alternate' type='text/html' href='http://saya-dev.blogspot.com/2008/09/lock-free-algorithms-and-hazard.html' title='Lock-free algorithms and hazard pointers'/><author><name>Rick</name><uri>http://www.blogger.com/profile/16922162914881396629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='http://2.bp.blogspot.com/_iBNw06Dsj6g/SkbHG9HqP9I/AAAAAAAAAFo/aZNu9Zyh2iA/S220/gon.jpg'/></author><thr:total>0</thr:total></entry></feed>
