Soundstep http://www.soundstep.com/blog Soundstep is a blog containing resources for developers, such as open source projects, libraries, frameworks, tutorials and experiments. Tue, 07 May 2013 12:04:15 +0000 en-US hourly 1 http://wordpress.org/?v=3.5.1 soma.js v2 write scalable javascript apps http://www.soundstep.com/blog/2013/05/07/soma-js-v2-write-scalable-javascript-apps/?utm_source=rss&utm_medium=rss&utm_campaign=soma-js-v2-write-scalable-javascript-apps http://www.soundstep.com/blog/2013/05/07/soma-js-v2-write-scalable-javascript-apps/#comments Tue, 07 May 2013 12:04:15 +0000 Romuald http://www.soundstep.com/blog/?p=1029 soma.js version 2 has finally been released!

Even though it shares the same goals as the previous version, the version 2 is completely different.

What is soma.js?

To set up a landscape, soma.js is a framework created to build scalable and maintainable javascript applications.

So yes, that’s another javascript framework. soma.js can be used as an MVC framework but its structure is so flexible that it can be used differently to fit your needs.

Why soma.js?

The following might not ring a bell to everyone, but the only thing developers should care about is writing code that is maintainable. This is sort of an ultimate goal to reach. And sometimes, it can be really hard, even for seasoned teams of developers.

Why should you bother think about that? Well, because a maintainable code will require less work and allow your application to grow. It is that simple.

It will also make you much happier, trust me. Have you never a reach a point looking at your code: “It is really becoming messy now, this will be a nightmare…”. So you know what I’m talking about?

Let me tell you something. Real large javascript apps, that are maintainable, don’t exist. Yes that’s right, they just don’t. Instead, you can find large scale javascript apps that are composed of a lot of pieces put together. This is more like it. These pieces can be called modules or other names.

In all successful and maintainable structures, these smaller pieces probably have a common point: they have very small number of dependencies. In other words, these smaller pieces can work on their own and don’t know about the application itself. They can be swapped, interfaced. They are meant to do a single job, nothing more, and have no idea what other elements will do with it. They are put together, moved, refactored, enhanced, and so on.

This is the success key of building large javascript applications, or in fact, any application.

This is what soma.js is about. You will write pure plain javascript as you are used to, and the framework will provide tool to help you reduce dependencies and make your code more maintainable and testable.

What is different in soma.js?

One day, and this wasn’t using javascript, I’ve started tackle “frameworks”. The idea was simple, they help build something. These interests in frameworks quickly drove me in blog posts showing obsessions about how code should be written, best practices basically.

They all had the same goal: make your developer life easier.

People are talking about their framework of choice, what is good and what is not. Some famous developers offering solutions to solve problems in more effective ways. And so on.

In different languages, I saw something happen. All these highly-coupled code problems, dependencies, non-maintainable code issues, and framework fights, got a solution that has been a revelation for a lot of developers: dependency injection.

Of course, I’m not saying that dependency injection is a solution for everything and should be used everywhere. But where complexity lies, I’m a strong believer in dependency injection. I also think that it has been a turn in a lot of developers’ carrier. It is helping, it is pretty, it is simple. You can find literally thousands of blog posts talking about its benefits, in various languages.

That is what soma.js version 2 brings: dependency injection.

How does it look?

I’ve spent a lot of time explaining the what, why and how. A site is available with tons of examples, guidelines to follow, what is dependency injection, and so on.

Click here to find out more.

Hope that will help some of you having a better time with your own code!

Romu

]]>
http://www.soundstep.com/blog/2013/05/07/soma-js-v2-write-scalable-javascript-apps/feed/ 0
User interactions with soma-template http://www.soundstep.com/blog/2012/12/10/user-interactions-with-soma-template/?utm_source=rss&utm_medium=rss&utm_campaign=user-interactions-with-soma-template http://www.soundstep.com/blog/2012/12/10/user-interactions-with-soma-template/#comments Mon, 10 Dec 2012 16:57:22 +0000 Romuald http://www.soundstep.com/blog/?p=992 As a reminder, soma-template is a DOM-based web template engine that will help you insert content in html pages with native DOM manipulation.

Events have been added to soma-template. You can now easily add user events to elements, such as click, mouse over, key press, mouse down, drag, and so on. The functions called can also received parameters from the current set of data. This allow the event handlers to receive targeted data without searching for its reference, which might greatly reduce the amount of code needed.

The site has been updated, see the events documentation and the full list of events.

The events have been used in the todo demo, the events demo and the people demo.

And here is a video showing the events in action.

]]>
http://www.soundstep.com/blog/2012/12/10/user-interactions-with-soma-template/feed/ 2
soma-template seamless dom manipulation http://www.soundstep.com/blog/2012/11/22/soma-template-seamless-dom-manipulation/?utm_source=rss&utm_medium=rss&utm_campaign=soma-template-seamless-dom-manipulation http://www.soundstep.com/blog/2012/11/22/soma-template-seamless-dom-manipulation/#comments Thu, 22 Nov 2012 15:37:30 +0000 Romuald http://www.soundstep.com/blog/?p=981 soma-template is a web template engine. The library aims to help developers insert data in their html applications using native DOM capabilities.

Most web template engine today are “string-based”, which means they will compute a string with a set of data, JSON data very often, and insert the result using the innerHTML DOM element property.

While this is completely fine, soma-template has another goal. The library will help you insert content in your html application with a minimal DOM node destruction, updating only what is needed. This is opening new capabilities, such as updating only some nodes, or being able to browse the template as you would browse the DOM.

Another goal has been the ease-of-use as having several templates can become messy and confusing. For that very reason, the template can be fully part of the DOM, without having to inject a template source into the DOM.

The template syntax will feel natural, the engine is customizable and it has a very flexible API that can be enhanced using custom functions or external libraries such as underscore.string.

The engine has been tested in all modern browsers and from IE7 to IE10, mobile and desktop.

Feel free to use it anywhere you like, send issues on Github, and feedback appreciated!

Click here to see the soma-template site

]]>
http://www.soundstep.com/blog/2012/11/22/soma-template-seamless-dom-manipulation/feed/ 0
soma-events native DOM 3 Observer pattern http://www.soundstep.com/blog/2012/09/17/soma-events-native-dom-3-observer-pattern/?utm_source=rss&utm_medium=rss&utm_campaign=soma-events-native-dom-3-observer-pattern http://www.soundstep.com/blog/2012/09/17/soma-events-native-dom-3-observer-pattern/#comments Mon, 17 Sep 2012 11:20:20 +0000 Romuald http://www.soundstep.com/blog/?p=855 At some points, any developer will read something about loose-coupling and the Law of Demeter.

It is usually happening when you are writing code that becomes a bit larger and you start to have difficulties to scale it up, maintain it, read it, test it, and so on. The idea is very simple, each component should work on its own, responsible for its own task, be encapsulated, and while begin part of something bigger, should not know about the other components (not having a reference to them).

You usually have 2 problems to solve to achieve this:
1. find a way so the component is getting data to do its job
2. find a way so the component can tell other components that something has been done

There’s tons of way of solving the first one, I talked about one of them in a previous post: injection with infuse.js.

And to solve the second problem, the Observer Pattern is usually the way, also called “publishing-subscribing”.

Let me quote Addy Osmani again:
“The motivation behind using the observer pattern is where you need to maintain consistency between related objects without making classes tightly coupled. For example, when an object needs to be able to notify other objects without making assumptions regarding those objects.”

I’ve kind of always been concerned with that one, as in the best world, you don’t want to add framework code in a view or a model component that should be fully re-usable, and re-usable everywhere, and written in pure plain javascript where possible.

There’s one Observer Pattern that is part of the Dom specification: the Event model (Dom 4 Event specs seems on its way too).

It would be a very good thing to use something standard as an Observer Pattern but there’s 2 problems with that one:
1. cross-browsing issues
2. need a DOM

I’ve extracted the observer pattern used in the soma.js framework so it is easily re-usable everywhere.

It is called soma-events, and provides a wrapper function to create native custom events and solve cross-browsing issues, and a custom dispatcher so the exact same API can be used without the DOM.

As a very quick overview, it would look like this:

var EventTypes = {
    START: "start"
}
var Application = function() {
    var model = new Model();
    dispatcher.dispatchEvent(new Event(EventTypes.START, {myStuff:"myStuff"}));
};
var Model = function() {
    dispatcher.addEventListener(EventTypes.START, function(event) {
        console.log("application started with:", event.params.myStuff);
    });
};
var app = new Application();

The dispatcher variable in this example can be both a custom dispatcher (EventDispather), or just a DOM Element.

More info and example on the Github readme:
https://github.com/soundstep/soma-events

Quick install (works also with node.js):

npm install soma-events

]]>
http://www.soundstep.com/blog/2012/09/17/soma-events-native-dom-3-observer-pattern/feed/ 0
infuse.js ioc javascript library http://www.soundstep.com/blog/2012/09/12/infuse-js-ioc-javascript-library/?utm_source=rss&utm_medium=rss&utm_campaign=infuse-js-ioc-javascript-library http://www.soundstep.com/blog/2012/09/12/infuse-js-ioc-javascript-library/#comments Wed, 12 Sep 2012 14:00:32 +0000 Romuald http://www.soundstep.com/blog/?p=840 Infuse.js is an IOC javascript library (inversion of control).

Using rules based on properties and paramaters naming, you will be able to inject data in functions or objects.

Quick video for the impatient:

Why would I need to inject anything anywhere?

Dependency injection is used in many languages, the concept is that some data are injected automatically when you create a “class” or other re-usable component.

Just a few advantages of using injection not to name them all. Injection will reduce boilerplate code (increasing readability), dependencies between components and you will be able to produce a much more re-usable code. Injection is also very good to produce a highly-testable code.

The application you are building will also benefit from lazy instantiation, which is very good, the instances will be created only when they are used and when you need them.

Infuse.js is a pretty small library compared to the huge benefit you can gain.

 So… How does this work?

In short, you are going to create some rules based on names (string), you will provide data to inject (string, number, array, boolean, objects, function, and probably anything that can be hold in a variable).

When these rules are created, you are going to use their names as properties or constructor parameters. And the injector will take care of populating these variables with the right content, no strings attached!

Sorry I still don’t get it…

Let’s take an example then, you are building a huge app with several developers, javascript files, components, and so on. You have a basic function called “Settings” that will hold a lot of information and you like to use it in about anything in the app. How do you do that?

Well, you could create some kind of global object, you can access it everywhere and it is done!

window.Settings = {
	deploy: 'dev',
	domain: 'localhost'
}

But in that case you will create a direct dependency on a object (Settings), which is bad for tons of reasons. Hard to test, not re-usable because of the dependencies, and so on. You should always stick to the Law of Demeter.

Another solution would be to create that object and pass it in everything you need, that would be a better a solution, but still very hard to maintain and not ideal.

With injection you can do the same thing in a much easier way (which is populating variable with something external), especially if you want to inject tons of things. But this could also be automatically done!

It would be nice to just say: “ok I’ve created these 6 components, I really would like to have that “settings” variable automatically set without doing anything or adding code for it!”. Well that’s what infuse.js will do.

Sounds good! Let’s see some code!

Well first, create an injector instance.

// create injector
var injector = new infuse.Injector();

Now you create an object you want to access to from everywhere, just as an example, it could be a function, an array, a string, or whatever.

// create object
var settings = {
	deploy: 'dev',
	domain: 'localhost'
}

Now you want to say: “ok, every time something contains the variable ‘settings’, or has a constructor parameter ‘settings’, I want that object to be set in.”

That is nothing more than a mapping rule. Here is an example.

injector.mapValue('settings', settings);

Last step is populating the variables. This can be done in two ways: manually or automatically. Here is how to do that manually:

// a function
var Receiver = function() {
	this.settings = null;
}
// create an instance
var receiver = new Receiver();
// populate the settings variable
injector.inject(receiver);

That’s basically it, you can add a postConstruct method, which will be automatically called when the injection is done.

Receiver.prototype.postConstruct = function() {
	alert(this.settings); // got it!
}

Easy? Let’s see the automatic version where the injector will take care of instantiating the function and populating the variables.

// a function
var Receiver = function() {
	this.settings = null;
}
Receiver.prototype.postConstruct = function() {
	alert(this.settings); // got it!
}
// create an instance
var receiver = injector.createInstance(Receiver);

Works also with a constructor.

// a function
var Receiver = function(settings) {
	this.mySettings = settings;
	alert(this.mySettings); // got it!
}
// create an instance
var receiver = injector.createInstance(Receiver);

The injector can inject data in several ways, and can also take care of instantiation, of what should be injected and how it should injected. If we turn the data to a function:

var Settings = function() {
	this.deploy = 'dev';
	this.domain = 'localhost';
}

We can use another type of rule (mapClass):

injector.mapClass('settings', Settings);

The injector will now inject a new instance of Settings every time it has to be injected somewhere (like doing a new Settings() and sending it).

This might not be ideal, maybe you want to inject the same instance all the time so you have some kind of shared unique instance? This is called a “Singleton mapping”. Don’t be scared by the name if you don’t like Singleton, they are not really Singleton. It just means that they are created only once and the same instance will be injected everywhere. You can do that by changing the rules like this:

injector.mapValue('settings', settings, true);

As the “settings” rule has been set “as Singleton”, the same settings instance will be injected in both functions.

var FooClass1 = function() {
	this.settings = null;
}
var FooClass2 = function() {
	this.settings = null;
}
var foo1 = injector.createInstance(FooClass1);
var foo2 = injector.createInstance(FooClass2);
// next line will alert true because the settings injected
// will be the same instance (mapped as Singleton)
alert(foo1.settings === foo2.settings);

This is just a small overview, you can do tons of things with injection and infuse.js.

Where do I get more info?

The repo is there, where you can find more examples (you can also check the tests in the repo to get a complete overview):
https://github.com/soundstep/infuse.js

Install with npm (infuse.js works with node.js):

npm install infuse.js

var Injector = require("infuse.js").Injector;
var injector = new Injector();
injector.mapValue('name', 'John');
var Person = function(name) { this.nameParam = name; };
var john = injector.createInstance(Person);
console.log(john.nameParam);

And the demo from the video.

]]>
http://www.soundstep.com/blog/2012/09/12/infuse-js-ioc-javascript-library/feed/ 7
hone.js minify html css and javascript http://www.soundstep.com/blog/2012/06/15/hone-js-minify-html-css-and-javascript/?utm_source=rss&utm_medium=rss&utm_campaign=hone-js-minify-html-css-and-javascript http://www.soundstep.com/blog/2012/06/15/hone-js-minify-html-css-and-javascript/#comments Fri, 15 Jun 2012 17:16:25 +0000 Romuald http://www.soundstep.com/blog/?p=829 I had fun making a node.js module and a npm package.

So here is hone.js, it is using r.js and other tools to optimize and minify html, css and javascript files.

More info there:
https://github.com/soundstep/hone.js

And a quick video:

]]>
http://www.soundstep.com/blog/2012/06/15/hone-js-minify-html-css-and-javascript/feed/ 0
soma.js router plugin http://www.soundstep.com/blog/2012/04/26/soma-js-router-plugin/?utm_source=rss&utm_medium=rss&utm_campaign=soma-js-router-plugin http://www.soundstep.com/blog/2012/04/26/soma-js-router-plugin/#comments Thu, 26 Apr 2012 12:39:48 +0000 Romuald http://www.soundstep.com/blog/?p=818 I wrote a router plugin for soma.js to create internal routes in a web app.

The plugin is based on the amazing library davis.js (thanks a lot to the author Oliver from New Bamboo for the help). It uses the HTML5 history API and have a hash fallback for browsers that don’t support the HTML5 API (see the davis hash routing plugin).

Click here to see the demo, the soma.js site has also been updated with the plugin and the latest version (1.0.2).

Prepare the html

Include the libraries in your page:

<script src="/js/davis.js"></script>
<script src="/js/davis.hashRouting.js"></script>
<script src="/js/soma.js"></script>
<script src="/js/soma-router.js"></script>

Create the plugin

Creating the plugin takes only one line:

var router = this.createPlugin(soma.router.Router);

This can be done in a soma.js framework element such as the application itself or a wire:

var SomaApplication = soma.Application.extend({
	init: function() {
		this.createPlugin(soma.router.Router);
	}
});
var app = new SomaApplication();

Create the routes

Given some html links:

<li><a href="/">Home</a></li>
<li><a href="/about">About</a></li>
<li><a href="/services">Services</a></li>
<li><a href="/articles">Articles</a></li>
<li><a href="/articles/article1">Articles</a></li>
<li><a href="/articles/article2">Articles</a></li>
<li><a href="/articles/article3">Articles</a></li>
<li><a href="/contact">Contact</a></li>

Here is how the routes can be created:

var routes = {
	'get': {
		'/' : RouterEventTypes.ROOT,
		'/:nav' : RouterEventTypes.NAV,
		'/:nav/:subnav' : RouterEventTypes.SUBNAV
	}
};

The variables RouterEventTypes are simple strings and will be used as event types.

var RouterEventTypes = {
	ROOT: "root",
	NAV: "nav",
	SUBNAV: "subnav"
};

When the router will find a route, from a url change or when a link is clicked in the browser, a specific event will be dispatched through the framework. A url such as “http://site.com/about” will be matched by the rule “/:nav” and an event of type “RouterEventTypes.NAV” will be dispatched through the framework.

Note that I could have set a route in a static way: “/about” rather than “/:nav”.

Register the routes to the router

The routes object created previously can be registered to the router this way:

var router = this.createPlugin(soma.router.Router, routes);

Listen to route changes

Now that everything is set up, it is only a matter of adding event listeners in the framework elements, here is an example with a wire:

var WireRouter = soma.Wire.extend({
	init: function() {
		this.addEventListener(RouterEventTypes.ROOT, this.rootHandler);
		this.addEventListener(RouterEventTypes.NAV, this.navHandler);
		this.addEventListener(RouterEventTypes.SUBNAV, this.subnavHandler);
	},
	rootHandler: function(event) {
		// do something
	},
	navHandler: function(event) {
		// do something
	},
	subnavHandler: function(event) {
		// do something
	}
});

