Mar 9, 2010 0
IntelliJ Idea9 ActionScript 3/Flex Workflow Part 1 – InsideRIA
Switching to IntelliJ Idea9 for Flex and Flash development looks quite attractive
Mar 9, 2010 0
Switching to IntelliJ Idea9 for Flex and Flash development looks quite attractive
Mar 9, 2010 0
Switching to IntelliJ Idea9 for Flex and Flash development looks quite attractive
Feb 18, 2010 0
“Each convergence of energy and communications technology changed our consciousness, extended our social networks and in turn expanded our empathy.” – Jeremy Rifkin
Nov 23, 2009 0
Grant Skinner's classic article on Flash 9 GC
Nov 23, 2009 0
Grant Skinner's classic article on Flash 9 GC
Nov 23, 2009 0
Detailed explanation of the Elastic Racetrack
Nov 23, 2009 0
Detailed explanation of the Elastic Racetrack
Nov 23, 2009 0
The annual update of Flash Player Internals
Nov 23, 2009 0
The annual update of Flash Player Internals
Oct 24, 2009 0
Almost year and a half ago I’ve wrote an article about making a pretty custom scroll-bar with a Fixed Sized Scroll-Thumb – a task known in the community as a designer scroll-bar. Both blog posts proved to be useful, but just recently I received an email from this very cool guy Dino from Canada with the following question.
Dino wrote:
I was also wondering how would I go about adding easing to the scrolling of a VBox? I don’t think there is an out-of-box solution such as an Accordion having a style property openEasingFunction that allows you to specify easing but I could be wrong. Does this require customization of the Container class? I was looking at Container.scrollChildren() and other methods in the Container class to determine if I could override any behaviour.
Somehow his email coincided with a scroll-related task I had recently. I had to use a scroll-bar which is situated on a pretty custom position and it was strolling columns of content with a snapping effect. So, how would I approach the problem with the animated scroll-bar?
Going for extending the Container or some of the others Flex containers is a hairy and let’s say adventurous direction to proceed with. And I believe the solution won’t be much flexible. What would you do if you need to place the scroll-bar on a more peculiar place (e.g. on the left or the top side of the container sizes or event somewhere else outside the scrolled container)?
The solution is to detach the scroll-bar from the container, so we can use an outside scroll-bar. The following code fragment shows you how to achieve this:
<!-- 1. Place the View that needs scrolling into a Canvas which represents the visible area which can't be exceeded by the View. !!!IMPORTANT!!! Disable the scrolling of the Canvas, so we can use a detached scroller, which we can place wherever we want (e.g. on the left or top sides of the Canvas) -->
<mx:Canvas id="viewContainer" width="{largerView.width}" height="500" verticalScrollPolicy="off" horizontalScrollPolicy="off" borderColor="black" borderStyle="solid"> <view:ViewThatNeedsScroll id="largerView"/> <!-- THIS IS THE VIEW -->
</mx:Canvas> <!-- 2. Create a Canvas with fictive content - this is the actual detatched scroll-bar. Make sure the dimensions of this Canvas are corresponding to the size of the visible area specified by the View-container. Also make sure the fictive content has dimensions corresponding to the the dimensions of the View. Use data binding to set the corresponding dimensions! -->
<mx:Canvas id="scrollerContainer" x="{viewContainer.x - scrollerContainer.width}" y="{viewContainer.y}" width="40" height="{viewContainer.height}"> <mx:Canvas width="1" height="{largerView.height}"/> <!-- THIS IS FAKE CONTENT -->
</mx:Canvas>
Before trying to add a tween and an easing to the scrolling motion, I’ll show you the most simplest solution for attaching this outer scroll-bar to the View that needs to be scrolled:
<!-- 3. Use Data Binding to attach the scroller to the View: --> <mx:Binding source="scrollerContainer.verticalScrollPosition" destination="viewContainer.verticalScrollPosition"/>
Here’s the working sample (view source is enabled):
I’ve implemented a simple controller component which animates the scrolling movement. You can adjust various properties of the ScrollerController, such as:
● interaction delay
● easing function
● max duration of the tween
● etc.
I’m not going to look at the controller’s implementation in details. Feel free to ask me any questions in the comments section.
Here’s the working sample (view source is enabled):
Tell me what do you think of my solution? How would you solve this problem?
Aug 10, 2009 0
Tutorial that covers exactly the environment I would like to see how is used.
Aug 10, 2009 0
Tutorial that covers exactly the environment I would like to see how is used.
Jul 31, 2009 0
Smoothing in Flash won’t work with every image. This is a bit of an old discovery, but yesterday I ran again into this issue and I had the luck to recall what was the reason for it, and decided to document it in my blog in case I run again into this issue.
Almost two years ago my colleague Barni and I literally spent half a day in finding what causes this behavior. We’ve tried everything – drawing the loaded bitmap into a new BitmapData-object with the smoothing argument set to true, but with no luck. And then it suddenly struck us – it was the image dimensions. Images that have an odd dimension(s) fail to be smoothed. Check the sample app beneath – choose a different image from the combo and observe whether the smoothing works for it:
The solution is to create a new BitmapData-object that is always with even dimensions.
var smoothBitmapData : BitmapData = new BitmapData( loadedBitmap.width + (loadedBitmap.width % 2), loadedBitmap.height + (loadedBitmap.height % 2), true, 0x00FF0000); smoothBitmapData.draw( loadedBitmap, null, null, null, null, true); smoothBitmap = new Bitmap( smoothBitmapData, PixelSnapping.NEVER, true);This is how it looks with the fix:
Jul 15, 2009 0
DOWNLOAD THE CODE (WRITTEN IN PERL)
Well, that’s an oldie! During the Cryptography course in the university (4 years and a half ago) I had an assignment to decipher a simple substitution cipher. Deciphering such ciphers is really straight-forward, but the extravagant part of me decided, that I’m too special to go with the straight way, so I’ve decided to try an alternative approach. Inspired from the Soft Computing course I attended the previous term, I was determined to experiment with a genetic algorithm and to play God with the small world of 20 populations with 20 individuals each possessing a unique DNA.
Well, does the evolution work or what? No matter how many times I’ve ran the evolution, it ended producing individuals which doesn’t look much like English – I had no luck with an exact match. Nevertheless the individuals bred by the process helped me a lot to recognize the English sentence that was in the cipher.
My implementation is in Perl – this language seemed most suitable for the task.
This is a slightly modified implementation of the genetics algorithm, described in “Solving Substitution Ciphers with Genetics Algorithm” by Joe Gester. A corpus of English text should be supplied – in this sample I pasted in the corpus.txt file “The Secret Garden” by G.K. Chesterton.
#########################################################################
# Solving Substitution Ciphers with Genetics Algorithm! #
# (c) Vladimir Tsvetkov, 2005 #
# For selfsatisfaction only! #
######################################################################### #!/usr/bin/perl use warnings;
use strict; ###############################################################################
# cypher text that is about to be cracked:
my $cypher_text = "BTKIB" . "OKIBR" . "BAARJ" . "ZGBON" . "QBBSH" . "OZIBM" . "BAAGB" . "ONZAH" . "RANMH" . "OZIBI" . "JQSAB" . "WKNHM" . "KTLBJ" . "ZZIBR" . "BWKQH" . "RWKHA" . "HHPJU" . "HVKIB" . "OJWQK" . "HRHWQ" . "BORIJ" . "KRJZX" . "HTWXK" . "HIJSS" . "BWWBC" . "K"; ###############################################################################
# almost randomly chosen corpus in English:
# use this to calculate the digram and trigram frequency tables:
my $corpus = ""; ###############################################################################
# capitalize all letters in the corpus, remove spaces, numbers and punctuation:
sub prepare_corpus { open (CORPUSFILE, '<', "corpus.txt") or die "Can't open file! $!"; my @contents = ; close (CORPUSFILE); foreach my $paragraph (@contents) { $corpus .= $paragraph; } $corpus =~ tr/a-z/A-Z/; # capitalize $corpus =~ s/\s//g; # remove spaces $corpus =~ s/\W//g; # remove punctuation and other symbols $corpus =~ s/\d//g; # remove digits
} prepare_corpus (); ###############################################################################
# alphabeth we use:
my $alphabeth = “ABCDEFGHIJKLMNOPQRSTUVWXYZ”; ###############################################################################
# letters distribution for the alphabeth we use (in %):
# if you are using another alphabet, you should change this table!
my %letter_distribution_table = ( ‘E’ => 12.31, ‘L’ => 4.03, ‘B’ => 1.62, ‘T’ => 9.59, ‘D’ => 3.65, ‘G’ => 1.61, ‘A’ => 8.05, ‘C’ => 3.20, ‘V’ => 0.93, ‘O’ => 7.94, ‘U’ => 3.10, ‘K’ => 0.52, ‘N’ => 7.19, ‘P’ => 2.29, ‘Q’ => 0.20, ‘I’ => 7.18, ‘F’ => 2.28, ‘X’ => 0.20, ‘S’ => 6.59, ‘M’ => 2.25, ‘J’ => 0.10, ‘R’ => 6.03, ‘W’ => 2.03, ‘Z’ => 0.09, ‘H’ => 5.14, ‘Y’ => 1.88
); ###############################################################################
# digram frequency table:
my %digram_frequency_table = (); # this will populate the %digram_frequency_table:
sub calculate_digram_frequency_table { my $i = 1; foreach my $letter (split (//, $corpus)) { last if ($i == length $corpus); my $digram = $letter . substr ($corpus, $i, 1); $i ++; if (defined $digram_frequency_table{$digram}) { $digram_frequency_table{$digram} ++; } else { $digram_frequency_table{$digram} = 1; } }
} calculate_digram_frequency_table (); ###############################################################################
# trigram frequency table:
my %trigram_frequency_table = (); # this will populate the %trigram_frequency_table:
sub calculate_trigram_frequency_table { my $i = 1; foreach my $letter (split (//, $corpus)) { last if ($i == (length $corpus) - 1); my $trigram = $letter . substr ($corpus, $i, 2); $i ++; if (defined $trigram_frequency_table{$trigram}) { $trigram_frequency_table{$trigram} ++; } else { $trigram_frequency_table{$trigram} = 1; } }
} calculate_trigram_frequency_table (); ###############################################################################
# implementing the crossover between individuals:
# as long as less than half of the key is swapped at any one time, at least
# the good information from one parent remains in the child and likely the
# majority of the good information from the other parent also remains
# Example:
# father - A (B C D) E F
# mother - B D F E C A
# the crossover takes the next 3 steps:
# 1. tr/BD/DB/
# 2. tr/CF/FC/
# 3. tr/DE/ED/
# child - E B C D F A
sub crossover { my ($father, $mother) = @_; my $letters_count = length $alphabeth; my $crossover_fragment_length = 12; my $fragment_offset = int (rand ($letters_count - $crossover_fragment_length + 1)); my $child = $mother; my $father_fragment = substr ($father, $fragment_offset, $crossover_fragment_length); my $mother_fragment = substr ($mother, $fragment_offset, $crossover_fragment_length); # swap the randomly chosen fragments: my $i = 0; foreach my $father_letter (split (//, $father_fragment)) { my $mother_letter = substr ($mother_fragment, $i, 1); $i ++; my $digram_left = $father_letter . $mother_letter; my $digram_right = $mother_letter . $father_letter; $_ = $child; eval “tr/$digram_left/$digram_right/”; $child = $_; } return $child;
} ###############################################################################
# implementing the fitness function for a given individual:
# To apply the fitness function to an individual, the cipher-text is decrypted
# using the individual’s gene as it’s key. Then every trigram and digram in
# the decrypted text is looked up in the table of how many times it occurs
# in the corpus. These numbers are then summed. Thus, trigrams and bigrams
# that occur commonly in the corpus are more heavily rewarded than those
# that do not.
sub fitness { my ($individual) = @_; my $permutated_alphabeth = $individual; my $plain_text = $cypher_text; # decrypt, using the given individual: $_ = $plain_text; eval “tr/$permutated_alphabeth/$alphabeth/”; $plain_text = $_; # calculate the fitness function of the decrypted text: my $fitness = 0; my $i = 1; foreach my $letter (split (//, $plain_text)) { unless ($i == length $plain_text) { my $next_letter = substr ($plain_text, $i, 1); my $digram = $letter . $next_letter; $fitness += $digram_frequency_table{$digram} if (defined $digram_frequency_table{$digram}); unless ($i == (length $corpus) - 1) { my $next_two_letters = substr ($plain_text, $i, 2); my $trigram = $letter . $next_two_letters; $fitness += $trigram_frequency_table{$trigram} if (defined $trigram_frequency_table{$trigram}); } else { $i ++; next; } } else { last; } $i ++; } return $fitness;
} ###############################################################################
# implementing mutation:
# This is implemented as a swap between probable neighbors based on the
# single letter frequencies of English. That is, the character ’e’ might
# be swapped with ’t’ but not with ’v’ or ’x’.
# In this case the random swap occurs only for the first 9 most frequent
# letters, based on the %letter_distribution_table.
sub mutation { my ($individual) = @_; my $mutated_individual = $individual; my $letters_count = 9; my $letter_position1 = int (rand ($letters_count)); my $letter_position2 = int (rand ($letters_count)); return $mutated_individual if ($letter_position1 == $letter_position2); my @letters_sorted_by_distribution = reverse sort { $letter_distribution_table{$a} <=> $letter_distribution_table{$b} } keys %letter_distribution_table; my $letter1 = $letters_sorted_by_distribution[$letter_position1]; my $letter2 = $letters_sorted_by_distribution[$letter_position2]; my $index1 = index ($alphabeth, $letter1); my $index2 = index ($alphabeth, $letter2); my @letters = split (//, $individual); my $swap_letter1 = $letters[$index1]; my $swap_letter2 = $letters[$index2]; my $digram_left = $swap_letter1 . $swap_letter2; my $digram_right = $swap_letter2 . $swap_letter1; $_ = $mutated_individual; eval “tr/$digram_left/$digram_right/”; $mutated_individual = $_; return $mutated_individual;
} ###############################################################################
# generate random individual (generates random permutation of the alphabeth):
sub generate_random_individual { my @letters = split (//, $alphabeth); my $random_individual = ”; foreach my $i (reverse (1 .. length $alphabeth)) { my $pos = int (rand $i); $random_individual .= $letters[$pos]; # delete the concatenated element from @letters: unless ($pos == $#letters) { my $temp = $letters[$#letters]; $letters[$#letters] = $letters[$pos]; $letters[$pos] = $temp; pop @letters; } else { pop @letters; } } return $random_individual;
} ###############################################################################
# number of populations:
my $populations_count = 20; ###############################################################################
# number of individuals in a population:
my $individuals_count = 20; ###############################################################################
# array of populations:
my @populations; ###############################################################################
# describe a population of indiliduals:
# my $population = {
# ‘individuals’ => [],
# ‘total_fitness’ => 0
# }; ###############################################################################
# describe an individual:
# my $individual = {
# ‘description’ => ”,
# ‘fitness’ => 0
# }; ###############################################################################
# sort individuals in a population by the fitness function:
sub sort_individuals { my ($population) = @_; @{$population->{’individuals’}} = reverse sort { $a->{’fitness’} <=> $b->{’fitness’} } @{$population->{’individuals’}};
} ###############################################################################
# sort populations by the cumulative fitness values:
sub sort_populations { @populations = reverse sort { $a->{’total_fitness’} <=> $b->{’total_fitness’} } @populations;
} ###############################################################################
# initialize the first generation:
sub zero_generation { foreach (1 .. $populations_count) { my $population = {}; $population->{’individuals’} = []; $population->{’total_fitness’} = 0; foreach (1 .. $individuals_count) { my $individual = {}; $individual->{’description’} = ”; $individual->{’fitness’} = 0; my $random_individual = generate_random_individual (); $individual->{’description’} = $random_individual; my $fitness = fitness ($random_individual); $individual->{’fitness’} = $fitness; push (@{$population->{’individuals’}}, $individual); $population->{’total_fitness’} += $fitness; } sort_individuals ($population); push (@populations, $population); } sort_populations ();
} ###############################################################################
# number of individuals in a population that will mutate:
my $mutate_individuals_count = 4; ###############################################################################
# mutate some randomly chosen individuals in a population:
# A random range of $mutate_individuals_count individuals from a single
# population will mutate.
sub mutate_population { my ($population) = @_; my $offset = int (rand ($individuals_count - $mutate_individuals_count)); foreach my $i (1 .. $mutate_individuals_count) { my $individual = ${$population->{’individuals’}}[$offset + $i]; my $mutated_description = mutation ($individual->{’description’}); $individual->{’description’} = $mutated_description; $population->{’total_fitness’} -= $individual->{’fitness’}; $individual->{’fitness’} = fitness ($mutated_description); $population->{’total_fitness’} += $individual->{’fitness’}; } sort_individuals ($population);
} ###############################################################################
# mutate all populations:
sub mutate_all_populations { foreach my $population (@populations) { mutate_population ($population); } sort_populations ();
} ###############################################################################
# breed the individuals in a population:
# The father is chosen among the 5 best individuals in a population.
# The mother is chosen among the rest individuals in the same population.
# Their child takes the place of the weakest individual in the population.
sub breeding { my ($population) = @_; my $father_pos = int (rand (5)); my $father_individual = ${$population->{’individuals’}}[$father_pos]; my $mother_pos = int (rand ($individuals_count - 5)) + 5; my $mother_individual = ${$population->{’individuals’}}[$mother_pos]; my $child_individual = ${$population->{’individuals’}}[$individuals_count - 1]; my $father = $father_individual->{’description’}; my $mother = $mother_individual->{’description’}; my $child = crossover ($father, $mother); $child_individual->{’description’} = $child; $population->{’total_fitness’} -= $child_individual->{’fitness’}; $child_individual->{’fitness’} = fitness ($child); $population->{’total_fitness’} += $child_individual->{’fitness’}; sort_individuals ($population);
} ###############################################################################
# breed all populations:
sub breed_all_populations { foreach my $population (@populations) { breeding ($population); } sort_populations ();
} ###############################################################################
# interbreeding between neighbour populations:
# The father is the best individual in the first population.
# The mother is randomly chosen individual from the next weakest population.
# Their child takes the place of the weakest individual in the mother’s
# population. I thought it’s quite reasonable to interbreed only neighbour
# populations (populations that have close values for the total_fitness).
sub interbreeding { foreach my $i (0 .. $populations_count - 2) { my $father_population = $populations[$i]; my $father_individual = ${$father_population->{’individuals’}}[0]; my $mother_population = $populations[$i + 1]; my $mother_pos = int (rand ($individuals_count)); my $mother_individual = ${$father_population->{’individuals’}}[$mother_pos]; my $child_individual = ${$mother_population->{’individuals’}}[$individuals_count - 1]; my $father = $father_individual->{’description’}; my $mother = $mother_individual->{’description’}; my $child = crossover ($father, $mother); $child_individual->{’description’} = $child; $mother_population->{’total_fitness’} -= $child_individual->{’fitness’}; $child_individual->{’fitness’} = fitness ($child); $mother_population->{’total_fitness’} += $child_individual->{’fitness’}; sort_individuals ($mother_population); } sort_populations ();
} ###############################################################################
# clone an individual:
sub clone_individual { my ($individual) = @_; my $cloned_individual = {}; $cloned_individual->{’description’} = $individual->{’description’}; $cloned_individual->{’fitness’} = $individual->{’fitness’}; return $cloned_individual;
} ###############################################################################
# sort array of individuals:
sub sort_best_individuals { my ($ref_individuals) = @_; @$ref_individuals = reverse sort { $a->{’fitness’} <=> $b->{’fitness’} } @$ref_individuals;
} ###############################################################################
# the best individuals throughout all generations:
my @best_individuals; ###############################################################################
# check if this individual is not already in the @best_individuals array:
sub is_member_individual { my ($ref_individuals, $individual) = @_; foreach my $member_individual (@$ref_individuals) { if ($member_individual->{’description’} eq $individual->{’description’}) { return “TRUE”; } } return undef;
} ###############################################################################
# merges to sorted lists of individuals:
sub merge_individuals { my ($ref_candidate_individuals) = @_; my @new_individuals = (@best_individuals); foreach my $candidate_individual (@$ref_candidate_individuals) { push (@new_individuals, $candidate_individual) unless (is_member_individual (\@new_individuals, $candidate_individual)); } sort_best_individuals (\@new_individuals); $#new_individuals = $populations_count - 1; @best_individuals = @new_individuals;
} ###############################################################################
# select the best individuals, and if they are better than the existing ones,
# change them:
# This is a way to save the local maxima for all generations in the evolution.
sub select_best_individuals { if (@best_individuals) { my @best_individuals_in_this_generation; foreach my $population (@populations) { my $individual = clone_individual (${$population->{’individuals’}}[0]); push (@best_individuals_in_this_generation, $individual); } sort_best_individuals (\@best_individuals_in_this_generation); merge_individuals (\@best_individuals_in_this_generation); } else { # first initialization of @best_individuals; foreach my $population (@populations) { my $individual = clone_individual (${$population->{’individuals’}}[0]); push (@best_individuals, $individual); } sort_best_individuals (\@best_individuals); }
} ###############################################################################
# calculate cumulative fitness for all populations in a generation:
sub cumulative_fitness { my $cumulative_fitness = 0; foreach my $population (@populations) { $cumulative_fitness += $population->{’total_fitness’}; } return $cumulative_fitness;
} ###############################################################################
# calculate next generation:
sub next_generation { breed_all_populations (); select_best_individuals (); interbreeding (); select_best_individuals (); mutate_all_populations (); select_best_individuals ();
} ###############################################################################
# decrypt the cypher text, using the individual’s description:
sub decrypt_individual { my ($individual) = @_; my $permutated_alphabeth = $individual->{’description’}; my $plain_text = $cypher_text; # decrypt, using the given individual: $_ = $plain_text; eval “tr/$permutated_alphabeth/$alphabeth/”; $plain_text = $_; return $plain_text;
} ###############################################################################
# prints all suggestions about the decription of the cypher text:
sub print_results { open (RESULTS, ‘>’, “decriptions.txt”) or die “Can’t open file! $!”; foreach my $population (@populations) { foreach my $individual (@{$population->{’individuals’}}) { my $plain_text = decrypt_individual ($individual); print RESULTS “$plain_text\n”; } } print RESULTS “\nBEST SUGGESTIONS:\n”; foreach my $individual (@best_individuals) { my $plain_text = decrypt_individual ($individual); print RESULTS “$plain_text\n”; } close (RESULTS);
} ###############################################################################
# number of generations that are allowed to be without an improvement:
# on every improvement increment this value!
# on every worsening decrement this value!
my $generations_without_improvement = 10; ###############################################################################
# simulation of the evolution process:
sub evolution { my $cumulative_fitness = 0; zero_generation (); select_best_individuals (); $cumulative_fitness = cumulative_fitness (); my $generations = 0; while ($generations_without_improvement) { print “GENERATION $generations\t\tFITNESS: $cumulative_fitness\tGENERATIONS LEFT: $generations_without_improvement\n”; $generations ++; next_generation (); my $new_cumulative_fitness = cumulative_fitness (); if ($new_cumulative_fitness > $cumulative_fitness) { $generations_without_improvement ++; $cumulative_fitness = $new_cumulative_fitness; } else { $generations_without_improvement –; } } print_results ();
} evolution ();
Jul 14, 2009 0
Cool&Easy way to configure reflections
Jul 14, 2009 0
Cool&Easy way to configure reflections
Jul 9, 2009 0
I’m writing this blog post for the very same purpose I’ve decidedly written my latest university paper in English. I just want to reach the biggest possible audience in attempt to introduce you an idea that has the potential to change drastically the way we write software.
HERE YOU CAN DOWNLOAD MY PAPER
Just as always when I have to write a paper for the university, I take the assigned topic and turn it into something completely different. And that’s exactly what I did for my Middleware paper.
My assignment was to write about Ontologies and Ontology Languages for Web Service Description, but it ended being a paper about reassessing the role which formality plays in the field of software engineering.
At the start, my intention was to take a couple of ontologies for web service description and to make an attempt to evaluate them according to a set of design criteria, as described in one of the most widely cited works in ontology – Thomas R. Gruber, Toward Principles for the Design of Ontologies Used for Knowledge Sharing.
But guess what? It doesn’t work that way. And it won’t work that way, especially when you don’t have enough time. And what do I mean by that?
As soon as I started my acquaintance with one of the ontologies I’ve picked, I realized that I don’t know enough and that I need to get familiar with the underlying layer. When I started to get to know the thing underneath, same sh*t happened. I just couldn’t move on without picking into the layer beneath. Getting two floors down and I couldn’t remember anymore what was two floors above.
I’ve always considered layering a good thing, but what was happening then? Why I’m not able to learn about a system one layer at a time, without having to pick into the layers beneath? And it just struck me:
All these layers of effective formality all the way down are simply inefficient…
…And it is inefficient not because it isn’t precise, but because it is maybe too precise.
When you grew an interest about something, interesting things will start to happen to you. Things like discovering new stuff, discovering new ideas and most importantly discovering new amazing people. Scheme is probably the most amazing programming language I’ve learned in the university, but I haven’t been manifesting any forms of interest in Lisp until recently. And that’s how I discovered the work of Gregor Kiczales – the creator of the Meta-Object Protocol for Lisp, the father of CLOS and the mind behind the Aspect-Oriented Programming. And one of the first things I did was listening to his keynote talk at OOPSLA 2007 (available as podcast and PDF slides). Since then I’ve been listening to this same talk at least three more times. This talk is all about formality vs. informality and it ended being a road-map for my Middleware paper. A substantial part of the audio you can find almost as a transcript in my paper. I’ve been shamelessly repeating Kiczales’ words with the hope they will raise some interest in these radical ideas.
In advance, I want to apologize to all the experts that are familiar in much more detail with the stuff I wrote about in my paper. To them it may seem that I’m just scratching the surface, and probably they’re right. Forgive me, if I haven’t presented your ideas in the right way, or if I’ve misunderstood you. If that’s the case, it would be great if I hear back from you.
Jul 7, 2009 0
Great comparison of Flex Frameworks – same requirements, different solutions!
Jul 7, 2009 0
Great comparison of Flex Frameworks – same requirements, different solutions!
Jun 30, 2009 0
A whole class of RIA applications is getting judiciously ignored by technology vendors like Adobe and Microsoft with the argument that these are way too custom to be utilized in any direction. In the recent years both vendors were focusing their efforts on streamlining the enterprise RIAs, both neglecting the class of applications that was previously the predominant type of RIA. I’m talking about marketing platform applications or Rich User Experiences that are not focused on providing a particular business function. Such applications most typically are not extensively using common UI controls and usually they don’t have to deal with visualizing and manipulating large sets of data in grids and charts.
Adobe have done a great job with Flex (and in the years to come it will hopefully improve)! But Flex comes with a certain weight that makes it nearly impossible to use when we have to develop the class of applications that I want to stress on. The overhead of the framework is too big to be ignored. Our main concern is that this will eventually result in poorer user experiences, because of initial download times. But even if we circumvent this issue in some way (check my article on Totally Custom Preloaders), the SWF will still include code dependencies that are used nowhere in the application. Not to mention that the whole component model is too heavy and complicated and will eventually stand in our way when we have to implement a totally custom experience.
But on the other hand Flex comes with a set of tools and concept that we really love and still want to be able to use. So what we end up doing in our free time in Obecto is a framework that would enable us to use Flex for really custom Flash apps with a minimal overhead from the framework. And we called this framework FLit – a light-weight Flex for Flash apps. We’ve developing it open source from line 1 – so feel free to check out the source from Google Code. There you’ll find some samples too!

First, FL stands for Flash. We want to build plain AS3 projects without the need to use <mx:Application> as a root object for our apps, and we want it to be as fast and as small as a plain AS3 project could be.

As you might guess FL also stands for Flex, but we only use a small subset of the Flex Framework, like Data Binding and MXML, and nothing else – no UIComponent, no Flex Application. How do we succeed in using MXML inside of a plain AS3 project? Well, this is a topic for another post.
We are also using a concept pretty close to the view contract in Spark, thus enabling the separation of concerns between the designer and the developer.

We understand liteness as to have minimum dependencies between components, thus there are no components in the framework that will induce as dependencies a substantial part of the framework itself.
We understand liteness as the ability to include only those concern that interest you and not some behavior hard-coded in the framework.
We also understand liteness as having a lite build process. Previously when building custom Flash apps we needed to use the designer machine and the designer productivity tools for the build. With FLit this is not the case – the designer is responsible only in preparing assets that must contain the parts specified in the view contract, so the productivity tools are not used for the build. So, this is also a pretty lite skinning process.

FLit is in early experimentation phase. Maybe this sample somewhat summarizes what’s inside the framework now? You can also check out the sample’s code!
A summary of features:
● light-weight base component
● light-weight base container
● view contract specification through metadata tags
● skin asset
● several layout strategies
● transition manager that supports declarative transitions between states
● tasks (an idea which originated from the GuggaFF) – Sequence and Parallel are also tasks
● declarative input validators
● skin-able button component
● tweening engine
Jun 19, 2009 0
This post is an attempt to help justify the sometimes seemingly unappreciated efforts of good application architecture. Sometimes project managers/clients can question time spent on architecture and it can be hard to bring out appropriate explanations on the spot. This…
May 19, 2009 0
Some really cool features are added into Gumbo effects.
May 19, 2009 0
Some really cool features are added into Gumbo effects.
May 18, 2009 0
Looks to me that mix-in's are not just for Flex, but also applicable for Flash.
May 18, 2009 0
Looks to me that mix-in's are not just for Flex, but also applicable for Flash.
May 14, 2009 0
Article aggregating lots of great resources (among which is my blog post Totally Custom Preloader) about Preloading Flex Applications
May 14, 2009 0
Article aggregating lots of great resources (among which is my blog post Totally Custom Preloader) about Preloading Flex Applications
May 13, 2009 0
Steps for installing Advanced Visualization onto the open source Flex SDK
May 13, 2009 0
Steps for installing Advanced Visualization onto the open source Flex SDK
Apr 29, 2009 0
A great resource about application and security domains in Flex.
Apr 29, 2009 0
A great resource about application and security domains in Flex.
Apr 29, 2009 0
Very straight forward explanation of what application domains are in Flex
Apr 29, 2009 0
Very straight forward explanation of what application domains are in Flex
Apr 15, 2009 0
The Flex DataBinding in the highest level of detail I've ever seen in a presentation.
Apr 15, 2009 0
The Flex DataBinding in the highest level of detail I've ever seen in a presentation.
Apr 14, 2009 0
Awesome explanation of the Flex SystemManager.
Apr 14, 2009 0
Awesome explanation of the Flex SystemManager.
Apr 14, 2009 0
Another great explanation of the details behind the UIComponent in Flex
Apr 14, 2009 0
Another great explanation of the details behind the UIComponent in Flex
Apr 14, 2009 0
One of the most comprehensive descriptions of the UIComponent life-cycle
Apr 14, 2009 0
One of the most comprehensive descriptions of the UIComponent life-cycle
Apr 11, 2009 0
This video is absolutely priceless – covering the Flash Player Architecture, optimizations, garbage collection and everything new to Flash Player 10.