Skip navigation

Category Archives: Uncategorized

I’m now hosting my own blog at http://lukesh.com — This wordpress.com blog is officially deprecated.

I’ve been intentionally learning how to develop using Sproutcore for about a month now, so I’ve been more aware of the buzz about it, and I have to say that most things I read are missing the point about the value promise of Sproutcore.

The impetus behind my learning is that it is an application development framework for the HTML5/JavaScript platform, versus the Flash Platform that I’m used to developing for. The key here is that it is an application development framework. It is not another DOM access library, widget set, or MVC, and it shouldn’t even be compared to them. It’s not a “Flash-killer“. It’s not even a “Flex-killer” per se, although in my mind it is an alternative in part.

Flash is just a display technology. Flex boils down to just a widget set and bindings library. Intrinsically, Flex lacks a good application development pattern. That’s partially why Seppuku is a viable alternative to maintaining the average Flex app built by someone else. There’s no built-in MVC, or unit testing strategy or IoC methodology.

I realize that Adobe’s building in support for FlexUnit4 in Flash Builder 4 / Flex 4 SDK which is wonderful. Michael Labriola et al are doing a fantastic work there that is critical for the Flex project. These necessessities have been the mother of invention with MVC frameworks like Cairgorm, Mate, FlightFramework, and HydraMVC for MVC. Lack of IoC has also inspired Mate, and Flight, as well as the excellent Swiz framework, and the DI part of HydraFramework. And, don’t even get me started on server interaction complexities.

I say all that to illustrate that the Flex development stack really fundamentally consists of Flash -> Flex (widget set, bindings, themes) -> MVC -> IoC -> Unit Testing -> Development environment (IDE, code tools, code gen) -> Support (documentation, community). I feel like that stack is essential to consistently producing good applications built using the Flex SDK, and I think other companies realize this too.

If you look at what Microsoft is doing with Silverlight, they are positioning themselves to own that stack, and not only that, but they have the advantage of not being the first in that they can fix all the things that Adobe has done wrong. It all looks really promising except for a few things, which I’ll discuss in a moment.

Let me begin by saying that contrary to popular belief, I don’t necessarily enjoy being married to Adobe and the Flash Platform. I really do embrace the ideology of an open, standards-driven web. The market has helped drive Flex because you really could deliver a richer “desktop-like experience” on the web, spawning the RIA buzzword. HTML5 and browser implementations are undeniably slower to progress than a company-owned platform like Adobe has. It was the evolution of Flash as a vector graphics rendering plugin for graphically fun and interesting content that facilitated it’s insane propagation, not it’s ability to draw text inputs and combo boxes.

Ok, back to Silverlight. First bad thing: you are locked into Microsoft. That’s a bad thing, just like being locked into Adobe is a bad thing. However, I would argue that specifically for web development, being locked into Microsoft is better than being locked into Adobe. They own the whole stack, and if you drink the MS Kool-Aid you never have to really leave Visual Studio. Also, Silverlight plays much nicer than Flash with the HTML DOM, which means you as the developer have a greater level of flexibility in how you implement Silverlight as part of your solution.

Second bad thing: you have to work in Windows. It’s not just that I really dislike working in Windows; it’s more that I dislike that I’m forced to. At least Adobe provides Windows, Mac, and (kinda) Linux support for their IDE and Player. I sincerely believe that a web development platform should be OS agnostic.