The event received contains the following information:

  • event.params.rule -> /:nav
  • event.params.request -> Davis.Request

And the Davis.Request will contains all the information you might need. Such as the link or url:

navHandler: function(event) {
	var request = event.params.request;
	// the following variable urlParameter will contain "about"
	// if the link was for example http://site.com/about
	var urlParameter = request.params[RouterEventTypes.NAV];
}

Controlling and interrupting

A global route change event can also be listened to:

this.addEventListener(soma.router.RouterEvent.CHANGED, this.changeHandler);

This is an internal framework command and can be interrupted this way:

changeHandler:function(event) {
	if (whatever_reason) {
		// stop the route to occur
		event.preventDefault();
	}
}

Hash routing fallback

In case the browser doesn’t support the HTML5 History API, you can add a hash fallback by adding the Davis plugin hashRounting just before you create the router plugin:

Davis.extend(Davis.hashRouting({ prefix: "!/" }));
this.createPlugin(soma.router.Router);

Davis handler

When a Davis.js instance is created, an handler is passed to it and will be a Davis.App.

For example:

var app = Davis(function () {
	// do something
});

The creation of the Davis.App is automatically done by the plugin but you can still pass the handler to it and do more Davis.js specific operations:

var router = this.createPlugin(soma.router.Router, routes, function() {
	app.bind('routeNotFound', function () {
		// do something
	});
});

Handling non-existing route

When you have a url and create HTML5 History routes (called states), these URLS might not exist in reality.
If a user go a non-existing URL, it can be either handled by the server to the serve the correct content, or you can use the following htaccess file on an Apache Server:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !index
RewriteRule (.*) index.html [L]

These rules will redirect any URL that is not a file or a folder to the index.html of you site, Davis.js will then handle the routes for you to show the right content on the client side.

Note that you need to specify to Davis.js that you want the first page load to be handled as a route:

var router = this.createPlugin(soma.router.Router, routes, function() {
	this.settings.generateRequestOnPageLoad = true;
});

To get the router plugin, you can either:
- clone the repository (native or mootools version)
- grab it directly (native or mootools)
- check out the soma.js site

For more information about Davis.js, you can check:
- Davis.js site
- Davis.js API documentation
- Davis.js code

]]>
http://www.soundstep.com/blog/2012/04/26/soma-js-router-plugin/feed/ 0
javascript displacement mapping http://www.soundstep.com/blog/2012/04/25/javascript-displacement-mapping/?utm_source=rss&utm_medium=rss&utm_campaign=javascript-displacement-mapping http://www.soundstep.com/blog/2012/04/25/javascript-displacement-mapping/#comments Wed, 25 Apr 2012 17:58:54 +0000 Romuald http://www.soundstep.com/blog/?p=800 I wrote a javascript displacement map filter, mostly as an experiment, this graphic technique has been widely used in Flash.

Check out the following demos:
- interactive demo
- picture demo

Displacement mapping is a simple action of shifting pixels. An image map containing color values is used as data to create the displacement and move pixels around.

The filter can be used several different effects, here are some that have been done in Flash, these might give you ideas:
- fish eye effect
- distortion
- fire
- flag effect (with perlin noise)

And two great links to have a better understanding of the displacement mapping. Both links explain the Flash version of the filter, but it is almost identical (missing modes for now) to the one I wrote in javascript. I strongly recommend to read the first link.
- understand displacement mapping
- actionscript documentation

About the demo with the picture, I created an image map in Photoshop, please notice my skill with a brush :)
displacement map

I used the javascript displacement filter to apply it on the following picture, and finally draw it in a canvas.
photo

The filter itself will take different parameters that can be changed in real-time (on a time interval):
- a canvas containing the image on which the filter will be applied on
- a canvas containing the image map to create the displacement
- a canvas where the result will be drawn
- a point (x and y) where the displacement will be applied on the image source
- a scale value for the X axis, this will be the amount of displacement on this axis
- a scale value for the Y axis
- a color channel for the X axis, the color used to create the displacement on this axis
- a color channel for the Y axis

It will look like this:

var filter = new filters.DisplacementMap(
	canvasSource,
	canvasMap,
	canvasTarget,
	new filters.Point(50, 50),
	40,
	40,
	filters.ColorChannel.RED,
	filters.ColorChannel.GREEN);
filter.draw();

When the draw method is called, the filter will loop over the pixels of the image map and find the color that has been specified to create the displacement. A color is represented by the hexadecimal value of 255 (0xFF). If the color found in the map for a specific pixel is superior to the half (0×80), the pixel shifting will increase, otherwise it will decrease.

About the second demo, I reproduced a flash demo from Zeh Fernando that I really liked. There’s a simple background with heart pattern used as a source image, and the displacement map looks like this:
displacement map

The gradient colors are chosen so that the displacement will create a magnifying effect. The red colors will be used to move the pixels on the X axis and the green colors will be used to move on the Y axis.

I also reproduced a little trick to emphasis the displacement. Ive added a simple png with transparency on top of the displacement, it contains lights and shadows:
heart

I also tweened the filter values with TweenJS to add a bit of movement (the heart bump), as in the Flash version.

Click here to download the demo and source.

]]>
http://www.soundstep.com/blog/2012/04/25/javascript-displacement-mapping/feed/ 11
javascript motion detection http://www.soundstep.com/blog/2012/03/22/javascript-motion-detection/?utm_source=rss&utm_medium=rss&utm_campaign=javascript-motion-detection http://www.soundstep.com/blog/2012/03/22/javascript-motion-detection/#comments Thu, 22 Mar 2012 01:00:38 +0000 Romuald http://www.soundstep.com/blog/?p=772 This is a motion detection experiment in javascript, and before starting any explanation:

Click here to see the demo.

To see this demo with your own webcam, you will need to download a browser that enables some new features as explained in this link. To make it simple, I’ve used Google Chrome Canary, go and get it!

I used an html 5 API this is not released yet, the html 5 getUserMedia API. This API makes you able to use a webcam stream in javascript. Exiting! Paul Neave has done a very nice webcam demo.

So what is the demo about?

I use a webcam feed, I put a xylophone image on top of it and I detect the user’s movements to play the xylophone.

To detect the user’s movement I used a technic that is probably well-known by developers, designers and motion designers: the blend mode difference.

The concept is, if you put a picture on top of the same picture and blend them together using the blend mode difference, you obtain… a black screen!

If there’s a slight difference between the 2 pictures, the colors start to appear, showing you the “difference” between the two pictures. You get something like that:

Not exactly like that actually, in this demo I made an average on each pixel between the red, the green and the blue, and turn them to white above a certain amount to get a bit more accuracy.

The first step is drawing the webcam feed in a canvas, grab a picture from it at a time interval, and blend the current frame to the previous one. This means that if you don’t move, the result will be black, and when you start moving some pixels will turn white.

To be a bit more precise, I loop over the pixels of the current frame and I subtract the pixels color from the same pixel color of the previous frame. This is what the blend mode difference is doing: “Difference subtracts the top layer from the bottom layer or the other way round, to always get a positive value.”.

The next step is checking in some areas (the different parts of the xylophone) if you have some white pixels in them. If you get a certain amount of non-black pixels in this area, it means that something moved since the last frame and I play a note.

I’ve been using the Web Audio API to the play the notes, the demo is fully done in javascript.

*UPDATE*

Click here to see a more in-depth article on ADC on how to create the motion detection

]]>
http://www.soundstep.com/blog/2012/03/22/javascript-motion-detection/feed/ 21
Javascript motion tracking http://www.soundstep.com/blog/2012/03/19/javascript-motion-tracking/?utm_source=rss&utm_medium=rss&utm_campaign=javascript-motion-tracking http://www.soundstep.com/blog/2012/03/19/javascript-motion-tracking/#comments Mon, 19 Mar 2012 14:15:28 +0000 Romuald http://www.soundstep.com/blog/?p=748 It is very often that I have to do video motion tracking for interactive video campaign in my daily work.

If I’m used used to do that in Flash, I made a quick experiment to do the same in javascript.

Thanks to Olof Storm who made me a perfect corner pin motion tracking in After Effects, and I’ve been using some code from Steven Wittens to draw an image in perspective.

Click here to see the motion tracking demo (give it a bit of time to fully load).

What I’m doing in this demo is drawing a video in a canvas, and using the corner pin tracking data to draw an image on top of the video.

I made 2 different videos, you can switch between them using the “switch video” button.

In the first video, I get the current video frame number by calculation (current time by video fps). And in the second video, I get the frame number using a different technique that is know to be quite accurate when we do it in Flash, I call that a binary counter.

The idea behind the binary counter is to export the video with some white and black rectangle that describe graphically the real frame number of the video. We’ve been using this technique in Flash for a while in the advertising industry, and Zeh Fernando talked about it last year.

You can see the binary counter on the right border of the video. The code gets a pixel in each bit of the binary counter (16 bits), find out if the bit is white or black to get a 0 or 1 and calculate a number out of it.

While you might not see a difference between the two frame number calculations at first glance, seeking the video with the binary counter version (using the top-right blue control) will keep the image and the video “synchronised”. Pretty cool.

This version is not perfect compared to what we do in Flash, some frames still seem to be a bit “out”. I also couldn’t find a way to solve “pixel snapping drawing” in a canvas, in other words, being able to draw an image on half a pixel.

I did really miss some powerful drawing method from the graphic API in Flash. I would love to find in javascript a “beginBitmapFill” method, apply matrix directly to a drawing method and draw triangles in an easier way to use this plane drawing technic we use in Flash.

*update*

I just found out that what I call a binary counter is actually a VITC, which I didn’t know! Interesting!

]]>
http://www.soundstep.com/blog/2012/03/19/javascript-motion-tracking/feed/ 6
Image loader plugin for soma.js http://www.soundstep.com/blog/2012/03/08/image-loader-plugin-for-soma-js/?utm_source=rss&utm_medium=rss&utm_campaign=image-loader-plugin-for-soma-js http://www.soundstep.com/blog/2012/03/08/image-loader-plugin-for-soma-js/#comments Thu, 08 Mar 2012 10:00:49 +0000 Romuald http://www.soundstep.com/blog/?p=742 Now that we can easily create plugins for soma.js, I’ve created an image loader plugin.

I’ve used PxLoader as a base and before any explanation, it looks like that:

Image loader plugin demo.

The plugin will take a url to a json config file that describes a list of images to load and dispatch some progress and complete events through the framework.

The advantage of using the plugin is that you are able to listen to these events anywhere in your application: in a wire, in the framework instance or a model.

Here is how to instantiate the plugin.

this.createPlugin(SomaImageLoader, "assets/config.json");

The plugin will first load the config file, you can add an event to know when it will be loaded. And again, anywhere in the application, a model to manage your assets would make complete sense.

this.addEventListener(SomaImageLoaderEvent.CONFIG_LOADED, this.configLoadedHandler.bind(this));

Once the config is loaded, you can dispatch a command to start the loading.

this.dispatchEvent(new SomaImageLoaderEvent(SomaImageLoaderEvent.START));

The plugin will catch the start event and start the loading.
To retrieve the images and use them, you can either listen to an “image complete” event, or wait that everything is loaded and listen to a “queue complete event”.

this.addEventListener(SomaImageLoaderEvent.ITEM_COMPLETE, this.itemCompleteHandler.bind(this));
this.addEventListener(SomaImageLoaderEvent.QUEUE_COMPLETE, this.completeHandler.bind(this));
itemCompleteHandler: function(event) {
	// notification received when an item is loaded
	console.log('> item complete', event.params.completed, "/", event.params.total);
	console.log('    id:', event.params.loader.id);
	console.log('    loader:', event.params.loader);
	console.log('    data:', event.params.data);
	// draw image loaded in a canvas
	var canvas = document.getElementById('canvas');
	var ctx = canvas.getContext('2d');
	ctx.drawImage(event.params.data, 0, 0);
},
completeHandler: function(event) {
	// notification received when all items are loaded
	this.log('> complete');
	// draw all images loaded in a canvas
	var canvas = document.getElementById('canvas');
	var ctx = canvas.getContext('2d');
	ctx.drawImage(event.params.data['img1'], 0, 0);
	ctx.drawImage(event.params.data['img2'], 100, 50);
	ctx.drawImage(event.params.data['img3'], 200, 100);
	ctx.drawImage(event.params.data['img4'], 300, 150);
	ctx.drawImage(event.params.data['img5'], 400, 200);
	},

You don’t have to use a config json, all these operation can be done manually if you wish to.

var plugin = this.createPlugin(SomaImageLoader);
// plugin.loadConfig("assets/config.json");
plugin.addImage("myImage1", "assets/images/img1.jpg");
plugin.addImage("myImage2", "assets/images/img2.jpg");
plugin.start();

You can find the plugin on the soma.js site in the “plugins section” or on the github repo.

You will find both a native version and a Mootools version.

]]>
http://www.soundstep.com/blog/2012/03/08/image-loader-plugin-for-soma-js/feed/ 0
soma.js update 1.0.1 plugin system http://www.soundstep.com/blog/2012/03/08/soma-js-update-1-0-1-plugin-system/?utm_source=rss&utm_medium=rss&utm_campaign=soma-js-update-1-0-1-plugin-system http://www.soundstep.com/blog/2012/03/08/soma-js-update-1-0-1-plugin-system/#comments Thu, 08 Mar 2012 01:54:01 +0000 Romuald http://www.soundstep.com/blog/?p=738 I’ve added a plugin system in soma.js and a tutorial how to create a plugin on the site.

It is quite simple and everything is explained in the tutorial step by step, but here is a quick overview.

To create a plugin, you just need to create a function that will receive a soma framework instance and any additional parameter.

var MyPlugin = function(instance, myParam) {
	this.instance = instance;
	this.myParam = myParam;
}

Another syntax that might be helpful, especially if you want to extend the plugin later on.

var MyPlugin = soma.extend({
	constructor: function(instance, myParam) {
		this.instance = instance;
		this.myParam = myParam;
	}
});

Now that you have access to the framework instance, you can create models, wires, commands, events, and so on.

To use the plugin, you just need to instantiate it in either a framework instance, a wire or a command.

var SomaApplication = soma.Application.extend({
	init: function() {
		var plugin = this.createPlugin(MyPlugin, "my param");
	}
});
var app = new SomaApplication();

That’s it!

Check out a more advanced plugin with the step by step tutorial on the soma.js site.

]]>
http://www.soundstep.com/blog/2012/03/08/soma-js-update-1-0-1-plugin-system/feed/ 0
Soma.js – lightweight MVC Javascript Framework http://www.soundstep.com/blog/2012/03/05/soma-js-lightweight-mvc-javascript-framework/?utm_source=rss&utm_medium=rss&utm_campaign=soma-js-lightweight-mvc-javascript-framework http://www.soundstep.com/blog/2012/03/05/soma-js-lightweight-mvc-javascript-framework/#comments Mon, 05 Mar 2012 15:25:46 +0000 Henry http://www.soundstep.com/blog/?p=711 We are excited to release a new Javascript framework called soma.js. I am Henry Schmieder, London based web developer, and this is my first post on this blog. Romu and I have been working on this framework the last couple of weeks and I’m going to introduce it to you.

soma.js is a Javascript model-view-controller (MVC) framework that is meant to help developers to write loosely-coupled applications to increase scalability and maintainability.

Check the soma.js website where you can find the framework, demos, unit tests, documentation, tutorials, and so on.

Why another Javascript framework?

We both have a strong background in other languages and we thought it would be nice to bring our experience to the Javascript world. Javascript is evolving, and while the language is pretty powerful, its use is very different today than years ago. Applications have become more and more complex and manifold, from one page GUI driven web apps to stateless mobile applications. To keep the process of developing modern JavaScript applications easy and fun, we built soma.js.

There are many great Frameworks out there, written in different languages, that cover the basics of a structured development flow of more complex applications. The core paradigm for a lot of them is the MVC concept.

We believe in the Law of Demeter to develop complex application structure, and we also believe that loose-coupling development is key. soma.js implements the Observer and Command pattern through the native javascript event system, which offered many advantages and flexibility.

There is a lot of discussion as to how much sense makes trying to project concepts of a strong OOP language like Java or ActionScript onto the loosely typed, dynamic prototype based Javascript. But there is a lot of sense in it, not at least having a background in applying the benefits of structured application design based on OOP concepts and pattern based concepts like MVC.

I used Mootools for the very first version of soma.js and Romu joined me to give the project a massive backwind towards a public release. So we worked on a complete unit test system, an automated template downloader and packer, a set of demos, a complete documentation and an interactive demo site that explains the project and allows realtime code example modification and execution and introduces into all the important concepts of the framework step by step. On top of that we decided to remove the dependency from another framework, Mootools, and created a complete native version, also entirely documented and unit test backed.

Have fun with it and provide feedback to us!

]]>
http://www.soundstep.com/blog/2012/03/05/soma-js-lightweight-mvc-javascript-framework/feed/ 2
Manage multiple Git SSH key with the terminal http://www.soundstep.com/blog/2012/02/23/manage-multiple-git-ssh-key-with-the-terminal/?utm_source=rss&utm_medium=rss&utm_campaign=manage-multiple-git-ssh-key-with-the-terminal http://www.soundstep.com/blog/2012/02/23/manage-multiple-git-ssh-key-with-the-terminal/#comments Thu, 23 Feb 2012 09:20:19 +0000 Romuald http://www.soundstep.com/blog/?p=644 If you are like me, you might have many accounts to online project hosting services. I have 1 codesion, 2 github and 1 beanstalk. On top of this you might also work at different places: at the office, at home, and so on.

I like to use git with the command line and it took me while to find out some really useful commands to manage the ssh keys.

All these services manage their access with ssh public key. To create them, it is easy, just follow the wonderful Github guide:
http://help.github.com/mac-set-up-git/

The following tips are working on a Mac, I have no idea if they would on Windows, I suspect Linux will work.

But sometimes you get:

Permission denied (publickey,keyboard-interactive).
fatal: The remote end hung up unexpectedly

Even though you generated created that key last week, it doesn’t seem to be there anymore. You probably have the key in your folder (/Users/my_user/.ssh) but the terminal doesn’t use it.

So first command, list the identities that are in use:

ssh-add -l

To remove an identity:

ssh-add -d /Users/my_user/.ssh/keyfile_name

And to add one:

ssh-add /Users/my_user/.ssh/keyfile_name

That’s it, very simple, but now you can manage your keys.

If you have other tips, please comment!

]]>
http://www.soundstep.com/blog/2012/02/23/manage-multiple-git-ssh-key-with-the-terminal/feed/ 0
After effects export trackers or properties http://www.soundstep.com/blog/2011/07/29/after-effects-export-trackers-or-properties/?utm_source=rss&utm_medium=rss&utm_campaign=after-effects-export-trackers-or-properties http://www.soundstep.com/blog/2011/07/29/after-effects-export-trackers-or-properties/#comments Fri, 29 Jul 2011 17:05:07 +0000 Romuald http://www.soundstep.com/blog/?p=639 Hi,

I wrote 2 quick scripts for After Effects to export properties to XML. I thought it might be handy for some of you.

I mainly wrote them to export motion trackers to use in Flash afterwards, but you should be able to export other properties.

To use them, do the following:
1. In the menu: Preferences > General > and tick “Allow scripts to write files and access network”
2. open a project
3. select the properties you want to export (for example the 4 points “Feature Center” of motion trackers)
4. In the menu: File > Scripts > Run script file…
5. select one the following scripts

A file “export.txt” should have been created on your desktop (and opened), with the XML content inside.

You should be able to export other properties, such as Transform properties like “position”, and so on.

It is certainly not bug free, but it should get you started.

Export by properties
Export by time

Hope that helps!

]]>
http://www.soundstep.com/blog/2011/07/29/after-effects-export-trackers-or-properties/feed/ 2
SomaAssets demo http://www.soundstep.com/blog/2011/06/06/somaassets-demo/?utm_source=rss&utm_medium=rss&utm_campaign=somaassets-demo http://www.soundstep.com/blog/2011/06/06/somaassets-demo/#comments Mon, 06 Jun 2011 15:00:46 +0000 Romuald http://www.soundstep.com/blog/?p=632 As requested, I Just made a quick demo how to implement the SomaAssets plugin in your application.

See the demo.
Download the demo.
View source.
Demo on github.

I’ll make a quick descrition here. I’ll be using the following XML config:

<?xml version="1.0" encoding="UTF-8"?>
<loader connection="1">
	<asset id="image0" src="assets/img/image0.jpg" smoothing="true" transparent="true"/>
	<asset id="image1" src="assets/img/image1.jpg" smoothing="true" transparent="true"/>
	<group id="group0">
		<group id="group00">
			<asset id="image2" src="assets/img/image2.jpg" smoothing="true" transparent="true"/>
			<asset id="image3" src="assets/img/image3.jpg" smoothing="true" transparent="true"/>
		</group>
		<group id="group01">
			<asset id="css" src="assets/css/stylesheet.css" preventCache="true" weight="352"/>
			<asset id="json" src="assets/json/data.json" preventCache="true" weight="582"/>
			<asset id="sound" src="assets/sounds/sample.mp3" preventCache="true" weight="16718"/>
			<asset id="text" src="assets/text/text.txt" preventCache="true" weight="574"/>
			<asset id="xml" src="assets/xml/sample.xml" preventCache="true" weight="79"/>
			<asset id="video" src="assets/video/sample.flv" weight="1550580"/>
			<asset id="zip" src="assets/zip/file.zip" weight="3493"/>
		</group>
	</group>
</loader>

First step, I create a SomaCore application.

public function Main() {
	_app = new SomaApplication(this);
}

In the application facade, I create a command from a SomaAssets just to demo how to monitor the assets loading at a framework level. I also register 3 views and 3 mediators to show how to get the assets at different moments. I create the plugin SomaAssets and I finally create a simple wire class “InitializeWire” to handle some global events (config loaded, assets loaded, etc).

package com.soma.plugins.assets.demo {

	import com.soma.plugins.assets.demo.commands.ExampleAssetCommand;
	import com.soma.plugins.assets.events.SomaAssetsEvent;
	import com.soma.core.Soma;
	import com.soma.core.di.SomaInjector;
	import com.soma.core.interfaces.ISoma;
	import com.soma.plugins.assets.SomaAssets;
	import com.soma.plugins.assets.demo.views.ImageGroup;
	import com.soma.plugins.assets.demo.views.ImageGroupMediator;
	import com.soma.plugins.assets.demo.views.ImageWhenAllLoaded;
	import com.soma.plugins.assets.demo.views.ImageWhenAllLoadedMediator;
	import com.soma.plugins.assets.demo.views.ImageWhenNotLoaded;
	import com.soma.plugins.assets.demo.views.ImageWhenNotLoadedMediator;
	import com.soma.plugins.assets.demo.wires.InitializeWire;
	import com.soma.plugins.assets.vo.SomaAssetsVO;

	/**
	 * @author Romuald Quantin
	 */
	public class SomaApplication extends Soma implements ISoma {

		private var _container:Main;

		public function SomaApplication(container:Main) {
			_container = container;
			super(_container.stage, SomaInjector);
		}
		
		// create a command for a demo purpose to monitor the assets that are loaded
		override protected function registerCommands():void {
			addCommand(SomaAssetsEvent.ASSET_LOADED, ExampleAssetCommand);
		}
		
		// register mediators to views
		// the views won't be created at the same moment to show how you can handle your loading 
		override protected function registerViews():void {
			mediators.mapView(ImageWhenAllLoaded, ImageWhenAllLoadedMediator);
			mediators.mapView(ImageWhenNotLoaded, ImageWhenNotLoadedMediator);
			mediators.mapView(ImageGroup, ImageGroupMediator);
		}
		
		// create the plugin and register an external assets configuration to load
		override protected function registerPlugins():void {
			createPlugin(SomaAssets, new SomaAssetsVO(this, "xml/assets.xml"));
		}
		
		// create an wire where you could handle the "global" loading process
		override protected function start():void {
			injector.createInstance(InitializeWire);
		}
		
		// just the document class to add some views to
		public function get container():Main {
			return _container;
		}
		
	}
}

In the InitializeWire class, I add some event listeners to handle errors, when the XML config is loaded and when the assets are all loaded. I used it mostly to create views and mediators at different moments of the loading process to show you how to handle you loaders, events and assets.

package com.soma.plugins.assets.demo.wires {

	import com.soma.plugins.assets.demo.views.ImageGroup;
	import com.soma.core.interfaces.IWire;
	import com.soma.core.wire.Wire;
	import com.soma.plugins.assets.demo.SomaApplication;
	import com.soma.plugins.assets.demo.views.ImageWhenAllLoaded;
	import com.soma.plugins.assets.demo.views.ImageWhenNotLoaded;
	import com.soma.plugins.assets.events.SomaAssetsEvent;
	import flash.display.DisplayObjectContainer;
	import org.assetloader.core.IAssetLoader;

	/**
	 * @author Romuald Quantin
	 */
	public class InitializeWire extends Wire implements IWire {
		
		[Inject(name="assets")]
		public var loader:IAssetLoader;
		
		// register some SomaAssets events for monitoring
		override public function initialize():void {
			addEventListener(SomaAssetsEvent.CONFIG_LOADED, configLoaded);
			addEventListener(SomaAssetsEvent.LOADER_COMPLETE, assetsComplete);
			addEventListener(SomaAssetsEvent.ERROR, assetsErrorHandler);
		}
		
		// shortcut to get the document class
		private function get container():DisplayObjectContainer {
			return SomaApplication(instance).container;
		}

		// in case there's an error for both the assets config or the assets
		private function assetsErrorHandler(event:SomaAssetsEvent):void {
			trace("Asset Error:", event.errorMessage, event.errorType);
		}
		
		// the external XML assets config has been loaded here 
		private function configLoaded(event:SomaAssetsEvent):void {
			container.addChild(new ImageWhenNotLoaded());
			container.addChild(new ImageGroup());
			trace("config loaded");
			loader.start();
		}
		
		// all assets container in the config XML have been loaded here 
		private function assetsComplete(event:SomaAssetsEvent):void {
			container.addChild(new ImageWhenAllLoaded());
		}

	}
}

In the ImageWhenAllLoadedMediator mediator, I inject directly an asset (Bitmap) as everything is loaded when the mediator gets created.

package com.soma.plugins.assets.demo.views {

	import com.soma.core.interfaces.IMediator;
	import com.soma.core.mediator.Mediator;

	import flash.display.Bitmap;

	/**
	 * @author Romuald Quantin
	 */
	public class ImageWhenAllLoadedMediator extends Mediator implements IMediator {

		[Inject]
		public var view:ImageWhenAllLoaded;
		
		// all the assets are loaded at this point
		// we can inject the asset (or loaders)
		[Inject(name="image0")]
		public var image:Bitmap;
		
		override public function initialize():void {
			image.scaleX = image.scaleY = 0.1;
			image.x = 130;
			view.addChild(image);
		}
		
		override public function dispose():void {
			while (view.numChildren > 0) view.removeChildAt(0);
			view = null;
			image = null;
		}
		
	}
}

The ImageWhenNotLoadedMediator mediator gets created when the XML config has been loaded. The assets are not loaded yet and I show how to retrieve the loader of a specific asset to monitor when it starts, the loading progress and when it has been completed.

package com.soma.plugins.assets.demo.views {

	import flash.display.Bitmap;
	import com.soma.core.interfaces.IMediator;
	import com.soma.core.mediator.Mediator;

	import org.assetloader.core.ILoader;
	import org.assetloader.events.AssetLoaderErrorEvent;
	import org.assetloader.events.AssetLoaderEvent;
	import org.assetloader.events.AssetLoaderProgressEvent;

	/**
	 * @author Romuald Quantin
	 */
	public class ImageWhenNotLoadedMediator extends Mediator implements IMediator {

		[Inject]
		public var view:ImageWhenNotLoaded;
		
		// here we get the loader of an asset for monitoring purpose
		// this one is an ImageLoader but we keep the interface as a type
		[Inject(name="image1")]
		public var imageLoader:ILoader;
		
		// add some listeners to monitor the loading of a single loader 
		override public function initialize():void {
			imageLoader.addEventListener(AssetLoaderErrorEvent.ERROR, errorHandler);
			imageLoader.addEventListener(AssetLoaderEvent.START, startHandler);
			imageLoader.addEventListener(AssetLoaderProgressEvent.PROGRESS, progressHandler);
			imageLoader.addEventListener(AssetLoaderEvent.COMPLETE, completeHandler);
		}

		private function errorHandler(event:AssetLoaderErrorEvent):void {
			trace("Error", event.errorType, event.message);
		}

		private function startHandler(event:AssetLoaderEvent):void {
			trace("Loading started (" + ILoader(event.currentTarget).id + ")");
		}

		private function progressHandler(event:AssetLoaderProgressEvent):void {
			trace("Loading progress (" + ILoader(event.currentTarget).id + ") progress:", event.progress, ", speed:", event.speed);
		}
		
		// the loader is complete, the asset is ready
		private function completeHandler(event:AssetLoaderEvent):void {
			trace("Loading completed (" + ILoader(event.currentTarget).id + ")");
			var image:Bitmap = event.data;
			image.scaleX = image.scaleY = 0.1;
			view.addChild(image);
		}
		
		override public function dispose():void {
			while (view.numChildren > 0) view.removeChildAt(0);
			view = null;
			imageLoader = null;
		}
		
	}
}

The ImageGroupMediator mediator does the same job as the mediator above but applied to an IAssetLoader (loader containing others loaders). The way to monitor the loading process is exactly the same. I also show different ways to retrieve the assets of this group, once the groupe has been loaded. You will notice the special injection name of the loader, it is a path generated from the XML config using the group and assets ids and a delimiter.

package com.soma.plugins.assets.demo.views {

	import flash.display.Bitmap;
	import com.soma.plugins.assets.SomaAssets;
	import com.soma.core.interfaces.IMediator;
	import com.soma.core.mediator.Mediator;
	import org.assetloader.core.IAssetLoader;
	import org.assetloader.core.ILoader;
	import org.assetloader.events.AssetLoaderErrorEvent;
	import org.assetloader.events.AssetLoaderEvent;
	import org.assetloader.events.AssetLoaderProgressEvent;
	import flash.utils.Dictionary;

	/**
	 * @author Romuald Quantin
	 */
	public class ImageGroupMediator extends Mediator implements IMediator {

		[Inject]
		public var view:ImageGroup;
		
		// here we get the plugin
		[Inject(name="assets")]
		public var assets:SomaAssets;

		// here we get a group using a path (ids + delimiter)
		[Inject(name="group0/group00")]
		public var imageGroup:IAssetLoader;
		
		// add some listeners to monitor the loading of a single group 
		override public function initialize():void {
			imageGroup.addEventListener(AssetLoaderErrorEvent.ERROR, errorHandler);
			imageGroup.addEventListener(AssetLoaderEvent.START, startHandler);
			imageGroup.addEventListener(AssetLoaderProgressEvent.PROGRESS, progressHandler);
			imageGroup.addEventListener(AssetLoaderEvent.COMPLETE, completeHandler);
		}

		private function errorHandler(event:AssetLoaderErrorEvent):void {
			trace("Error", event.errorType, event.message);
		}

		private function startHandler(event:AssetLoaderEvent):void {
			trace("Loading started (" + ILoader(event.currentTarget).id + ")");
		}

		private function progressHandler(event:AssetLoaderProgressEvent):void {
			trace("Loading progress (" + ILoader(event.currentTarget).id + ") progress:", event.progress, ", speed:", event.speed);
		}

		// now the group is loaded, get the 2 images from the group 
		private function completeHandler(event:AssetLoaderEvent):void {
			trace("Loading completed (" + ILoader(event.currentTarget).id + ")");
			var images:Dictionary = event.data;
			trace("asset from dictionary", images["image3"]);
			trace("asset from loader:", imageGroup.getAsset("image3"));
			trace("asset from plugin:", assets.getAssets("group0/group00/image3"));
			var image2:Bitmap = images["image2"];
			var image3:Bitmap = images["image3"];
			image2.x = 290;
			image2.scaleX = image2.scaleY = 0.1;
			image3.x = 340;
			image3.scaleX = image3.scaleY = 0.1;
			view.addChild(image2);
			view.addChild(image3);
		}
		
		override public function dispose():void {
			while (view.numChildren > 0) view.removeChildAt(0);
			view = null;
			imageGroup = null;
		}
		
	}
}

The ExampleAssetCommand command is just a demo to show that you can use the SomaAssetsEvent class to directly create commands from it. In this example I used the type SomaAssetsEvent.ASSET_LOADED. The command will get created every time an asset is loaded.

package com.soma.plugins.assets.demo.commands {

	import com.soma.core.controller.Command;
	import com.soma.core.interfaces.ICommand;
	import com.soma.plugins.assets.SomaAssets;
	import com.soma.plugins.assets.demo.SomaApplication;
	import com.soma.plugins.assets.events.SomaAssetsEvent;

	import flash.display.DisplayObjectContainer;
	import flash.events.Event;
	import flash.media.Sound;
	import flash.media.Video;
	import flash.net.NetStream;
	import flash.text.TextField;
	import flash.utils.getQualifiedClassName;

	/**
	 * @author Romuald Quantin
	 */
	public class ExampleAssetCommand extends Command implements ICommand {
		
		[Inject]
		public var evt:SomaAssetsEvent;
		
		[Inject(name="assets")]
		public var assets:SomaAssets;
		
		// just some examples
		public function execute(event:Event):void {
			var container:DisplayObjectContainer = SomaApplication(instance).container;
			trace("Command Example (" + evt.path + ") > " + assets.getLoader(evt.path).type + " Loaded: " +  getQualifiedClassName(evt.asset));
			// you can use a switch to find the assets:
			switch (evt.path) {
				case "group0/group01/css":
					break;
				case "group0/group01/json":
					break;
				case "group0/group01/sound":
					var sound:Sound = evt.asset;
					sound.play(0);
					break;
				case "group0/group01/text":
					var textfield:TextField = new TextField();
					textfield.multiline = textfield.wordWrap = true;
					textfield.text = evt.asset;
					container.addChild(textfield);
					break;
				case "group0/group01/xml":
					break;
				case "group0/group01/video":
					var video:Video = new Video();
					var stream:NetStream = evt.asset;
					container.addChild(video);
					video.y = 80;
					video.smoothing = true;
					video.attachNetStream(stream);
					stream.resume();
					break;
				case "group0/group01/zip":
					break;
			}
		}
		
	}
}

This implementation is just an example as it could be handled in very different ways, but that should get you started.

]]>
http://www.soundstep.com/blog/2011/06/06/somaassets-demo/feed/ 0
SomaCore plugin to load and manage assets: SomaAssets http://www.soundstep.com/blog/2011/06/03/somacore-plugin-assets-somaassets/?utm_source=rss&utm_medium=rss&utm_campaign=somacore-plugin-assets-somaassets http://www.soundstep.com/blog/2011/06/03/somacore-plugin-assets-somaassets/#comments Fri, 03 Jun 2011 14:13:10 +0000 Romuald http://www.soundstep.com/blog/?p=622 Two new releases today, an asset loader and the SomaCore plugin: SomaAssets.

The AssetLoader library is a port from Matan’s AssetLoader library to be event-based, it makes you able to load and manage multiple assets (image, video, xml, sound, etc) in your application.

SomaAssets is a plugin based on the AssetLoader library to easily access to your assets and effectively integrate them in your SomaCore application with paths and automatic mapping name generation for injection.

Special thanks to Matan for his help with the AssetLoader and his joy in general, a pleasure to “meet” him.

You can read the SomaAssets wiki section to get started with it, but I’ll post below a few hints of what you can easily do with it within a SomaCore application.

AssetLoader source
AssetLoader wiki
SomaAssets source
SomaAssets wiki

Easily create the plugin and add a XML config file for the assets.

createPlugin(SomaAssets, new SomaAssetsVO(this, "xml/assets_config.xml"))