Ok, wasn’t I writing about Sproutcore? Oh yeah. I’m already way past the tl;dr threshold for most people, but there’s a lot to blab about discuss. All that background was to make the point that an application development platform is more than the display layer and widgets, and even goes beyond the language you’re using. I beleive the fundamentals of an application development platform are:

  1. A prescriptive methodology: You or other developers need to be able to look at your source and not have to figure out how you’ve interpreted solutions to basic problems.
  2. Consistent development workflow: You or other developers should be able to intrinsically understand how your application can be scaled or altered as it evolves.
  3. MVC methodology: You or other developers should be able to intrinsically understand how your application separates concerns.
  4. Data access consistency: You or other developers should strive to unify data access methodology so that applications are easier to debug regardless of server technology.
  5. Unit tests: The application platform should provide a way of structuring unit tests for all aspects of the platform, including establishing Fixtures for data access logic.
  6. Build tools: Scaffolding, configuration, etc. tools should minimize “monkey work” and give the developer the ability to go from thought to implementation as quickly as possible.
  7. Good documentation: it goes without saying that docs should ideally help the new learner ramp up, and serve as a reference to experienced devs.
  8. Helpful community: I could write an entire post about this one based on my experiences in the Ruby community, but it is critical to have mentors and people who are willing to accept that fact that you are an annoying little n00b and require hand holding like a little child as you ask questions and sound like an idiot for a few days. Also, when you are off the teet and developing like a madman, you need intelligent people to bounce ideas off of. If you go from n00b to the smartest one in the community in a week, you’ve got problems with the community.

Granted, I’ve only been evaluating Sproutcore as I’ve been finding time around regular work, holidays, and spending time with my family, but I’m definitely over the 0 – 1 level of proficiency and actually starting to build things and ask real questions, and I can say that so far, when I need to do something, it feels like Sproutcore has provided for it in a very logical way. All my personal requirements for a good framework are accounted for. I’m not going to port HydraFramework to Sproutcore, because it’s unnecessary in Sproutcore; it already has a wonderful MVC and bindings methodology. I’m not scrounging for a unit testing methodology; it also has been provided for. Skinning / theming couldn’t be easier. Build tools are great. I can develop on my 486 running Ubuntu if I wanted to. There’s always someone idling in #sproutcore who is helpful. The docs are great. It may not have achieved feature parity with the Flex development stack yet but it shows tremendous promise.

So again, the question isn’t Sproutcore vs. jQuery. In fact, you can (and probably will) use jQuery if you develop Sproutcore apps. The question really isn’t even Sproutcore vs. Flash vs. Silverlight, but it’s so easy to frame it up like that. The point of Sproutcore is that it provides the beginnings of an end-to-end application development strategy in HTML5 that competes with Adobe’s Flash Platform (Flash + Flex + Cairngorm + FlexUnit) and Silverlight’s presentation layer and tools.

There are a few additional things I want to point out. I’m not saying it’s the only way by any means. You can write an open standards desktop experience using any recipe you’d like. Maybe my point is that I feel that choosing an application development platform is more than the sum of its parts.

I have also been evaluating Cappuccino by 280 North. For all intents and purposes, it competes directly with Sproutcore, and I’m not blatantly ignoring it. However, my #1 hangup with it is the Objective-J abstraction. I understand using Objective-C for Cocoa development. I understand JavaScript for web development. But to me, I see not much more than a syntactical advantage for Cocoa developers as the point of Objective-J. For me, it makes more sense to stick with JavaScript as JavaScript. I’m going to try to keep my eye on it, especially the Atlas project.

I’d definitely be interested in hearing your experiences with Sproutcore or your own recipe for RIA *choke* or Desktop Experience type applications. I’ll also try to post more details as I continue evaluating.

HydraMVC has become a part of HydraFramework. The source is on http://github.com/lukesh and you can read more about the framework at http://hydraframework.com. More later!

I think I have a decent workaround to this old bug, where you run into formatting problems if you want to use a custom borderSkin on a Panel or Alert. (I especially wanted to use a skin created with Degrafa.) In addition, I wanted to set up something where I could create a generic Panel skin to use throughout my application, but also use the skin for Alerts without it messing up the title bar. Even though it’s over a year old, this post is still getting remarks about the layout bug. 

Admittedly, my workaround is a total hack. However, that’s why it’s called a workaround. I’ve been using it without issues, and wanted to make it public. Click here to download a Flex project archive with the solution files. This is what it looks like:

 

Custom Panel / Alert Skin

Custom Panel / Alert Skin