Easily retrieve the assets with paths through the XML config.

var image:Bitmap = assets.getAssets("group0/group00/img0");

Easily retrieve the plugin, main loader, config and assets with injection in a SomaCore application. The following mapping names have been automatically generated from the XML config.

[Inject(name="assets")]
public var plugin:SomaAssets;

[Inject(name="assets")]
public var loader:IAssetLoader;

[Inject(name="group0/group00/img0")]
public var loaderType1:ImageLoader;

[Inject(name="group0/group00/img0")]
public var assetType1:Bitmap;
]]>
http://www.soundstep.com/blog/2011/06/03/somacore-plugin-assets-somaassets/feed/ 3
AS3 debugging interface with BinderUI http://www.soundstep.com/blog/2011/05/17/as3-debugging-interface-with-binder-ui/?utm_source=rss&utm_medium=rss&utm_campaign=as3-debugging-interface-with-binder-ui http://www.soundstep.com/blog/2011/05/17/as3-debugging-interface-with-binder-ui/#comments Tue, 17 May 2011 09:31:57 +0000 Romuald http://www.soundstep.com/blog/?p=615 BinderUI is a debugging tools to help you create interfaces and debug values.

Very often I’m sure you spend time building visual interfaces to set, to see and to debug some values.
This can be useful for example to show to the creative (or even the client?) and extract the right values instead of tweaking thing for ages, I’m sure you know what I mean.

That can be time consuming and is often very annoying so I wanted to ease the process (1 line of code and a metadata tag).

BinderUI is a simple static class and the idea is to “bind” a value to visual components such as slider, knob, meter, text input, and so on. For the components I used the library minimalComps.

That means that the bound values will update the components in real-time and the components will update the values (two-ways). I used the BindingUtils and ChangeWatcher classes from the mx package but as it will be for debugging, you can use it on project that will be pure AS3 as well.



Click here to see the demo.

As a quick example, imagine you have a custom darkness property on your custom class, you can bind the value this way:


BinderUI.displaySliderHorizontal(this, _mySprite, “darkness”, “darkness”, null, 0.1, 1, -255, 255);

This will create a slider that will update (and be updated) for your darkness property.

You’ll also need to add a Bindable metadata in your class:

[Bindable]
public class MySprite extends Sprite {

Note: in case you want to debug built-in flash properties (such as x and y), you’ll need to override the properties in your custom class even if it does nothing.

override public function get x():Number {
	return super.x;
}
override public function set x(value:Number):void {
	super.x = value;
}

For now you can debug only properties (getters and setters), and types that are String, Number, Boolean (and color).

Here is a list of component that can be used.

BinderUI.displayLabel(this, s, "x")
BinderUI.displayColorChooser(this, sprite, "color", 0xFFFF00);
BinderUI.displayCheckBox(this, sprite, "halfTransparent", "half transparent");
BinderUI.displayIndicatorLight(this, sprite, "halfTransparent", "half transparent");
BinderUII.displayNumericStepper(this, sprite, "x", 5, null, 0, 900, 1);
BinderUI.displayInput(this, sprite, "x");
BinderUI.displaySliderHorizontal(this, sprite, "x", "x", null, 0.1, 1, 0, 900);
BinderUI.displaySliderVertical(this, sprite, "x", "x", null, 0.1, 1, 0, 900);
BinderUI.displayTextarea(this, sprite, "x");
BinderUI.displayKnob(this, sprite, "x", "x", null, Knob.VERTICAL, 20, 0, 900);
BinderUI.displayMeter(this, sprite, "x", "x", null, 0, 900);

In some case, it is harder to bind values, such as when you want to update a component from what you type in a textfield. You’ll need to dispatch an event yourself (usually these events are added by the compiler with the Bindable metadata tag).

dispatchEvent(new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE, false, false, PropertyChangeEventKind.UPDATE, 'text', oldValue, newValue, this));

About colors, you can use the displayColorChooser method. The easiest is using a “color” property for example.

BinderUI.displayColorChooser(this, mySprite, "color");

You can also use the colorTransform property but this property is not bindable, so it will work only in one way (component —> target):

BinderUI.displayColorChooser(this, mySprite.transform, "color");

You can also use the MinimalConfigurator to create your interface from an XML file.

Three methods are available to dispose (remove and destroy) components. You can dispose by target, by component or dispose everything.

BinderUI.disposeByTarget(mySprite);
BinderUI.disposeByComponent(myComponent)
BinderUI.dispose();

Download source and demos.
Source on github.

]]>
http://www.soundstep.com/blog/2011/05/17/as3-debugging-interface-with-binder-ui/feed/ 0
Knob AS3 drag on circle or ellipse http://www.soundstep.com/blog/2011/04/08/knob-as3-drag-on-circle-or-ellipse/?utm_source=rss&utm_medium=rss&utm_campaign=knob-as3-drag-on-circle-or-ellipse http://www.soundstep.com/blog/2011/04/08/knob-as3-drag-on-circle-or-ellipse/#comments Fri, 08 Apr 2011 13:58:20 +0000 Romuald http://www.soundstep.com/blog/?p=604 I needed some knobs for a debug interface. I share this very simple class to use so you don’t have to rebuild it from scratch, it should be pretty flexible.



Click here to see the demo.

Download source.

The knob can be used as circle or ellipse, here is how to create one:

var knob:Knob = new Knob();
knob.addEventListener(Event.CHANGE, changeHandler);
addChild(knob);

function changeHandler(event:Event):void {
	var knob:Knob = event.currentTarget as Knob;
	trace(knob.value);
	trace(knob.valuePercent);
}

Set the radius, a custom handler and a custom graphic:

var customHandler:Sprite = new Sprite();
customHandler.graphics.beginFill(0xFF0000);
customHandler.graphics.drawRect(-10, -10, 20, 20);
customHandler.graphics.endFill();
var knob:Knob =  = new Knob(100, 50, customHandler);
knob.stylePathColor = 0x00FF00;
knob.stylePathThickness = 3;
knob.stylePathAlpha = 0.3;

That’s pretty much it, here is the class:

package {

	import flash.display.DisplayObject;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;

	/**
	 * @author Romuald Quantin
	 */
	public class Knob extends Sprite {

		private var _radiusX:Number;
		private var _radiusY:Number;
		private var _handler:DisplayObject;
		private var _sector:Sector;
		
		private var _stylePathColor:uint = 0xCCCCCC;
		private var _stylePathAlpha:Number = 1;
		private var _stylePathThickness:Number = 0;

		public function Knob(radiusX:Number = 100, radiusY:Number = 100, handler:DisplayObject = null) {
			setRadius(radiusX, radiusY);
			setHandler(handler);
			updatePositionFromDegree(-90);
		}

		private function setRadius(radiusX:Number, radiusY:Number):void {
			_radiusX = radiusX;
			_radiusY = radiusY;
			if (!_sector) _sector = new Sector(0, _radiusX, _radiusY);
			draw();
			updatePosition();
		}

		private function setHandler(value:DisplayObject):void {
			disposeDragabble();
			_handler = (!value) ? createNewHandler() : value;
			setHandlerListeners();
			addChild(_handler);
			updatePosition();
		}

		private function setHandlerListeners():void {
			_handler.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
		}

		private function removeHandlerListeners():void {
			_handler.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
			stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
			stage.removeEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler);
		}

		private function mouseLeaveHandler(event:Event):void {
			stopDragging();
		}

		private function mouseDownHandler(event:MouseEvent):void {
			startDragging();
		}

		private function mouseUpHandler(event:MouseEvent):void {
			stopDragging();
		}

		private function startDragging():void {
			stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
			stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
			stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
			stage.removeEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler);
			stage.addEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler);
		}

		private function stopDragging():void {
			stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
			stage.removeEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler);
		}

		private function mouseMoveHandler(event:MouseEvent):void {
			updatePosition();
		}

		private function updatePosition():void {
			var ratio:Number = _radiusX / _radiusY;
			var angle:Number = Math.atan2(mouseX, mouseY);
			updatePositionFromDegree(90 - (Math.atan2(Math.sin(angle), Math.cos(angle) * ratio)) * (180 / Math.PI));
			dispatchEvent(new Event(Event.CHANGE));
		}

		private function updatePositionFromDegree(value:Number):void {
			_sector.degree = value;
			_sector.radiusX = _radiusX;
			_sector.radiusY = _radiusY;
			if (_handler) {
				_handler.x = _sector.x;
				_handler.y = _sector.y;
			}
		}

		private function createNewHandler() : DisplayObject {
			var circle:Sprite = new Sprite();
			circle.graphics.beginFill(0x434F6C);
			circle.graphics.drawCircle(0, 0, 5);
			return circle;
		}

		private function draw():void {
			graphics.clear();
			graphics.lineStyle(_stylePathThickness, _stylePathColor, _stylePathAlpha);
			graphics.moveTo(_sector.x, _sector.y);
			var i:Number = 0;
			var l:Number = 360;
			for (; i <= l; ++i) {
				_sector.degree = i;
				_sector.radiusX = _radiusX;
				_sector.radiusY = _radiusY;
				graphics.lineTo(_sector.x, _sector.y);
			}
			graphics.endFill();
		}

		public function get radiusX():Number {
			return _radiusX;
		}

		public function set radiusX(value:Number):void {
			setRadius(value, _radiusY);
		}

		public function get radiusY():Number {
			return _radiusY;
		}

		public function set radiusY(value:Number):void {
			setRadius(_radiusX, value);
		}

		public function get handler() : DisplayObject {
			return _handler;
		}

		public function set handler(value:DisplayObject):void {
			setHandler(value);
		}

		public function get value():Number {
			return _sector.degree + 90;
		}

		public function set value(value:Number):void {
			updatePositionFromDegree(value - 90);
		}

		public function get valuePercent():Number {
			return value / 360;
		}

		public function set valuePercent(value:Number):void {
			this.value = 360 * Math.min(1, Math.max(0, value));
		}

		public function disposeDragabble():void {
			if (!_handler) return;
			removeHandlerListeners();
			if (_handler.hasOwnProperty("dispose")) {
				_handler['dispose']();
			}
			removeChild(_handler);
			_handler = null;
		}

		public function dispose():void {
			disposeDragabble();
			_sector = null;
		}

		public function get stylePathColor():uint {
			return _stylePathColor;
		}

		public function set stylePathColor(value:uint):void {
			_stylePathColor = value;
			draw();
		}

		public function get stylePathAlpha():Number {
			return _stylePathAlpha;
		}

		public function set stylePathAlpha(value:Number):void {
			_stylePathAlpha = value;
			draw();
		}

		public function get stylePathThickness():Number {
			return _stylePathThickness;
		}

		public function set stylePathThickness(value:Number):void {
			_stylePathThickness = value;
			draw();
		}
	}
}

class Sector {

	public var degree:Number;
	public var radiusX:Number;
	public var radiusY:Number;

	public function Sector(degree:Number = 0, radiusX:Number = 10, radiusY:Number = 10) {
		this.degree = degree;
		this.radiusX = radiusX;
		this.radiusY = radiusY;
	}

	public function get x():Number {
		return radiusX * Math.cos(degree * Math.PI / 180);
	}

	public function get y():Number {
		return radiusY * Math.sin(degree * Math.PI / 180);
	}

	public function toString():String {
		return "[Sector] degree: " + degree + ", radiusX: " + radiusX + ", radiusY: " + radiusY + ", x: " + x + ", y: " + y;
	}
}
]]>
http://www.soundstep.com/blog/2011/04/08/knob-as3-drag-on-circle-or-ellipse/feed/ 2
SomaCore wiki and framework flow http://www.soundstep.com/blog/2011/03/14/594/?utm_source=rss&utm_medium=rss&utm_campaign=594 http://www.soundstep.com/blog/2011/03/14/594/#comments Mon, 14 Mar 2011 09:00:43 +0000 Romuald http://www.soundstep.com/blog/?p=594 I’ve added some more information on the SomaCore wiki.

You can find some code and explanation how to use, create and remove Wires within the framework, using injection or not. I also explained how to monitor and control the application flow with methods you are used to, such as dispatchEvent, addEventListener, preventDefault and so on.

You can also find explanation to handle the views in the framework.

Last addition is a diagram showing the commands flow from other framework elements, I’ve added it to the previous SomaCore diagram.

SomaCore Diagram


Next step in the wiki are about commands and 2 others diagrams related to them.

Hope that will help to get you started.

]]>
http://www.soundstep.com/blog/2011/03/14/594/feed/ 0
SomaCore tutorial framework instance http://www.soundstep.com/blog/2011/02/09/somacore-tutorial-framework-instance/?utm_source=rss&utm_medium=rss&utm_campaign=somacore-tutorial-framework-instance http://www.soundstep.com/blog/2011/02/09/somacore-tutorial-framework-instance/#comments Wed, 09 Feb 2011 09:00:57 +0000 Romuald http://www.soundstep.com/blog/?p=583 I’ll be writing in the next days a series of wiki, manual, best practices with tons of code example. It should help you to get started. I will be explaining in-depth how SomaCore works and what you can do with it.

The first one is about the Framework Instance. The different ways to create a SomaCore application, what is required, how to enable dependency injection and how to access to this instance.

]]>
http://www.soundstep.com/blog/2011/02/09/somacore-tutorial-framework-instance/feed/ 2
SomaCore AS3 MVC Framework v2 release http://www.soundstep.com/blog/2011/02/07/somacore-as3-mvc-framework-v2-release/?utm_source=rss&utm_medium=rss&utm_campaign=somacore-as3-mvc-framework-v2-release http://www.soundstep.com/blog/2011/02/07/somacore-as3-mvc-framework-v2-release/#comments Mon, 07 Feb 2011 10:00:56 +0000 Romuald http://www.soundstep.com/blog/?p=558 SomaCore is a lightweight AS3 MVC event-based framework that provides a very flexible structure for your Flash, Flex and AIR projects.

The main addition in this version 2 is Dependency Injection, but it is up to you how you want to use SomaCore because injection is optional.

Information

SomaCore Main Page (tutorials, demos, source)
Repository SomaCore (github)
Repository Demos (github)
Repository Plugins (github)
Documentation

Don’t want to read, just show me some code!

SomaCore Hello World
SomaCore CafeTownSend (Flex)
Twitter Search demo (pure as3)

SomaCore is both a registry and dependency injection framework

As a base, SomaCore is a registry framework, much like PureMVC. The framework makes you able to add and remove elements to the framework instance to be able to access them from anywhere (such as addView, getView, addWire, getWire, addModel, getModel, addCommand, and so on).

Enable injection

You are now able to use dependency injection. It can be enabled by sending an ISomaInjector class to the constructor of the Soma class:

public class SomaApplication extends Soma implements ISoma {
    public function SomaApplication(stage:Stage) {
        super(stage, SomaInjector);
    }
}

The injector is accessible from framework instances, wires and commands using the property injector.

Here is a quick example:

injector.mapToInstance(MyModel, new MyModel());
injector.mapSingleton(MyWire);
injector.getInstance(MyWire);
package  {
    import com.soma.core.wire.Wire;
    import com.soma.core.interfaces.IWire;
    
    public class MyWire extends Wire implements IWire {

        [Inject]
        public var model:MyModel;
        
        override public function initialize():void {
            // called when the wire has been registered to the framework
            trace(model, " is injected");
        }
        
        override public function dispose():void {
            // called when the wire has been removed from the framework
        }
        
    }
}

Inspirations

Before going further, I have to give some credits.

When I first tried Robotlegs, one part strikes me as it was solving a problem I had for a while: The mediator system: being able to build your application and add mediators regardless of any kind of structure and very easily. This workflow was so nice that it made me rethink a lot of things.

SomaCore has some capabilities that made me build the framework and I wasn’t ready to give them up. But I felt that this mediator workflow in SomaCore would just be amazing and a great addition.

I built these tools and frameworks to make my developer life easier, I then share them to other developers. If my work makes them enjoy their coding, that’s good enough for me.

So before asking myself too many questions, I reproduced the mediator system in SomaCore. It is now very similar to Robotlegs but it can also be used without enabling injection. That is the first part of the credits: a big one to Robotlegs that has been an amazing inspiration to SomaCore, as big as PureMVC has been for the version 1.

The second credit would go to the library SwiftSuspenders, the same one that Robolegs is using to handle its dependency injection. It is very lightweight and has good performance.

Mediators

Here is how it works, you can map a view to another class (the mediator), and every time this “mapped view” will be added to a display list, the mediator class will be instantiated with a reference to this view. The mediator class will also be destroyed when the view is removed from the display list. Everything is automatic and handled by the framework.

In SomaCore the Mediator class is extending the Wire class which gives access to everything in the framework.

Mapping a view (example in a wire):

mediator.mapView(MySprite, MySpriteMediator);

The mediator get instantiated when the view is added to the display list

addChild(new MySprite());

Mediator example:

package {
    import com.soma.core.interfaces.IMediator;
    import com.soma.core.mediator.Mediator;
    public class MySpriteMediator extends Mediator implements IMediator {
        
        [Inject]
        public var view:MySprite;
        
        override public function initialize():void {
            // called when the mediator has been created and registered to the framework
            trace(view == viewComponent);
        }
        
        override public function dispose():void {
            // called when the mediator has been destroyed by the framework
        }
        
    }
}

From version 1 to version 2

Only minor changes:

1. initialize and dispose methods in wires and models are now public.

package  {
    import com.soma.core.interfaces.IModel;
    import com.soma.core.model.Model;
    public class ModelExample extends Model implements IModel {
        override public function initialize():void {
            // called when the model has been registered to the framework
        }
        override public function dispose():void {
            // called when the model has been removed from the framework
        }
    }
}

2. the framework instance property has changed from soma to instance.

package  {
    import com.soma.core.wire.Wire;
    import com.soma.core.interfaces.IWire;
    public class WireExample extends Wire implements IWire {
        override protected function initialize():void {
            // called when the wire has been registered to the framework
            trace("my framework instance:", instance)
        }
        override protected function dispose():void {
            // called when the wire has been removed from the framework
        }
    }
}

3. a public setup method is available in your framework instance.