Just a quick observation of how important it is to me that in order to achieve and maintain focus, I need to reduce my “sphere of awareness” as small as possible. I picture an imaginary bubble around me, and whether I like it or not, my mind is background-monitoring everything within that bubble. The larger the bubble is, the easier it is to be distracted as things vie for my attention, and the harder it is for me to zone in to what I’m doing as I’m constantly polling for updates from everything in that sphere. That’s why we all wear headphones.

The problem arises when switching between managerial and development tasks. A managerial mindset requires the constant awareness of the entire machine, and the ability to triage all kinds of interruptions. You get into that mindset, and you begin to habitually and frequently poll everything in that sphere. You begin to listen in to conversations, feel the need to check on status of things, re-check your to-do list for anything you might have missed. Then, when you detect that precious 10-minute pocket of time between fires, you have to get something done. You take of your managerial hat, and you put on your developer hat.

You’re refactoring the hell out of some code, the body flayed open with guts hanging all over the place, but you are constantly looking over your shoulder, expecting someone to ping you about something on your to-do list that is pending. I live in this place.

Twitter has become a once-a-day blog read, so no more Twitteriffic throwing Growl notes all over the place. IM closed. Yammer closed. Email closed. I decide that enough is enough and I have to get something done today. After a solid hour or two, I finally shake off the itching feeling of imminent interruption and get into a groove. I can’t shake it anymore, and I open my email, only to find that people are frustrated with me as they’ve been attempting to get my attention for hours. My sphere of awareness explodes, and now I’m putting out fires and feeling guilty for working.

My sphere is tired of expanding and contracting. I have to figure out a better way of doing this.

A few people here have only recently switched to Mac as their primary computing platform. People generally find most things to be easier and more pleasant to use on a Mac. However, there is frequently a point of confusion for a Windows user when they try to find their “network drives,” or mapped network shares that they had previously configured to automatically remap on login, and were displayed in “My Computer.”

This describes the methodology of mounting network drives in Finder so that they are easily accessible in normal workflow, minimizing the steps required to access those drives, and removing the need to remember if they have been mounted or not.