var app:ISoma = new Soma();
app.setup(stage, SomaInjector);

4. an initialize and start protected methods have been added in the Soma instance.

package  {
    import com.soma.core.Soma;
    import com.soma.core.interfaces.ISoma;
    import com.soma.core.di.SomaInjector;
    import flash.display.Stage;
    public class SomaApplication extends Soma implements ISoma {
        public function SomaApplication(stage:Stage) {
            super(stage, SomaInjector);
        }
        override protected function initialize():void {
            
        }
        override protected function registerCommands():void {
            
        }
        override protected function registerModels():void {
            
        }
        override protected function registerViews():void {
            
        }
        override protected function registerWires():void {
            
        }
        override protected function registerPlugins():void {
            
        }
        override protected function start():void {
            
        }
    }
}

SomaCore features

Here are some features that might makes you enjoy the framework.

Stage as single event dispatcher

SomaCore is using a single event dispatcher: the stage, and a system of event interception to handles its commands system. As the commands in SomaCore are normal built-in events with the property bubbles set to true, this makes you able to dispatch commands straight from a view removing potential layers (like mediators) to handles communications from the views to the framework.

This also makes you able to communicate between different modules (or swf files) as they all share the same stage.

Seamless commands and events integration

The commands in SomaCore are normal built-in events and the framework has a seamless integration with the flash event system. Seamless meaning that the built-in syntax is in use: dispatchEvent, addEventListener, and so on.

Register a command:

addCommand(MyEvent.DO_SOMETHING, MyCommand);

Dispatch a command from a framework elements (wires, commands, models, etc) or views:

dispatchEvent(new MyEvent(MyEvent.DO_SOMETHING));

Monitoring commands from wires, mediators, or models:

addEventListener(MyEvent.DO_SOMETHING, myEventHandler);

Commands monitoring

This capability is probably one of the most important to me. SomaCore makes you able to listen to commands from any wires and mediators, but also makes you able to stop the execution of any command (if the event is set as cancelable) using event.preventDefault().

package  {
    import com.soma.core.wire.Wire;
    import com.soma.core.interfaces.IWire;
    public class WireExample extends Wire implements IWire {
        override public function initialize():void {
            // called when the wire has been registered to the framework
            addEventListener(MyEvent.DO_SOMETHING, myEventHandler);
        }
        private function myEventHandler(event:MyEvent):void {
            // the command MyEvent.DO_SOMETHING has been dispatched
            // I can monitor it here (possible from any wires and mediators)
            // for some reasons, I decide to stop the execution of this command:
            event.preventDefault();
        }
        override public function dispose():void {
            // called when the wire has been removed from the framework
            removeEventListener(MyEvent.DO_SOMETHING, myEventHandler);
        }
    }
}

Easy way to map a mediator to a view

This is the workflow I reproduced from Robotlegs. It allows you to build you application, let’s say… complicated layouts, structure, tons of views, and so on. But at any point, if the framework needs to talk to a specific view, you can easily map a mediator to this view:

mediator.mapView(MyView, MyViewMediator);

For the other way around: a view needs to talk to the framework, mediators are not necessarily needed as you can dispatch commands straight from views in SomaCore. The commands are just normal events. The only requirement is that the view needs to be on the stage (added to a display list, after a ADDED_TO_STAGE event) in order for the stage to get the command.

Flexibility (injection, not injection, or both)

As the injection is optional in the framework, you are free to code the way you like, in the registry way like PureMVC way or in the injection way like Robotlegs, or even using both ways in the same time.

For some reasons, you might want to avoid injection, describeType, getElementByName, not comfortable yet with the concept, portability, optimal performance for games, etc. This is still possible with SomaCore.

Here are the built-in registry methods without injection:

addWire(MyWire.NAME, new MyWire());
getWire(MyWire.NAME);
addModel(MyModel.NAME, new MyModel());
getModel(MyModel.NAME);
addView(MY_SPRITE_NAME, new Sprite());
getView(MY_SPRITE_NAME);

With injection, you might do something like:

injector.mapSingleton(MyModel);
injector.createInstance(MyWire);
// MyWire injectee class
[Inject]
public var model:MyModel;

You can also use both:

var wire:MyWire = new MyWire();
injector.mapToInstance(MyWire, wire);
addWire(MyWire.NAME, wire);

Making you able to get the wire back this 2 ways:

[Inject]
public var wire:MyWire;
getWire(MyWire.NAME)

Plugins system

An easy way to add plugins to the framework, the SomaDebugger is the first one but I have plans to write others.

Debugger

The SomaDebugger especially built to work with SomaCore (even if it can be used without).

protected function registerPlugins():void {
    createPlugin(SomaDebugger, new SomaDebuggerVO(this, SomaDebugger.NAME_DEFAULT, getCommands(), true, false));
}

Lightweight

SomaCore is lightweight, here are the size compiled of the framework:

9.46 KB (9 693 bytes) – injector not enabled
14.83 KB (15 185 bytes) – injector enabled

Next steps

I’ll make new documents for code examples, best practices, and so on to help you get started.
Maybe a javascript version as a developer has made an amazing port of SomaCore.

If you’re looking for more information about the dependency injection part before I write documents, check the README file from the injection library: SwiftSuspenders.

Try SomaCore out, it is really easy to get started with. You’ll feel at home very quickly with its flexibility and well integrated command system with built-in events.

]]>
http://www.soundstep.com/blog/2011/02/07/somacore-as3-mvc-framework-v2-release/feed/ 4
SomaCore Twitter Search demo http://www.soundstep.com/blog/2010/10/26/somacore-twitter-search-demo/?utm_source=rss&utm_medium=rss&utm_campaign=somacore-twitter-search-demo http://www.soundstep.com/blog/2010/10/26/somacore-twitter-search-demo/#comments Tue, 26 Oct 2010 00:54:55 +0000 Romuald http://www.soundstep.com/blog/?p=546 Another SomaCore demo is available on Githug or on the SomaCore page.

This demo is relatively simple. Keywords are sent to the Twitter API using a command that is dispatched straight from the view as it is something possible with SomaCore. A command is nothing more than a flash built-in event. The views are able to dispatch commands without accessing to a mediator first and stay completely free of framework code.

A TwitterService dispatch a search result event after getting the data. The wire responsible of the main view is listening to the search result event and update the view.

The SearchWire class demonstrates that both commands and events can be listened to from any wire.

The control of the flow of the application is also very flexible, the SearchWire class could have stopped the search command for any reason using event.preventDefault() as the class is listening to the command (if the event is sent with a cancelable property set to true).

Any commands in SomaCore can be listened to in any wires, and can also be “default prevented”.

Twitter Search

SomaCore Twitter Search

View Demo
View Source
Download Source

Credits: Inspired by a great Flex Robotlegs demo by John Lindquist, using the AS3 API library Tweetr.

]]>
http://www.soundstep.com/blog/2010/10/26/somacore-twitter-search-demo/feed/ 1
SomaCore Hello World http://www.soundstep.com/blog/2010/10/24/somacore-hello-world/?utm_source=rss&utm_medium=rss&utm_campaign=somacore-hello-world http://www.soundstep.com/blog/2010/10/24/somacore-hello-world/#comments Sun, 24 Oct 2010 17:33:32 +0000 Romuald http://www.soundstep.com/blog/?p=542 I’ve added a very simple SomaCore Hello World demo.

The application creates a wire, a view and a model. The view dispatch a command to request a message, the command ask the data to the model, the model gets the data and dispatch an event to notify the framework, the wire catch the event and update the view with the message.

That’s all!

The demo is also available from the demo repository on Github:
http://github.com/soundstep/somacore_demos

Hello World

SomaCore Hello World

View Demo
View Source
Download Source

]]>
http://www.soundstep.com/blog/2010/10/24/somacore-hello-world/feed/ 1
SomaCore AS3 MVC framework on Github http://www.soundstep.com/blog/2010/10/18/somacore-as3-mcv-framework-on-github/?utm_source=rss&utm_medium=rss&utm_campaign=somacore-as3-mcv-framework-on-github http://www.soundstep.com/blog/2010/10/18/somacore-as3-mcv-framework-on-github/#comments Mon, 18 Oct 2010 20:14:13 +0000 Romuald http://www.soundstep.com/blog/?p=532 I’ve decided to put my framework SomaCore on Github.

SomaCore is a lightweight event-based MVC framework written in AS3 that provides a structure, models, views management and commands. Somacore can be used for Flash, Flex and AIR projects.

SomaCore does not use any external library and does not use dependency injection.

SomaCore is completely event-based and use a concept of wires to code in an efficient decoupled way.

Framework
http://github.com/soundstep/somacore_framework
Demos
http://github.com/soundstep/somacore_demos
Plugins
http://github.com/soundstep/somacore_plugins
Blog Page (with demos)
http://www.soundstep.com/blog/downloads/somacore/
Video tutorial
http://www.soundstep.com/blog/source/somacore/tutorials/getting-started/
Documentation
http://www.soundstep.com/blog/source/somacore/docs/

A very handy capability of the framework among others is the way you can monitor the flow of your application. SomaCore is using the the flash model to monitor commands and even intercept them in a way so that any actionscript developer will feel at home. Example in a wire class to listen and intercept a command:

// listen to a command
addEventListener(MyEvent.DO_SOMETHING, commandHandler);
// remove a listener
removeEventListener(MyEvent.DO_SOMETHING, commandHandler);

private function commandHandler(event:MyEvent):void {
	// intercept (if the event is cancelable)
	e.preventDefault();
}

Click here to see one of the demo code to get started.

Some other things to know about the framework

  • Commands are normal built-in Flash events with the bubbles property set to true.
  • Commands can be used in the views as they are not really framework code.
  • Parallel and sequence commands are built-in.
  • Wires are the glue of the frameworks elements (models, commands, views, wires) and can be used the way you wish, as proxy/mediators or managers.
  • Wires can manage one class or multiple classes.
  • Wires and commands access to all the framework elements (stage, framework instance, wires, models, views and commands).
  • Plugins can be created for the framework (such as the SomaDebugger plugin).
  • Powerful flow control using the built-in flash event model.

Here is how to get started with github:
http://help.github.com/



]]>
http://www.soundstep.com/blog/2010/10/18/somacore-as3-mcv-framework-on-github/feed/ 1
SomaUI update for Flex SDK 4 http://www.soundstep.com/blog/2010/09/29/somaui-update-for-flex-sdk-4/?utm_source=rss&utm_medium=rss&utm_campaign=somaui-update-for-flex-sdk-4 http://www.soundstep.com/blog/2010/09/29/somaui-update-for-flex-sdk-4/#comments Wed, 29 Sep 2010 09:10:10 +0000 Romuald http://www.soundstep.com/blog/?p=526 I’ve updated SomaUI, the AIR tool that generates the draft of a Flash website build with SomaMVC. Sorry for the late update but you can now use the generator with Flex 4 and target the Flash Player 10.1.

To avoid a confusion, SomaUI is an AIR tool that generates AS3 sources build with the AS3 MVC Framework SomaMVC.

SomaMVC has nothing to do with SomaCore, they are 2 different frameworks and don’t share the same goal.

While SomaMVC (which would entered in the same category as the Gaia Framework) is meant to be generated and rely on an XML File to describe and build its content, SomaCore is a lightweight MVC framework that doesn’t build anything for you and would entered in the same category as PureMVC.

I intend at some point to rebuild SomaMVC using SomaCore and unify these 2 projects.

You can find the new SomaUI version on this page or on the Google code project.

]]>
http://www.soundstep.com/blog/2010/09/29/somaui-update-for-flex-sdk-4/feed/ 16
SomaCore AS3 MVC Framework video tutorial http://www.soundstep.com/blog/2010/08/18/somacore-as3-mvc-framework-video-tutorials/?utm_source=rss&utm_medium=rss&utm_campaign=somacore-as3-mvc-framework-video-tutorials http://www.soundstep.com/blog/2010/08/18/somacore-as3-mvc-framework-video-tutorials/#comments Wed, 18 Aug 2010 14:32:44 +0000 Romuald http://www.soundstep.com/blog/?p=513 I’ve just uploaded a new video tutorial (48 min) for my lightweight AS3 MVC Framework SomaCore.

You can now get started with it. I explain how to create the framework instance, how to create a wire, create views, create commands and how to intercept them.

SomaCore Getting Started Video Tutorial

I hope you like it!

]]>
http://www.soundstep.com/blog/2010/08/18/somacore-as3-mvc-framework-video-tutorials/feed/ 4
Bringing life to an image http://www.soundstep.com/blog/2010/08/16/bringling-life-to-an-image/?utm_source=rss&utm_medium=rss&utm_campaign=bringling-life-to-an-image http://www.soundstep.com/blog/2010/08/16/bringling-life-to-an-image/#comments Mon, 16 Aug 2010 15:20:45 +0000 Romuald http://www.soundstep.com/blog/?p=503 Here is how to bring life to an image using the filter DisplacementMapFilter.

Click here to see the demo.

I got the idea from a video made by Chad Perkins (thanks Chad, you’re giving me a lot of inspiration!) where he is showing this effect in After Effects. My Flash nature pushed me to reproduced it with AS3. The result is great even if the After Effects version is slightly better, maybe the Flash version can be tweaked a bit more.

Here is how it works. I used this wonderful picture from my friend Ziemowit Maj :)

You also need a second picture that will describe the map of the filter using luminance. The foreground areas should be whiter than the background areas. I made this picture using Photoshop, the brush tools, and of course my proven drawing skills :D

I apply the DisplacementMapFilter on a BitmapData and I move the map position over time. It is not too complicated, but you can probably spend more time than me to draw the map correctly. Be careful not to make a distortion too big or it will look weird! Here is the code:

package {
	import caurina.transitions.Tweener;

	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.BitmapDataChannel;
	import flash.display.PixelSnapping;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.filters.DisplacementMapFilter;
	import flash.filters.DisplacementMapFilterMode;
	import flash.geom.Point;
	import flash.geom.Rectangle;

	/**
	 * <b>Author:</b> Romuald Quantin - <a href="http://www.soundstep.com/" target="_blank">www.soundstep.com</a><br />
	 * <b>Company:</b> Less Rain - <a href="http://www.lessrain.com/" target="_blank">www.lessrain.com</a><br />
	 * <b>Class version:</b> 1.0<br />
	 * <b>Actionscript version:</b> 3.0<br />
	 * <b>Copyright:</b> 
	 * <br />
	 * <b>Date:</b> Aug 16, 2010<br />
	 * <b>Usage:</b>
	 * @example
	 * <listing version="3.0"></listing>
	 */
	
	public class Main extends Sprite {
		
		[Embed(source="../assets/photo.jpg")]
		private var Photo:Class;
		[Embed(source="../assets/map.jpg")]
		private var Map:Class;
		
		private var _photo:Bitmap;
		private var _map:Bitmap;
		private var _point:Point;
		private var _photoDisplaced:Bitmap;
		private var _photoDisplacedData:BitmapData;
		private var _filter:DisplacementMapFilter;
		
		private var _range:Number = 17;

		//------------------------------------
		// private, protected properties
		//------------------------------------
		
		

		//------------------------------------
		// public properties
		//------------------------------------
		
		
		
		//------------------------------------
		// constructor
		//------------------------------------
		
		public function Main() {
			initialize();
		}

		//
		// PRIVATE, PROTECTED
		//________________________________________________________________________________________________
		
		private function initialize():void {
			// stage
			stage.frameRate = 41;
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			// photo
			_photo = new Photo();
			// photoDisplaced
			_photoDisplacedData = new BitmapData(_photo.width, _photo.height);
			_photoDisplaced = new Bitmap(_photoDisplacedData, PixelSnapping.AUTO, true);
			_photoDisplaced.scaleX = 1.05;
			_photoDisplaced.scaleY = 1.05;
			_photoDisplaced.x = (stage.stageWidth - _photo.width) >> 1;
			_photoDisplaced.y = (stage.stageHeight - _photo.height) >> 1;
			addChild(_photoDisplaced);
			// map
			_map = new Map();
			// point
			_point = new Point(-(_range), 0); 
			// enterframe
			addEventListener(Event.ENTER_FRAME, loop);
			// scroll motion
			move(_range);
		}

		private function move(target:Number):void {
			Tweener.addTween(_point, {time:2, x:target, transition:"linear", onComplete:move, onCompleteParams:[target*-1]});
		}

		private function loop(event:Event):void {
			_filter = new DisplacementMapFilter(
				_map.bitmapData,
				_point,
				BitmapDataChannel.RED,
				BitmapDataChannel.RED,
				_point.x,
				_point.y,
				DisplacementMapFilterMode.WRAP);
			_photoDisplacedData.applyFilter(_photo.bitmapData, _photoDisplacedData.rect, new Point(0,0), _filter);
			_photoDisplaced.bitmapData.draw(_photoDisplacedData, null, null, null, new Rectangle( _point.x, _point.y, _photo.width, _photo.height), true);
		}
		
		// PUBLIC
		//________________________________________________________________________________________________
		
		
		
	}
}
]]>
http://www.soundstep.com/blog/2010/08/16/bringling-life-to-an-image/feed/ 5
Super White Effect http://www.soundstep.com/blog/2010/08/13/super-white-effect/?utm_source=rss&utm_medium=rss&utm_campaign=super-white-effect http://www.soundstep.com/blog/2010/08/13/super-white-effect/#comments Fri, 13 Aug 2010 10:37:09 +0000 Romuald http://www.soundstep.com/blog/?p=481 Let’s start by a Flash demo here and a bit of explanation below.

While training myself to get better with After Effects, I stumble on a very interesting thing about color.

I was watching a Chad Perkins video about HDRI and color depth, more precisely, 32 bits rendering.

He showed what was happening with a Fast Blur effect (which is a 32 bits effect), and a white text in a 32 bits After Effects project.

Here is the rendering in a 8 bits project, just a normal blur.

And here is the result is you set the project to be 32 bits.

So what’s happening here? We can see there is some kind of halo, or glow, but there’s just a blur. I found the result pretty nice, a lot of luminance, and they call that “superwhite”. I didn’t find a lot of information, maybe there is another term for that. I found that very intriguing.