1. Mount the drives using Finder.

  • Click on Finder, and select “Connect to Server…” from the “Go” menu.
  • Connect to our primary data server “carbon” by entering “smb://carbon” in the “Server Address:” field and click “Connect.” Once Finder has connected, you will be able to select from the following shares: backups, documents, media, proposals, resources, temp, townhall, users, vault.
  • Repeat this process for all the drives you would like to be accessible. Repeat this process as well for other servers as well. Our primary web server, “nitrogen” (use “smb://nitrogen” in the “Server Address:” field), will give you access to the “wwwroot” share.

2. Create a “Network” folder in your user folder.
  • Open a finder window, and click on your username in the sidebar.
  • Control+Click (or right click) in the window and select “New Folder.”
  • Name the new folder “Network”

3. Create shortcuts to the network drives in the Network folder.

  • You should see all your network drives on your desktop. If you don’t, click your desktop, select “Preferences…” from the “Finder” menu, and ensure that “Connected servers” is checked.
  • With the newly created “Network” folder, as well as your desktop visible, select all your network drives and drag them to the “Network” folder. Your cursor should add a small curved arrow when you drag them over the folder.

4. Create shortcuts to the “Network” folder.

  • Drag the “Network” folder into your sidebar, preferably as the first item, above your username.
  • Drag the “Network” folder into your dock, next to the Trash Can.

5. Integrating into your workflow.

  • Remember that you don’t have to remember to “mount the drives” when you need them. Treat them as if they are already mounted and just use them. OSX will mount them as needed.
  • When saving a file from within an application, click the “Network” folder in the sidebar, and then choose the drive you want to open. If it’s mounted, it will be immediately accessible. If it’s not, there will be a slight pause as OSX mounts the drive.
  • When you are opening file, or need to browse the network drive, it is often easiest to click the “Network” shortcut in the dock and select the drive you want to explore. Again, if it’s mounted, it will appear instantly. If it’s not, it will mount automatically. You will see it appear on your desktop.
  • If you find the desktop icons of your network drives distracting, you can hide them altogether, guiding you to always use the dock or the sidebar as your first access to the drives. To do this, click your desktop, select “Preferences…” from the “Finder” menu, and uncheck “Connected servers.”

Keep in mind that this was written for OSX 10.5 Leopard, however this process will also work in 10.4 although the names of certain things may be slightly different. Also, this is just what I’ve found to be a streamlined workflow; it’s not necessarily “the way” ™ to do it. I’d love to hear what others do.

We’ve been using this for a while now, and I’d just like to tell the internets that Charles is awesome. I would definitely recommend it.

This is a flexified, simplified version of John Grden’s earth demo. Create a new Flex project called “GreatWhiteExperiment1″, add the GreatWhite source path, and paste the code:  

package {
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	
	import org.papervision3d.cameras.FreeCamera3D;
	import org.papervision3d.lights.PointLight3D;
	import org.papervision3d.materials.ColorMaterial;
	import org.papervision3d.materials.shadematerials.FlatShadeMaterial;
	import org.papervision3d.materials.shaders.FlatShader;
	import org.papervision3d.materials.special.ParticleMaterial;
	import org.papervision3d.objects.primitives.Sphere;
	import org.papervision3d.objects.special.ParticleField;
	import org.papervision3d.render.BasicRenderEngine;
	import org.papervision3d.scenes.Scene3D;
	import org.papervision3d.view.Viewport3D;
	
	[SWF(backgroundColor="0x000000", width="900", height="600", frameRate="30")]
	public class GreatWhiteExperiment1 extends Sprite
	{
		private var renderer:BasicRenderEngine
		private var scene:Scene3D;
		private var camera:FreeCamera3D;
		private var viewport:Viewport3D;
		
		// 3d Objects
		private var pointLight:PointLight3D;
		private var earth:Sphere;
		
		public function GreatWhiteExperiment1()
		{
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;

			renderer = new BasicRenderEngine();
			scene = new Scene3D();
			camera = new FreeCamera3D();
			viewport  = new Viewport3D(0, 0, true, false);
			addChild(viewport);
			 
			camera.z = -350;
			camera.focus = 1100;
			camera.zoom = 1;
			
			pointLight = new PointLight3D(true);
			scene.addChild(pointLight);
			pointLight.moveUp(350);
			pointLight.moveRight(350);
			
			var earthMaterial:ColorMaterial = new ColorMaterial(0x00CCCC);
			
			//var earthBumpMaterial:MovieAssetMaterial = new MovieAssetMaterial("earthMapBump2");
			//phong only, no bump
			//var earthShader:PhongShader = new PhongShader(pointLight, 0xFFFFFF,0x404040,20);
			//phong with bump
			
			// create shader
			//var earthShader:PhongShader = new PhongShader(pointLight, 0xFFFFFF, 0x303030, 20, null, null);
			var earthShader:FlatShader = new FlatShader(pointLight, 0xFFFFFF, 0);
			
			// combine shader with original material, for a shaded material
			//var earthShadedMaterial:ShadedMaterial = new ShadedMaterial(earthMaterial, earthShader);
			var earthShadedMaterial:FlatShadeMaterial = new FlatShadeMaterial(pointLight, 0xFFFFFF, 0);
			
			// add to sphere
			earth = new Sphere(earthShadedMaterial, 250, 12, 12);

			scene.addChild(earth);

			createStars();
			 
			stage.addEventListener(Event.ENTER_FRAME, handleEnterFrame);
		}
		
		private function handleEnterFrame(e:Event):void
		{
			earth.yaw(-.5);
			camera.x=camera.y=camera.z=0;
			camera.yaw(.5);
			camera.moveBackward(1000);
			
			renderer.renderScene(scene, camera, viewport);
		}
		
		private function createStars():void
		{
			//Create a new particle material;
			var pm:ParticleMaterial = new ParticleMaterial(0xFFFFFF,1);
			
			//Create a new particlefield.
			var particleField:ParticleField = new ParticleField(pm, 2000, 5000, 5000, 5000);
			scene.addChild(particleField);
		}
	}
}
Follow

Get every new post delivered to your Inbox.