I’ve started to think how to get this effect in flash. The problem is Flash is only rendering 8 bits. I quote a details I found about Pixel Bender:

Although Pixel Bender images have 32-bits per channel, graphics in Flash Player and AIR only have 8-bits per channel. When a kernel is run, the input image data is converted to 32-bits per channel and then converted back to 8-bits per channel when kernel execution is complete.

But I wanted to have a try anyway and even if I don’t have the exact same effect in Flash, I found out that something is happening. Here is what I’ve done.

1. I put a white text on the stage (2 actually for other tests)
2. I’ve added a Blur effect (15 and 15)

Here is the result, again just a normal blur.

Then I’ve changed the alpha multiplier value (ColorTransform property) from 1 to 2.5, nothing happened obviously, alpha 1 or 2.5 is the same isn’t it? But here is the effect coming, if you add a bit of color, for example by setting the blue multiplier from 1 to 0.99, you then get a (fake?) superwhite. Here is the result:

Again, there’s no glow of anything, it is just a color and alpha effect. The amount of “superwhite” is changed with the value of the alpha multiplier, at least from 1 to… 20 or something.

Pretty cool huh? It is a fake superwhite because if I trust After Effect, it can happen only with 32 bits rendering, and I also don’t get exactly the same result as in After Effect, the color halo around is missing. But still, I found that quite intriguing. I’m not that good with colors, but I believe that what’s happening is the alpha channel that is multiplied by each color channel. Maybe someone will have a more in-depth explanation of what’s happening? I would be curious.

To check out the demo, click here.

You can click the button at the bottom to applied values. You can see the difference between the “Normal Blur” and the “Super White”.

]]>
http://www.soundstep.com/blog/2010/08/13/super-white-effect/feed/ 2
AS3 Layout Manager BaseUI v4 finally released http://www.soundstep.com/blog/2010/07/05/as3-layout-manager-baseui-v4-finally-released/?utm_source=rss&utm_medium=rss&utm_campaign=as3-layout-manager-baseui-v4-finally-released http://www.soundstep.com/blog/2010/07/05/as3-layout-manager-baseui-v4-finally-released/#comments Mon, 05 Jul 2010 13:40:54 +0000 Romuald http://www.soundstep.com/blog/?p=457 Finally, BaseUI version 4 is released!

If you don’t know what is BaseUI, it is a lightweight layout manager written in pure AS3 that is helping you to handle the position and size of your elements in a Flash layout (a site, an application and or whatever you can build with AS3).

More specifically, it is calculating positions and size when you resize your browser to update your elements. BaseUI makes you able to use layout properties (such as top, bottom, horizontalCenter, and so on) on any DisplayObject instance, much like you would do in a Flex environment.

You can use BaseUI with a single DisplayOBject instance, with tons of DisplayObject instances or in a more complex system with layout classes (such as canvas, horizontal and vertical box, and tile).

Before showing you how it works with some simple examples, I’d like to mention that BaseUI has been completely rebuilt from scratch. I did that because I wasn’t happy at all with a lot of things in the previous version. I wanted a very clean and effective library, with no hacks to make things works, which would make it very reliable.

The library is now contained in a com.soma.ui package, it will be part of the next Soma MVC Framework version.

I removed two things from the previous version:

- the width and height ElementUI properties, as it wasn’t making sense, you can now just set the width and height on your own DisplayObject instances.
- the percentage values for width and height, that is not possible anymore, I might add specific properties in the future if requested

Enough talk, you will get everything you need on the BaseUI page:

demo

source

documentation

Concept and the need of a reference

The important concept to understand is that you need to specify a reference to a BaseUI instance, or to the class that will handle the DisplayObject (which is the ElementUI class). A reference is what will be used to calculate size and position. For example, if you want your DisplayObject to be at 10 pixels from the bottom, you need to tell the library from what object. That’s what a reference is.

The reference can be any DisplayObjectContainer, such as the stage, a sprite, a layout, etc. Once you understand completely the need of having a reference, it is good to know that is doesn’t have to be a parent of your DisplayObject, it can be anything, anywhere. The only important things is that the reference must have a proper width and height, the stage or a layout class will always have it, but an empty Sprite instance won’t, the values will be 0.

All the following example will use the stage as a reference, but again, you can use anything you want.

Create a BaseUI instance

var baseUI:BaseUI = new BaseUI(stage);

Adding and removing DisplayObject instances

var baseUI:BaseUI = new BaseUI(stage);
var mySprite:Sprite = new Sprite();
var element:ElementUI = baseUI.add(mySprite);
element.refresh();
addChild(mySprite);
baseUI.remove(mySprite);
baseUI.removeAll();

Getting ElementUI instances

var element:ElementUI = baseUI.getElement(mySprite);
var arrayOfElements:Array = baseUI.getElements(); // note that this is a copy of the real array
var dictionaryOfElements:Dictionary = baseUI.getElementsAsDictionary(); // note that this is a copy of the real dictionary

Setting ElementUI properties

var element:ElementUI = baseUI.getElement(mySprite);
element.bottom = 10;
element.right = 10;
element.refresh();
var element:ElementUI = baseUI.getElement(mySprite);
element.horizontalCenter = 0;
element.verticalCenter = 0;
element.refresh();
var element:ElementUI = baseUI.getElement(mySprite);
element.ratio = ElementUI.RATIO_IN;
element.refresh();

Reset ElementUI properties

You can reset the Number properties of the ElementUI instance by using NaN or null for the others:

element.top = 10;
element.top = NaN;

element.ratio = ElementUI.RATIO_IN;
element.ratio = null; // or Element.RATIO_NONE

element.rect = new Rectangle(0, 0, 50, 50);
element.rect = null;

Or reset all of them:

element.reset();

Using ratio

The ratio is a kind of mode. You can use with a DisplayObject instance that keeps its proportion (Aspect Ratio) when it gets resized. Especially useful with pictures or backgrounds for example.

There is two ratio mode, a mode “in” and a mode “out”.

The mode “in” will always display all the surface of the DisplayObject instance in its reference, you might get empty area if the reference has a different ratio.
The mode “out” will always cover the surface of the reference, you might miss some part of the DisplayObject if the reference has a different ratio.

ElementUI aspect ratio

var element:ElementUI = baseUI.add(mySprite);
element.ratio = ElementUI.RATIO_IN;
element.alignX = ElementUI.ALIGN_RIGHT;
element.alignY = ElementUI.ALIGN_BOTTOM;

DisplayObject boundaries (optional)

When you use some ElementUI properties (such as right, bottom, horizontalCenter, etc), BaseUI will use the width and height of your DisplayObject instance to make its position calculation. For example, if you want the object to be at 10 pixels from the bottom, BaseUI needs to use the height.

This might prove difficult in some cases, for example if you have a specific “center point” or if the size of the DisplayObject instance changes all the time (if it is animated).

To solve this kind of problem, you can specify the boundaries of your DisplayObject to be used as a size in BaseUI instead of its real size. You can do that by using the “rect” and a Rectangle instance.

For example, if you draw a square in a sprite width 100 and height 100, but starting at x -50 and y -50 so it is centered. You can specify the boundaries like this:

var element:ElementUI = baseUI.add(myCenteredSprite);
element.rect = new Rectangle(-50, -50, 100, 100);

And you can remove it this way:

element.rect = null;

ElementUI Listeners

An ElementUI instance can dispatch three events, in this order:

1. EventUI.WILL_CALCULATE (dispatched before any calculation)
2. EventUI.WILL_UPDATE (dispatched after calculation and before updating the DisplayObject)
3. EventUI.UPDATED (dispatched after that the DisplayObject has been updated)

You can stop the ElementUI process in the EventUI.WILL_CALCULATE and EventUI.WILL_UPDATE handlers using “event.preventDefault()”.

var baseUI:BaseUI = new BaseUI(stage);
var element:ElementUI = baseUI.add(mySprite);
element.addEventListener(EventUI.WILL_CALCULATE, willCalculateHandler);
element.addEventListener(EventUI.WILL_UPDATE, willUpdateHandler);
element.addEventListener(EventUI.UPDATED, updatedHandler);
element.right = 10;
element.bottom = 10;
element.refresh();
addChild(mySprite);

private function willCalculateHandler(event:EventUI):void {
    //event.preventDefault(); // stop the process before the calculation
    trace(event.element); // trace the ElementUI instance
    trace(event.element.object); // trace the DisplayObject instance
    trace(event.element.baseUI); // trace the BaseUI instance
}

private function willUpdateHandler(event:EventUI):void {
    //event.preventDefault(); // stop the process before new properties are applied to the DisplayObject
    trace(event.element); // trace the ElementUI instance
    trace(event.element.object); // trace the DisplayObject instance
    trace(event.element.baseUI); // trace the BaseUI instance
    trace(event.properties); // trace the properties that will be applied to the DisplayObject
}

private function updatedHandler(event:EventUI):void {
    trace(event.element); // trace the ElementUI instance
    trace(event.element.object); // trace the DisplayObject instance
    trace(event.element.baseUI); // trace the BaseUI instance
    trace(event.properties); // trace the properties that have been applied to the DisplayObject
}

Refreshing an element

When you create an element, the position and size will be calculated when an Event.RESIZE occurs, which might not happen unless you resize your browser. For a performance matter, the calculation is not done when you change a property. To make the calculation and update your element, you might need to use the refresh method of your ElementUI instance (or BaseUI instance for all the ElementUI).

element.refresh();
baseUI.refresh();

Disposing and garbage collection

Both BaseUI and ElementUI classes have a dispose method to destroy variables and make the instance eligible for the garbage collection. The only one you have to care about is the BaseUI one, as the ElementUI will be properly destroyed when you use the remove and removeAll BaseUI methods.

baseUI.dispose();
baseUI = null;

Using layouts

Five layouts classes are built in BaseUI, all of them have ElementUI properties directly accessible.

- The LayoutUI class: the super class of all the other layouts classes, only a container, children stay un-touched
- The CanvasUI class: handle the children with ElementUI properties
- The HBoxUI class: display the children, one after the other, in a horizontal direction
- The VBoxUI class: display the children, one after the other, in a vertical direction
- The TileUI class: display the children, one after the other, and is in both direction and in a “multiline” way

All the layouts classes will have some common properties, such as background color, background transparency, rounded values, and if the content that goes outside of the boundaries of the layouts should be displayed or hidden.

You can also use layouts in other layouts, like adding canvas in tiles that are added in vertical boxes, etc. Be aware that we’re still using flash here, and even if the library is efficient, it might get slower if you add thousands of tiles in thousands of other tiles with thousands of bitmaps. Calculation are made and everything has limits, especially Flash. Beside that, I got good performance with the library, you will be fine unless you do crazy things :)

The LayoutUI class

The LayoutUI class extends the MovieClip class and is nothing else that a container that will always have a size (width and height), even if there’s nothing inside. Another difference with another built-in flash container (like Sprite, MovieClip, etc), is that the width and height will always be the one of the container regardless of what it contains.

For example, a layout instance (width 100 and height 100), that contains another DisplayObject (width 200 and height 200). The width and height values returned by a normal Sprite or MovieClip would be 200, while the layouts classes will return 100 (see getRealWidth and getRealHeight methods).

And that is true for all the layouts in the library, it is something to be aware of.

var layout:LayoutUI = new LayoutUI(stage, 400, 300);
layout.backgroundColor = 0xFF0000;
layout.backgroundAlpha = 0.2;
layout.bottom = 10;
layout.right = 10;
layout.refresh();
addChild(layout);

The CanvasUI class

The behavior of the CanvasUI class is very close to its super class (LayoutUI), with the different that an ElementUI instance is created (or removed) when you add children to its display list. Makes you able to handle the children of the CanvasUI instance with ElementUI properties.

var canvas:CanvasUI = new CanvasUI(stage, 400, 300);
canvas.backgroundColor = 0xFF0000;
canvas.backgroundAlpha = 0.2;
canvas.ratio = ElementUI.RATIO_IN;
addChild(canvas);

var sprite:Sprite = new Sprite();
sprite.graphics.beginFill(0xFF0000, .5);
sprite.graphics.drawRect(0, 0, 100, 100);

var element:ElementUI = canvas.add(sprite);
element.right = 10;
element.bottom = 10;

canvas.refresh();

The HBoxUI class (horizontal box)

The goal of the HBoxUI class is that it will take from the positioning of its children, and align them in an horizontal way and only one row. Properties such as children gap, children align and children padding are introduced.

var hbox:HBoxUI = new HBoxUI(stage, 400, 300);
hbox.backgroundColor = 0xFF0000;
hbox.backgroundAlpha = 0.2;
hbox.ratio = ElementUI.RATIO_IN;
hbox.childrenGap = new GapUI(5, 5);
hbox.childrenPadding = new PaddingUI(5, 5, 5, 5);
hbox.childrenAlign = HBoxUI.ALIGN_BOTTOM_RIGHT;
addChild(hbox);

for (var i:int=0; i&lt;8; ++i) {
var sprite:Sprite = new Sprite();
sprite.graphics.beginFill(0xFF0000, .5);
sprite.graphics.drawRect(0, 0, 100, 100);
hbox.addChild(sprite);
}

hbox.refresh();

The VBoxUI class (vertical box)

The VBoxUI class is much like the HBoxUI one, but you found out, in a vertical way.

var vbox:VBoxUI = new VBoxUI(stage, 400, 300);
vbox.backgroundColor = 0xFF0000;
vbox.backgroundAlpha = 0.2;
vbox.ratio = ElementUI.RATIO_IN;
vbox.childrenGap = new GapUI(5, 5);
vbox.childrenPadding = new PaddingUI(5, 5, 5, 5);
vbox.childrenAlign = VBoxUI.ALIGN_BOTTOM_RIGHT;
addChild(vbox);

for (var i:int=0; i&lt;8; ++i) {
var sprite:Sprite = new Sprite();
sprite.graphics.beginFill(0xFF0000, .5);
sprite.graphics.drawRect(0, 0, 100, 100);
vbox.addChild(sprite);
}

vbox.refresh();

The TileUI class

A kind of mix between the HBoxUI and VBoxUI classes, Flex developer are used to it as well. It will show the children in multiple lines, in any direction depending of the setting used.

var tile:TileUI = new TileUI(stage, 400, 300);
tile.backgroundColor = 0xFF0000;
tile.backgroundAlpha = 0.2;
tile.ratio = ElementUI.RATIO_IN;
tile.childrenGap = new GapUI(5, 5);
tile.childrenPadding = new PaddingUI(5, 5, 5, 5);
tile.childrenAlign = TileUI.ALIGN_BOTTOM_RIGHT;
tile.childrenDirection = TileUI.DIRECTION_HORIZONTAL;
addChild(tile);

for (var i:int=0; i&lt;16; ++i) {
var sprite:Sprite = new Sprite();
sprite.graphics.beginFill(0xFF0000, .5);
sprite.graphics.drawRect(0, 0, 100, 100);
tile.addChild(sprite);
}

tile.refresh();

I’m sure you will enjoy the library, it is very easy to use. Please send me some feedback :)

Happy development!

Romuald

]]>
http://www.soundstep.com/blog/2010/07/05/as3-layout-manager-baseui-v4-finally-released/feed/ 20
Badge AIR runtime installation bug with Firefox http://www.soundstep.com/blog/2010/06/29/badge-air-runtime-installation-bug-with-firefox/?utm_source=rss&utm_medium=rss&utm_campaign=badge-air-runtime-installation-bug-with-firefox http://www.soundstep.com/blog/2010/06/29/badge-air-runtime-installation-bug-with-firefox/#comments Tue, 29 Jun 2010 09:22:01 +0000 Romuald http://www.soundstep.com/blog/?p=448 I found out that there’s a bug with the badge used to install an AIR application with Firefox from version 3.6.4 until today’s version (3.6.6).

If you don’t have the AIR runtime installed a Adobe UI should pop up to show a progress bar and install the runtime. The trouble is that nothing happened at all after clicking on the YES button.

Badge AIR runtime installation

To test the bug, uninstall your AIR runtime and test the badge in this page.

The problems is very inconsistent, sometimes it works and sometimes it doesn’t.

I haven’t been able to find out what’s going on, so I reported the bug in this page.

Romu

]]>
http://www.soundstep.com/blog/2010/06/29/badge-air-runtime-installation-bug-with-firefox/feed/ 1
SomaCore update AS3 MVC Minimal Framework http://www.soundstep.com/blog/2010/05/14/somacore-update-as3-mvc-minimal-framework/?utm_source=rss&utm_medium=rss&utm_campaign=somacore-update-as3-mvc-minimal-framework http://www.soundstep.com/blog/2010/05/14/somacore-update-as3-mvc-minimal-framework/#comments Fri, 14 May 2010 13:48:12 +0000 Romuald http://www.soundstep.com/blog/?p=442 Hi everyone,

In case you didn’t notice that I released an new minimal AS3 MVC Framework some time ago, SomaCore is available on this page.

I call it minimal because it is very lightweight, yet powerful and non-intrusive. You don’t have much to learn if you’re used to MVC framework of any sort.

I made an update today, the second one in months because it won’t change a lot, the structure is there. All the sources and demo have been updated.

You can also replace any kind of previous use of the framework, the only feature added is a dispose method that will remove everything that has been created in the framework. Mostly useful in case you’re creating several instance of the framework, it will now be correctly garbage collected.

Once you’ve created a instance of the framework:

var app:ISoma = new Application(stage);

The only things you need to do is

app.dispose();
app = null;

Here is what it is doing to the components that have been added to the frameworks:

- all wires will be removed. On each wire, the dispose method will be called. You can overwrite this dispose method in your wires subclasses.

- all models will be removed. On each model, the dispose method will be called. You can overwrite this dispose method in your models subclasses.

- all commands will be removed

- all views will be removed but not removed from the display list, that’s your job. On each view, a dispose method will be called if it exists. You can create this dispose method in your views:

public function dispose():void {
	// dispose objects, graphics and events listeners
}

It important to say that all the components will be removed from the framework, but that’s your matter to properly destroyed what you’re creating in order to be garbage collected.

A quick info for my plans because I’ve silent lately (busy).

I’ll make a BaseUI release in the next weeks, a completely rebuilt and optimized version 4. It is ready but I need to finish the documentation.

After that I plan to make more examples and screen cast about the SomaCore Framework.

I just wanted to say that I’m rarely happy about what I’m producing, because I like things to be… perfect. Of course, perfection can’t be reached, but that is pushing me to create the better code I can, at my level.

I’m now using SomaCore in some projects. One is a relatively complicated AIR Modular Application for children. And for once, I’m very happy with what I’ve done with SomaCore. It has been a great help really, I should say that it saves me a lot of troubles when changes happened because I built the application how I wanted it, without “framework-fight” and as much flexible as I could. It just made me more responsive to any kind of changes in the project.

For this reason, I’ll try to push SomaCore further by making more demos, videos, examples, documentation, wires concept and so on.

I still have plans to create a new version of the first automated framework Soma MVC, and its source generator, based on SomaCore.

Happy development!

]]>
http://www.soundstep.com/blog/2010/05/14/somacore-update-as3-mvc-minimal-framework/feed/ 3
Firefox 3.6 Mac bug with MouseEvent http://www.soundstep.com/blog/2010/03/02/firefox-3-6-mac-bug-with-mouseevent/?utm_source=rss&utm_medium=rss&utm_campaign=firefox-3-6-mac-bug-with-mouseevent http://www.soundstep.com/blog/2010/03/02/firefox-3-6-mac-bug-with-mouseevent/#comments Tue, 02 Mar 2010 12:36:27 +0000 Romuald http://www.soundstep.com/blog/?p=433 Firefox 3.6 introduced a very annoying bug, and only on a Mac.

If you’re using somewhere a MouseEvent.ROLL_OUT or MouseEvent.MOUSE_OUT, this event will fired even if you only click on a object without leave the object with the mouse.

Example there

The select box in the middle of the page doesn’t work because a roll out event is fired when you click on it.

I didn’t try yet to find a fix with MOUSE_UP and MOUSE_DOWN, but the problem is, all the existing sites that are using those events might be broken…

I believe Firefox is, or not firing the right event, or removing and putting back the flash so it loses the focus, meaning roll out is fired… A friend told me that the same things happen with java applet, didn’t verify it yet.

Bug report

To test it, paste this as a document class:

package com.soundstep.baseui.demo {
	import flash.events.MouseEvent;
	import flash.display.Sprite;
	public class Main extends Sprite {
		public function Main() {
		var s:Sprite = new Sprite();
		s.graphics.beginFill(0xFF0000);
		s.graphics.drawRect(0, 0, 100, 100);
		s.addEventListener(MouseEvent.MOUSE_OUT, test);
		addChild(s);
		}
		private function test(e:MouseEvent):void {
			trace("ok");
		}
	}
}

Click on the square and you’ll see that the MOUSE_OUT is fired…

I hope they’ll fix soon or I’ll have to find a hack and change everything that is live.

Romu

]]>
http://www.soundstep.com/blog/2010/03/02/firefox-3-6-mac-bug-with-mouseevent/feed/ 18
AS3 garbage collection monitor http://www.soundstep.com/blog/2010/01/18/as3-garbage-collection-monitor/?utm_source=rss&utm_medium=rss&utm_campaign=as3-garbage-collection-monitor http://www.soundstep.com/blog/2010/01/18/as3-garbage-collection-monitor/#comments Mon, 18 Jan 2010 11:26:50 +0000 Romuald http://www.soundstep.com/blog/?p=423 I needed to watch objects to know if they were properly garbage collected or not, so I’ve added a GC Monitor in the SomaCore Debugger. It is pretty easy to use and I think very useful if you start to care about the memory that the Flash Player is using and global performance.

Demo Flash (garbage collection monitor)

SomaCore Flash AS3 Demo - Garbage Collection

View Demo
View Source
Download Source

The concept to use it is to “register” an object, such as a Sprite or anything, with a name.

The first step is to create the debugger. If you’re using the framework SomaCore, you’ll find some demo by clicking here.
And if you want to use the debugger without using SomaCore, here is a snippet to create the application and debugger:

package {
	import flash.display.Sprite;
	import com.soma.core.Soma;
	import com.soma.core.interfaces.ISoma;
	import com.soma.debugger.SomaDebugger;
	import com.soma.debugger.vo.SomaDebuggerVO;
	import com.soma.debugger.events.SomaDebuggerEvent;
	public class Main extends Sprite {
		function Main() {
			// create soma application
			var app:ISoma = new Soma(stage);
			// create debugger options
			var vo:SomaDebuggerVO = new SomaDebuggerVO(app, SomaDebugger.NAME_DEFAULT, [], true, false);
			// create debugger
			var debugger:SomaDebugger = app.createPlugin(SomaDebugger, vo) as SomaDebugger;
			// use debugger
			debug("Hello Debugger");
			debug(this);
			debug(app);
		}
		private function debug(obj:Object):void {
			// use app.dispatchEvent() from a class that is not in the display list
			dispatchEvent(new SomaDebuggerEvent(SomaDebuggerEvent.PRINT, obj));
			// events available:
			// SomaDebuggerEvent.SHOW_DEBUGGER;
			// SomaDebuggerEvent.CLEAR;
			// SomaDebuggerEvent.PRINT;
			// SomaDebuggerEvent.HIDE_DEBUGGER;
			// SomaDebuggerEvent.MOVE_TO_TOP;
		}
	}
}

Register an object to watch it:

dispatchEvent(new SomaDebuggerGCEvent(SomaDebuggerGCEvent.ADD_WATCHER, "my sprite", mySprite));

You can dispatch this event from anywhere in an DisplayObject in the display list (Sprite, MovieClip, etc), from the document class, the stage or the SomaCore instance.

In the debugger window, there is a “garbage collection bar” where you can click to see the registered objects, they can be either “retained” or “released”. A released object means it has been garbage collected and doesn’t exist anymore. The memory used by this object will be free to use.

A “force” button will trigger the garbage collection, it will call System.gc() twice with a small interval. This should only works in a Flash Player Debugger version, but useful for debugging.

Here is a list of events you can use for the garbage collection monitor:

SomaDebuggerGCEvent.REMOVE_ALL_WATCHERS
SomaDebuggerGCEvent.REMOVE_WATCHER // pass the name of he object as parameter
SomaDebuggerGCEvent.ADD_WATCHER // pass the name of the objects and the object itself as parameter
SomaDebuggerGCEvent.FORCE_GC

Note: by default SomaDebugger is now using a weak reference to the objects that you want to inspect. You can turn off this option to inspect everything in the debugger, but the objects will never be released, making the garbage collection monitor useless.

Here is how to force the inspection of any objects:

SomaDebugger.WEAK_REFERENCE = false;

Any feedback appreciated!

Romu

]]>
http://www.soundstep.com/blog/2010/01/18/as3-garbage-collection-monitor/feed/ 3
SomaCore Debugger update http://www.soundstep.com/blog/2009/11/27/somacore-debugger-update/?utm_source=rss&utm_medium=rss&utm_campaign=somacore-debugger-update http://www.soundstep.com/blog/2009/11/27/somacore-debugger-update/#comments Fri, 27 Nov 2009 14:35:25 +0000 Romuald http://www.soundstep.com/blog/?p=417 I’ve updated the debugger used in SomaCore. You can know click on everything to parse the objects and I’ve added a FPS + Memory meter. I’ll continue to improve the debugger with my needs, next step might be a Garbage Collection monitor.

Click here to see the debugger in action.

Tips: if you close the debugger, type “debug” to get it back.

Here is a little bit of code in case you want to want to use the debugger without using the SomaCore Framework.

package {
	
	import flash.display.Sprite;
	import com.soma.core.Soma;
	import com.soma.core.interfaces.ISoma;
	import com.soma.debugger.SomaDebugger;
	import com.soma.debugger.vo.SomaDebuggerVO;
	import com.soma.debugger.events.SomaDebuggerEvent;
	
	public class Main extends Sprite {
		
		function Main() {
			// create soma application
			var app:ISoma = new Soma(stage);
			// create debugger options
			var vo:SomaDebuggerVO = new SomaDebuggerVO(app, SomaDebugger.NAME_DEFAULT, [], true, false);
			// create debugger
			var debugger:SomaDebugger = app.createPlugin(SomaDebugger, vo) as SomaDebugger;
			// use debugger
			debug("Hello Debugger");
			debug(this);
			debug(app);
		}
		
		private function debug(obj:Object):void {
			// use app.dispatchEvent() from a class that is not in the display list
			dispatchEvent(new SomaDebuggerEvent(SomaDebuggerEvent.PRINT, obj));
			// events available:
			// SomaDebuggerEvent.SHOW_DEBUGGER;
			// SomaDebuggerEvent.CLEAR;
			// SomaDebuggerEvent.PRINT;
			// SomaDebuggerEvent.HIDE_DEBUGGER;
			// SomaDebuggerEvent.MOVE_TO_TOP;
		}
		
	}
	
}
]]>
http://www.soundstep.com/blog/2009/11/27/somacore-debugger-update/feed/ 0
SomaCore AS3 MVC Framework event-based http://www.soundstep.com/blog/2009/11/20/somacore-as3-mvc-framework-event-based/?utm_source=rss&utm_medium=rss&utm_campaign=somacore-as3-mvc-framework-event-based http://www.soundstep.com/blog/2009/11/20/somacore-as3-mvc-framework-event-based/#comments Fri, 20 Nov 2009 12:06:30 +0000 Romuald http://www.soundstep.com/blog/?p=410 Following my previous post about MVC design philosophy and an AS3 MVC Framework that suit my needs and expectations, I’ve started using SomaCore in a relatively complicated AIR modular application, and I’m really enjoying it.

I made some small changes to the code and I thought it would be a good idea to provide you the sources. SomaCore was a missing tool in my actionscript work.

I’ve started to feel the power of the native Flash event system (even if criticized!) by being able to listen to commands independently of the commands itself (and what the command is doing), or being able to “preventDefault” any command, or to monitor very easily everything that is going on in the framework. The wires have been a good help to keep my code very clean without tons of classes, while keeping my models and views completely free of framework code.

I also found out some kind of hidden capabilities I didn’t think about while making it. One of them is an “easy module communication”, so easy that, you have absolutely nothing to do to enable it. When I say module, it could be another SomaCore instance, a loaded SWF, another SomaCore instance in a loaded SWF, and so on. But I’ll give more details later.

You can now find the (updated) SomaCore resources on the SomaCore Page.

Special thanks to Henry for his testing and feedback!

Feel free to use the sources and give me some feedback. I’ll try later to give more explanation on how to use SomaCore and the Wires, new demos and tutorials.

Romu

]]>
http://www.soundstep.com/blog/2009/11/20/somacore-as3-mvc-framework-event-based/feed/ 1
MVC design philosophy http://www.soundstep.com/blog/2009/10/06/mvc-design-philosophy/?utm_source=rss&utm_medium=rss&utm_campaign=mvc-design-philosophy http://www.soundstep.com/blog/2009/10/06/mvc-design-philosophy/#comments Tue, 06 Oct 2009 11:05:14 +0000 Romuald http://www.soundstep.com/blog/?p=371 Hi Everyone,

This is not exactly a “Soma release”, but I would like to share with you my last work so we can talk about: A new AS3 MVC Framework with its own design philosophy.

Why another AS3 MVC Framework?

I’ve been working with different Frameworks in the last years, such as PureMVC, Cairngorm and Mate for the well-known. I’ve always knew that I would write my own “MVC design philosophy”, without taking big words, because I would have some needs that existing Frameworks wouldn’t completely fill.

That’s what happened. I needed a Flash lightweight framework, not DI, event based, working both for Flex or Pure AS3. The biggest inspirations have been PureMVC for the proxies and mediators, and Mate for their event system.

I’ll be starting an interesting AIR Modular app and I needed something that will easily allow me to have views and models free of Framework code, without creating tons of files or use any injection. I also wanted a Framework very flexible, so I can use it even for smaller project, being sure I’ll be effective in terms of development time.

Free the views and models

First problem, free the views and models of Framework code (loose-coupling). It seems there’s a wave of DI Framework but… I’ve never really been into DI Framework, because they tend to control the way you’re doing things. If you stick to it, it is fine, but I’ve always felt more freedom with framework like PureMVC. I might be wrong, it is just an opinion and not even entirely true as I didn’t felt that problem with Mate.

So, to solve this problem, I used the events Mate concept. A basic Flash Events that has a bubble property set to true can become Commands when they are mapped to a Command class. Those events can be intercepted, stopped and processed by the Framework (execute Commands). The great thing is, views and models are free of Framework code and can use Commands because they are just Flash native events.

Wires introduction

Second problem, was to “update” data or states in the views and models. PureMVC is using proxies and mediators and I like that approach. However, you end up by creating tons of files for the sake of loose-coupling pratice. So I’ve created something that I call “Wire”. Now software engineers or PureMVC adept might say that what I’m doing is wrong. I have no idea, I’m no computer scientist, I do what I feel and I’m sharing it with you.

Wire are classes that can contain Framework code and they will be the links between the models, the views, the Framework and… whatever you like. Wire can be proxies, they can be mediators, but they can also be both and handle more than one view or model.

Basically, they are as free as you want them to be. They can even be optional if you don’t care about good practice or loose-coupling programming. Wires have easy access to all the framework, models, commands and views. They can register create models, views, register commands or create other wires.

Update from comment:

So far I saw two ways to inject/update information into views without having framework code inside:

- Dependency Injection
- Buffer classes (such as Mediators and Proxies in PureMVC for the analogy, respectively for Views and Models). I mean “buffer” by classes that act as steward of other classes.

I’ve chosen the second way, and I’ve created a “buffer” class that I called a Wire.

Wires are completely free classes. I won’t tell you how to use them (because that’s up to you) but I can tell what you can do with them. Wires can be used to update views and models but they are not tight to anything. They are not even only tight to one tier. To create a wire class you extend Wire and implements IWire, and here are the roles they can take:

- a wire can act as steward of a view (such as Mediator in PureMVC)
- a wire can act as steward of a model (such as Proxies in PureMVC)
- a wire can manage both a view and a model
- a wire can manage multiple views and/or multiple models
- a wire can be considered as a subdivision of the framework and create its own views, create its own models and register its own commands. Much like you would create a specific package to hold a specific matter.

When I build something, I always try to keep a good level of freedom to handle problems how I like but most importantly, how they should be. If you like to have the framework telling you (or forcing you) how to build your application, fair enough but you won’t like it.

The wires are the free elements that will let you built your application the way you like or the way it is required to be. They can make your application rigid, segmented, flexible or centralized, depending of the role you are going to give them. They are so free that I believe remove (or lesser) what I call “Framework Fight”.

Let’s take an example, the Cafe TownSend below.

There are 2 wires: the LoginWire and the Employee Wire. They both register their own commands to control their views and models.

The Login Wire only handles a Login View.

The EmployeeWire handles 2 views: a list of employees and an employee details. But also 1 model (the employees data), all of them only related to employees matter.

SomaCore

I temporarily named this framework SomaCore and it has nothing to do with the Framework I released on this blog (Soma). However, this framework might become the core of what will be Soma v3.

I post this code hoping to get your feedback or point of view of what might be great or wrong in this framework.

Here is a diagram:

SomaCore MVC Diagram


Click here to download a zip file containing the Framework sources code (classes and SWC).

And here are some demos. I made a Flex Cafe TownSend demo and a pure AS3 demo.

SomaCore Flex Cafe TownSend SomaCore Flash AS3 Demo
View Demo
View Source
Download Source
View Demo
View Source
Download Source

This is a very early state, this Framework has not been used yet in a real project beside the demos above. Have a look and please comment what you feel is good or wrong in the core concept.

Romu

]]>
http://www.soundstep.com/blog/2009/10/06/mvc-design-philosophy/feed/ 11
Soma MVC v2.0.2 minor update http://www.soundstep.com/blog/2009/09/07/soma-mvc-v2-0-2-minor-update/?utm_source=rss&utm_medium=rss&utm_campaign=soma-mvc-v2-0-2-minor-update http://www.soundstep.com/blog/2009/09/07/soma-mvc-v2-0-2-minor-update/#comments Mon, 07 Sep 2009 12:55:07 +0000 Romuald http://www.soundstep.com/blog/?p=362 A minor update for Soma and SomaUI, mostly bug fixes. The source are available available on the SomaUI page.

SomaUI v2.0.2

-bug fixed: page selection in the page tab wasn’t working properly
-bug fixed: layout tab and layout properties wasn’t correctly updating the XML
-bug fixed: Flash Player wasn’t correctly updated in Page Settings tab when opening a project
-update: new page auto-name renamed to Page1, Page2, etc
-update: Soma v2.0.2

Soma v2.0.2

-bug fixed: layout with a background alpha 0 wasn’t displayed

Note: to update sources already exported with a version 2.0.x, just grab the com.soma package (or SWC) and replace, or in SomaUI, in the export tab and under Soma Framework, select “overwrite all”.

]]>
http://www.soundstep.com/blog/2009/09/07/soma-mvc-v2-0-2-minor-update/feed/ 3
Soma MVC MovieClip Page Mode video tutorial http://www.soundstep.com/blog/2009/09/02/soma-mvc-movieclip-page-mode-video-tutorial/?utm_source=rss&utm_medium=rss&utm_campaign=soma-mvc-movieclip-page-mode-video-tutorial http://www.soundstep.com/blog/2009/09/02/soma-mvc-movieclip-page-mode-video-tutorial/#comments Wed, 02 Sep 2009 15:11:23 +0000 Romuald http://www.soundstep.com/blog/?p=356 Here is a new Video Tutorial about the MovieClip Page Mode in Soma, it might remind you the Flash Catalyst workflow. This mode is only for Flash IDE user. I’m creating a designed site in few minutes by importing Photohop Files in MovieClip that wll be managed by Soma.

The PageManager will instantiate MovieClip instead or pure actionscript class. It is a very useful mode if you want to build your site with the Flash IDE with a minimum of code, and very quickly.

SomaUI MovieClip Page Mode Video Tutorial


]]>
http://www.soundstep.com/blog/2009/09/02/soma-mvc-movieclip-page-mode-video-tutorial/feed/ 0
Soma MVC minor update 2.0.1 http://www.soundstep.com/blog/2009/09/01/soma-mvc-minor-update-2-0-1/?utm_source=rss&utm_medium=rss&utm_campaign=soma-mvc-minor-update-2-0-1 http://www.soundstep.com/blog/2009/09/01/soma-mvc-minor-update-2-0-1/#comments Tue, 01 Sep 2009 17:57:42 +0000 Romuald http://www.soundstep.com/blog/?p=353 New version available (v2.0.1), small bugs solved with the Page Manager.

Here is how I will update Soma and SomaUI. There is 3 numbers in the version number:

1. the first is a major update, where possibly everything change, probably not usable with previous sources.
2. the second is a medium update, the structure might slightly change and it might need refinement to match with a previous medium version.
3. the third is a minor update, totally transparent for the user, you can update the framework and the generator without breaking what you have already done.

So this is a minor update, meaning it doesn’t change anything for what you are doing. You can just update the framework and the generator. SVN and source (zip) have been updated, you can get them in the SomaUI page.

Romu

]]>
http://www.soundstep.com/blog/2009/09/01/soma-mvc-minor-update-2-0-1/feed/ 5
Soma MVC tips and tutorials http://www.soundstep.com/blog/2009/08/24/soma-mvc-tips-and-tutorials/?utm_source=rss&utm_medium=rss&utm_campaign=soma-mvc-tips-and-tutorials http://www.soundstep.com/blog/2009/08/24/soma-mvc-tips-and-tutorials/#comments Mon, 24 Aug 2009 14:39:56 +0000 Romuald http://www.soundstep.com/blog/?p=347 Beside having Soma Protest to learn how Soma MVC is working, I will add in the future (to the Google code wiki) some tutorials and tips that will help you during your development.

I will also “centralized” any Video Tutorial I will make in this wiki.

First one today, how to control the page flow in Soma.

Romu

]]>
http://www.soundstep.com/blog/2009/08/24/soma-mvc-tips-and-tutorials/feed/ 6
Soma v2 AS3 MVC Framework released! http://www.soundstep.com/blog/2009/08/21/soma-v2-as3-mvc-framework-released/?utm_source=rss&utm_medium=rss&utm_campaign=soma-v2-as3-mvc-framework-released http://www.soundstep.com/blog/2009/08/21/soma-v2-as3-mvc-framework-released/#comments Fri, 21 Aug 2009 13:13:45 +0000 Romuald http://www.soundstep.com/blog/?p=334 I finally release the version 2 of the framework Soma MVC and its source code generator SomaUI. It has been a long run since the last release, months of works and nights spent to make your life easier! But here we are.

Firstly, I’d like to thanks Less Rain. Not only they are amazing and skilled people, but they also have been very supportive to me. Thanks again!

Soma v2 have been already used for many projects and it has been a joy to work with it. I first built this framework for myself, as a tool. I wouldn’t release it if I didn’t think that Soma could help you with a minimum of learning and “framework fights”, and I hope… with a lot of fun!

If the concept, compare to the version 2, is similar, a lot have been improved and added.

First a SomaUI demo!

SomaUI is a tool that is generate source code, a Flash site based on Soma.

SomaUI Getting Started Video Tutorial


Soma, the AS3 MVC Framework

The framework is more consistent and is simpler to use, ease of use has always been my goal. And for this, the transitions proxies don’t exist anymore and the template system has been removed.

Paradoxically, the framework is a lot more powerful and stronger that the version 1, especially in terms of automation.

What’s new?

Some libraries have been added and they can also be used without the framework, such as a loader library SomaLoader (already released as a standalone) to manage loading processes, queue management and loading display.

I also built a video player “SomaVideoPlayer” (not released yet as a standalone), very easy to use and with a powerful skin system to alter built-in controls or create new ones.

I also built an assets system to dynamically create images, video, or anything, positioned them, describe layout behaviors, and a lot more… and just from an XML file, no code required! The process is amazingly quick. For example to create a video player on screen, it takes not more than a single XML node. This assets system can be used to dynamically create your own assets (custom display objects) at run-time from an XML.

There a new special “page mode movieclip” that works with the Flash IDE, that can make simple development of a whole site a matter of minutes (depending on what you want you want to reach). This will be my next tutorial.

I’ve never wanted Soma to impose rules to a developer, at least not too much. A big point in Soma (and SomaUI), it is never handling physical files or assets files. You can still embed images, fonts or anything the way you like (with SWC, in Flash IDE, metadata tags, or whatever). I did break some encapsulation rules though, and it was to reach a very high level of freedom and flexibility.

SomaUI, the source code generator

The first version has always been in beta and was more a kind of “concept”.

The version 2 is going a lot further and its purpose is:

- building an XML file required in order to make Soma working
- exporting deploy files (html, css, etc)
- exporting source (actinscript, Flash file, XML, etc)
- compile with the Flex SDK

If you know how to build the XML file that is required by Soma, you can avoid to use SomaUI. So the whole point of SomaUI is helping you building that XML and create files to spare time.

Through screens you can set up your project, configure it, create pages, create assets, backgrounds, and export!

Finally

I hope you will have nice time with those tools. To download the sources, get the documentation, samples, explanation or more help… everything is starting on the SomaUI Page.

Any feedback (good or bad) are always welcomed!

Happy development!

Romu

]]>
http://www.soundstep.com/blog/2009/08/21/soma-v2-as3-mvc-framework-released/feed/ 13
SomaUI v2 small update http://www.soundstep.com/blog/2009/08/18/somaui-v2-small-update/?utm_source=rss&utm_medium=rss&utm_campaign=somaui-v2-small-update http://www.soundstep.com/blog/2009/08/18/somaui-v2-small-update/#comments Tue, 18 Aug 2009 07:22:45 +0000 Romuald http://www.soundstep.com/blog/?p=318 Hi,

Small update about my work on SomaUI v2 and Soma v2. I can say that:

- Soma v2 is done (the as3 framework)
- Soma Documentation is done (asdoc)
- Soma Protest is ready (site demo)
- SomaUI v2 is done (the source generator, AIR-java application)
- SomaUI Demo is done (a SomaUI project demo)

It has been a huge amount of work, especially with the generator, I can’t count the nights I passed on it. But we’re almost there. I’ve already used the framework and generator on many projects here at Less Rain.

So good news, the framework is (I think and hope) very enjoyable. I always had fun with it and it made my life far easier on common tasks.

The last step before I release the v2 is a screencast to get you started with the new generator. I should be able to do that this week.

Thanks for following me!

Romu

]]>
http://www.soundstep.com/blog/2009/08/18/somaui-v2-small-update/feed/ 0
Mac and SVN to merge folder http://www.soundstep.com/blog/2009/07/21/mac-and-svn-to-merge-folder/?utm_source=rss&utm_medium=rss&utm_campaign=mac-and-svn-to-merge-folder http://www.soundstep.com/blog/2009/07/21/mac-and-svn-to-merge-folder/#comments Tue, 21 Jul 2009 13:50:14 +0000 Romuald http://www.soundstep.com/blog/?p=310 This is not Flash related but I had to post something about as I’m really annoyed. I’m now working all the time on Mac, I believe I couldn’t bear anymore spywares and other Windows annoyances.

Anyway, I’m almost fine on the Mac but there’s one thing I can’t understand is that they didn’t implement a “merge folders” capability when you copy and paste something. On a Mac, if you copy a source folder containing folder and files to paste it to a target folder, if you choose replace, the content of the folders will disappear and be replaced by the source. meaning if you have files on the folder target that doesn’t exist in the source folder, they will just disappear. On Windows, it asks you if you want to overwrite or not because anyway, it is always going to merge.

I could use the Unix command ditto and the terminal, but wow, how is it possible something as simple as that is not implemented? People from windows will know what I’m talking about. Actually, there’s a lot people complaining and tons of app that does the job.

So I tried to find a simple and quick app, which actually wasn’t really easy as they all want to merge the content of the files. I don’t want to do that at all, that’s more a code matter to merge the content of a file. I found 2 or 3 that does the job but kind of heavy for such a common task, I want to do that as quickly as I could do on windows.

The best I found is: Merge Folders

You select the source, the target, if you want to overwrite and that’s it. Perfect? Almost…

My problem was mostly related to SVN, copy file from local copy to other local copy, or whatever. This app would have been perfect if I could choose “include hidden files, yes or not”.

So I need first to export a package not to have the hidden folders .svn and then merge my exported copy to a repo or local copy. That’s ok but again, on a Mac, things are not that easy when it comes to development, maybe I passed too much time on Windows? I’m sorry but Windows and tortoiseSVN is kind of wonderful compare to a what I get on the Mac. So as I can’t make an export with the “SVN-finder-integrated” (scplugin), I use mostly SynchroSVN, great but still a lot slower than on Windows. When you have some delicate actions to make like merging branches, tortoiseSVN on Windows is really great.

I’m sure some of you have the same problem, what are you solutions? What do you use? Is there something simple and quick that I missed?

Romu

]]>
http://www.soundstep.com/blog/2009/07/21/mac-and-svn-to-merge-folder/feed/ 0
Make Flash Switcher working http://www.soundstep.com/blog/2009/07/17/make-flash-switcher-working/?utm_source=rss&utm_medium=rss&utm_campaign=make-flash-switcher-working http://www.soundstep.com/blog/2009/07/17/make-flash-switcher-working/#comments Fri, 17 Jul 2009 14:28:49 +0000 Romuald http://www.soundstep.com/blog/?p=303 Flash Switcher Firefox extension allows you to easily switch from one flash player version to another. It works great but unfortunately only after some tweaking. Flash Switcher still works with the last Firefox version, at the time I’m talking (Firefox 3.5).

There are already some posts about Vista and Flash Switcher, to solve some bugs that are related to folders permissions. I had some trouble to find the folders on Mac and as I still see people asking how to make it work, I’m going to tell you the paths and what to do on Vista and Mac.

First you can install Flash Switcher there:
http://www.sephiroth.it/firefox/flash_switcher/

Restart Firefox.

You need to change the permissions on some folders before you start using it. On the following folders, right click + get info on Mac and right click + properties on windows, and give full access. Your paths will be different, those ones contains my user name and generated Firefox profile string, but you’ll find out.

Vista

Plugin path:
C:\Windows\System32\Macromed

Firefox Plugin path:
C:\Users\romuald\AppData\Roaming\Mozilla\Firefox\Profiles\squnf11y.default\extensions\flash_switcher@sephiroth.it\plugins\win

Mac

Plugin path:
/Library/Internet Plug-Ins

Firefox Plugin path:
/Users/romuald/Library/Application Support/Firefox/Profiles/9ly9womf.default/extensions/flash_switcher@sephiroth.it/plugins/mac

Once done, click on the Flash Switcher icon in the status bar. Save your current Flash Player (or it will be removed the first time you use it, I don’t know why), by selecting it and click on “save as”.

Now it should just work, at least that’s what I’ve done this morning and it is working for me. You should get a javascript alert saying “ok, the new plugin has been installed”, or something similar. And if you still get an error, it is probably still the paths permissions, try to re-apply the permissions (I had to do it twice, don’t ask me why).

To get more players in the list, just uninstall and install other versions, or you can get the plugins files straight from there:

Archive Flash Players

Hope it helps.

]]>
http://www.soundstep.com/blog/2009/07/17/make-flash-switcher-working/feed/ 4
SomaUI v2 Beta Testing http://www.soundstep.com/blog/2009/07/08/somaui-v2-beta-testing/?utm_source=rss&utm_medium=rss&utm_campaign=somaui-v2-beta-testing http://www.soundstep.com/blog/2009/07/08/somaui-v2-beta-testing/#comments Wed, 08 Jul 2009 10:00:44 +0000 Romuald http://www.soundstep.com/blog/?p=297 Hi everyone,

As I’m close to release Soma v2 (AS3 MVC Framework) and SomaUI v2 (application to generate actionscript source code and deploy files based on Soma), I’d like to share an earlier version with some beta-testers who are interested to help me debug both the framework and the generator.

Mac and Windows available, I didn’t have time to make the Linux one. The generator is in a beta state but the framework and code generated are pretty stable as it has been already used many times in real projects.

I will not send it to everyone, or I will not have time to manage this properly (depending of the feedback), sorry about that.

You can drop me an email from this blog to ask me. Please, participate only to give me a hand and by helping me with your feedback and bug reports. I can provide support, depending of my time if you wish to use it for real projects. For the curious, just be patient, the release will available very soon :)

Thanks and, happy development!

]]>
http://www.soundstep.com/blog/2009/07/08/somaui-v2-beta-testing/feed/ 3
Hexosearch Actionscript search engine http://www.soundstep.com/blog/2009/07/06/hexosearch-actionscript-search-engine/?utm_source=rss&utm_medium=rss&utm_campaign=hexosearch-actionscript-search-engine http://www.soundstep.com/blog/2009/07/06/hexosearch-actionscript-search-engine/#comments Mon, 06 Jul 2009 10:24:23 +0000 Romuald http://www.soundstep.com/blog/?p=289 I found a nice actionscript search engine:

http://www.hexosearch.com/

It looks like a beta for now, but I like the concept. Basically you can register your blog so the search engine will easily find actionscript talks. You can even choose AS2, AS3 or Flex.

Worth trying :)

By the way, if some of you want a bit more (direct) news about my work, and probably Soma, I’m trying to tweet a bit!

http://twitter.com/soundstep

]]>
http://www.soundstep.com/blog/2009/07/06/hexosearch-actionscript-search-engine/feed/ 1
Neoderma release and Soma v2 progress http://www.soundstep.com/blog/2009/04/06/neoderma-release-and-soma-v2-progress/?utm_source=rss&utm_medium=rss&utm_campaign=neoderma-release-and-soma-v2-progress http://www.soundstep.com/blog/2009/04/06/neoderma-release-and-soma-v2-progress/#comments Mon, 06 Apr 2009 16:32:31 +0000 Romuald http://www.soundstep.com/blog/?p=284 Hi everyone,

I’ve been working on the version 2 of Soma and its generator. I’m pretty busy so I didn’t post for a while, but I’m going to give you some news today.

We’ve just released at Less Rain the Neoderma international website. It is not a “crazy-kick-your-ass-3D-website”, nothing is complicated there, but it has a very nice and clean “look and feel” and a complex CMS where everything can be changed (structure, content, animations, language, and so on). The content is pretty big so it is a complicated site in terms of data. Neoderma is a multi-language site (translations are not done yet but will appear in the future).

I’m talking about Neoderma here because it has fully been built with Soma v1 and the framework has been a great help (and also a joy) to keep a strong and solid structure. Soma has been very effective in responding to (almost) whatever I needed, and because Soma is very flexible, it worked perfectly with a site where everything can be  changed via a CMS.

I’m not allowed to give any source code of course, but I can advice Soma users if they wonder how to do something. Soma v1 is lacking documentation and examples but this will be greatly improved in the v2.

About the v2 I’m working on, it is in a pretty good shape. The framework is almost done. I’ll make the full documentation before releasing it. It is easier to use and more consistent, not at all completely different though. Templates disappeared as we could do without them, a real node parser has been built to dynamically instantiate classes (custom or built-in) straight from the XML, a new page mode appears for Flash IDE users making you able to build something in no time, SomaLoader implemented, and more features we’ll see at the release.

SomaUI, the generator is done at 80% and will make you able to build the XML Site definition with a friendly user interface, as well as exporting and compile the sources created. You’ll even be able to build something very quickly from SomaUI, without knowing the framework and opening a documentation.

Thanks for your patience, it is on its way :)

Hopefully, I’ll post more if I can get a bit more time!

Happy development.

]]>
http://www.soundstep.com/blog/2009/04/06/neoderma-release-and-soma-v2-progress/feed/ 5
SomaLoader release http://www.soundstep.com/blog/2009/03/03/somaloader-release/?utm_source=rss&utm_medium=rss&utm_campaign=somaloader-release http://www.soundstep.com/blog/2009/03/03/somaloader-release/#comments Tue, 03 Mar 2009 01:49:30 +0000 Romuald http://www.soundstep.com/blog/?p=277 SomaLoader is a lightweight loading manager written in AS3. You can load many types such as images, swf, xml, text, xml, css, fonts in a swf, mp3, variables and binary data. Items can be added, removed and changed in position from the queue even while loading.

SomaLoader provides a simple and unique interface for massive loading, to listen to events and access to data.

SomaLoader has some specific features such as targeting before loading, easy loading progress display, caching system and binary loading for “silent loading”.

I’m working on the version 2 of Soma (AS3 MVC Flash Framework) and SomaLoader will be part of the framework, this is a pre-release as it can be used as a standalone.

More information on the SomaLoader page.

]]>
http://www.soundstep.com/blog/2009/03/03/somaloader-release/feed/ 0
Soma 1.6.4 and urlfriendly http://www.soundstep.com/blog/2009/01/27/soma-164-and-urlfriendly/?utm_source=rss&utm_medium=rss&utm_campaign=soma-164-and-urlfriendly http://www.soundstep.com/blog/2009/01/27/soma-164-and-urlfriendly/#comments Tue, 27 Jan 2009 16:33:22 +0000 Romuald http://www.soundstep.com/blog/?p=260 I’ve made a minor update that brings us to Soma 1.6.4 and SomaUI 1.0.6, you can get the new versions from the SomaUI page.

In the XML Site Definition, the attribute urlfriendly in a page node builds the URL for the deep-linking and in previous version this attribute had to be unique through the XML. It is no longer the case, you can now have identical parts in the URL.

This wasn’t possible before:

/#/page1/common-urlfriendly/

/#/page2/common-urlfriendly/

/#/page3/common-urlfriendly/

Only the PageManager changed, you can update your sources from the previous version without problem.

And by the way, from now, I’ll be release only minor update for Soma and SomaUI as I’m working on the v2 for both of them.

]]>
http://www.soundstep.com/blog/2009/01/27/soma-164-and-urlfriendly/feed/ 3