<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title>virtual.olympus.blog</title>
	<link href="http://www.virtual-olympus.com/atom.xml" rel="self"/>
	<link href="http://www.virtual-olympus.com"/>
	<updated>2017-01-19T04:16:04.089Z</updated>
	<id>http://www.virtual-olympus.com</id>
	<author>
		<name>Benjamin Gavin</name>
		<email>ben@virtual-olympus.com</email>
	</author>

    
    <entry>
      <title>That Conference 2016 - How'd it go?</title>
      <link href="http://www.virtual-olympus.com/posts/2017/01/that-conference-2016-follow-up/"/>
      <updated>2017-01-18T00:00:00.000Z</updated>
      <id>/posts/2017/01/that-conference-2016-follow-up/</id>
      <content type="html"><![CDATA[<div><h2 id="what-d-we-do-">What&apos;d we do?</h2>
<p>Last year was my first opportunity to officially present alongside my eldest son Christopher.  Christopher had been
helping with the Lab / Camp the previous two years, and he was interested in taking more responsibility as a co-presenter.  Together we presented 
<a href="https://www.thatconference.com/sessions/session/10346">That Robotics / IoT Lab 2016</a> both Tuesday and Wednesday afternoons.  Building 
on the previous two years experience, we were able to bring some of the same materials and created a number of new activities for the geeklings
to enjoy.</p>
<p><img src="http://www.virtual-olympus.com/posts/2017/01/that-conference-2016-follow-up/BenAndChristopher.jpg" alt="Ben &amp; Christopher"></p>
<p>Among the projects the Geekling attendees enjoyed were:</p>
<ul>
<li>VexIQ Mini-Kits (Racer, Cycle, Duck Explorer and Plane)</li>
<li>VexIQ Sensor Lab (utilizing Robot-C Graphical / Classic)</li>
<li>Drivable / Programmable VexIQ Omni-Vehicle</li>
<li>That Pi Hunt (utilizing Raspberry Pi / Bluetooth Beacons)</li>
<li>Arduino Bot</li>
<li>ESP8266 Sensor Projects (via Feather Huzzah and Sparkfun ThingDev)</li>
</ul>
<p>I&apos;ll talk a bit about the various projects, what went well, what didn&apos;t and what we&apos;d likely improve if we have the chance
to do it all again this year.</p>
<h2 id="vexiq-kits-sensor-lab">VexIQ Kits / Sensor Lab</h2>
<p>In 2016, we had 4 kits the kids could put together, complete with a printed booklet (think LEGO instructions).  We
had an opportunity to re-use a couple of the kits from 2015, and Christopher and Zac (my younger son) came up with a couple new options. We 
had a few of each kit, and as in previous years, these were a major hit.  The kit creation process allowed both
Christopher and Zac to experience the engineering design process, from basic line drawings and brainstorming, through
design review, initial construction and digitization (via SnapCAD and Adobe InDesign).  Once the instructions first
draft was completed, the boys assembled the bots to prove it actually worked and correct any part / direction flaws / gaps.</p>
<p>The 4 kits we brought to camp were the Racer, Cycle, Duck Explorer and Plane.  The kits were (mostly) easy to follow and the 
Geeklings could work with their parents (or other Geeklings) to complete assembly.  The first 3 kits (Racer, Cycle and Duck)
were all relatively similar in complexity, and could be completed in less than 45 minutes.  I felt that the plane kit was a 
bit of an experiment.  The model was more advanced than any of the previous models we had tried, and required a significant 
amount of time to assemble [average was about 2 hours].  I was impressed that 3 different groups completely finished
the project, and 1 more got most of the way through before we ran out of time.</p>
<p><img src="http://www.virtual-olympus.com/posts/2017/01/that-conference-2016-follow-up/VexKits.png" alt="Vex Kits"> <img src="http://www.virtual-olympus.com/posts/2017/01/that-conference-2016-follow-up/PlaneComplete.jpg" alt="Completed Plane"></p>
<p>The sensor lab was also a big hit.  We had assembled a number of &apos;sensor plates&apos;, essentially a 12x12 Vex IQ Plate, with a
brain, controller, motor and all the sensor types we had available (Color, Distance, Bumper Switch, Gyro, Touch LED).  We had a 
&apos;wall of laptops&apos; that attendees could use to program the sensor array, and some pre-built instructions and construction paper
cards to work with the color sensor and Touch LED.  There were numerous geeklings who went above and beyond, working with 
Graphical RobotC to manipulate the sensor input and do lots of cool things.  One enterprising family reprogrammed our drivable 
omni-bot to do a little dance and flash the attached TouchLEDs to make a &apos;disco bot&apos;.  It was truly awesome to see them dig in 
and take a simple exercise to a whole new level.</p>
<p><img src="http://www.virtual-olympus.com/posts/2017/01/that-conference-2016-follow-up/SensorKit.jpg" alt="Sensor Kits"></p>
<h2 id="robot-virtual-worlds-robot-c">Robot Virtual Worlds / Robot-C</h2>
<p>We again leveraged the free &apos;Summer of Learning&apos; (SoL) licenses that are made available via the 
<a href="https://www.cs2n.org/summer-of-learning/">Computer Science Student Network (CS2N)</a>.  Unfortunately, the 2016 licenses
ONLY covered virtual robot programming through Robot Virtual Worlds, which limited attendees to only a few laptops that
could run &apos;full&apos; Robot-C and interact with the sensor kits above.  Previous SoL licenses had included both the Robot Virtual Worlds
and standard Robot-C.  I&apos;m hoping that this years entry brings that capability back, as we don&apos;t have funding resources
to purchase full licenses for all our camp laptops.  </p>
<p>The RVW license allowed the geeklings to utilize the Robot-C IDE to walk
through some exercises using a virtual robot in pre-defined &apos;worlds&apos;, solving problems and learning a bit about 
programming robots along the way.  The nice part about RVW is that it allows experimentation without needing a physical robot 
to work with.  Last year the geeklings again adventured in &apos;Expedition Atlantis&apos; (a math problem solving game), explored Palm Island 
(which we visited a bit in 2014) and delved into the Ruins of Atlantis.</p>
<p><a href="http://www.robotvirtualworlds.com"><img src="http://www.virtual-olympus.com/posts/2017/01/that-conference-2016-follow-up/RobotVirtualWorlds.png" alt="RVW Ruins of Atlantis"></a></p>
<h2 id="arduino-bot-and-esp8266-sensor-projects">Arduino Bot and ESP8266 Sensor Projects</h2>
<p>Entirely new this year were a number of &apos;Internet of Things&apos; projects that the geeklings could try.  The
wall of laptops included copies of <a href="https://www.arduino.cc/en/Main/Software">Arduino Studio</a>.  A number of
folks had loaned us some sensor and bot hardware, and we wanted to give the kids a chance to explore both
hardware and software simultaneously, along with providing some projects that might interest the older geeklings.</p>
<p><a href="http://www.accolade-systems.com/index.html">Accolade Systems</a> loaned us a couple of their Arduino-based
robots to use for the camp, and we borrowed a number of sensors from <a href="http://www.skylinetechnologies.com">Skyline</a>
that worked with the ESP8266 boards that we had on hand (a Feather Huzzah from Adafruit and a ThingDev from SparkFun).</p>
<p><img src="http://www.virtual-olympus.com/posts/2017/01/that-conference-2016-follow-up/mechatronics2.png" alt="Robotic Shield"></p>
<p>On a whole, these projects were underutilized, primarily because Christopher and I just ran out of
time to put together guided samples.  If we have a chance this year, I think we&apos;ll plan to bring more prepared
examples to help lower the barrier of entry on these projects.  The geeklings seemed to really enjoy
putting together hardware and seeing it &apos;come to life&apos;, so I think a bit more guidance here could have made
for a very engaging experience for all.</p>
<h2 id="that-pi-hunt">That Pi Hunt</h2>
<p>The final project that the kids could participate in was one I had hoped would be a main
draws of the IoT Lab.  I had spent some time putting together a Windows IoT Core application which could
read Bluetooth LE Beacons, light up some LEDs and &apos;capture&apos; the beacons by wandering throughout
the conference center.  We had brought some <a href="https://store.gimbal.com/collections/beacons/products/s10">Gimbal Series 10 Beacons</a>
and That Conference loaned us some <a href="https://store.kontakt.io/our-products/27-bluetooth-beacon.html">Kontakt.io Smart Beacons</a>
which we distributed around the Lab room and in a couple of the conference hallways.  Kontakt.io
was also generous enough to donate some goodies for the kids to take with them!</p>
<p><img src="http://www.virtual-olympus.com/posts/2017/01/that-conference-2016-follow-up/ThatPiHuntBeacon.jpg" alt="Beacon Sample"> <img src="http://www.virtual-olympus.com/posts/2017/01/that-conference-2016-follow-up/ThatPiHuntHW.jpg" alt="That Pi Hunt Hardware"></p>
<p>I plan to do a larger write-up / lessons learned on That Pi Hunt, but the end result was a bit
of a mixed bag.  I think a combination of environmental, software and hardware problems
made the process a bit of a frustration for most who tried it out.  However, we learned a lot, both
about how exciting playing around with hardware can be, and different approaches we&apos;d take if
we had to do it all over again.  The kids loved to see the simple hardware they had assembled
work with the test application that we developed, and it proved a great way to ensure that they
had wired everything correctly.</p>
<p>I plan to continue developing the app to hopefully squash the bugs, and add some additional
sensor options to the mix.  All the code is available in our <a href="https://github.com/bengavin/that-conference-2016/tree/pihunt">GitHub Repo</a>
in the &apos;pihunt&apos; branch.  Feel free to pull it down and play around with it.</p>
<h2 id="in-closing">In Closing</h2>
<p><a href="https://www.thatconference.com">That Conference 2016</a> and specifically That Robotics / IoT Lab felt 
like a bit of a whirlwind, but we had a ton of fun.  As we do every year, we found some things worked 
better than others, and we plan to take those learnings and apply them to future presentations.  If you 
had a chance to attend last year, thanks for stopping out, and if not, we hope to see you this year!</p>
<p>All the code and examples we used for the lab are slowly but surely making their way
out to GitHub.  Some of the code was pulled from other samples available on the internet,
and some was created specifically for the lab, but all should be available there, with links
to the source material where applicable.</p>
<p><a href="https://github.com/bengavin/that-conference-2016">That Robotics / IoT Lab Repository</a></p>
<p>Thanks again to all who make That Conference possible (organizers, attendees and sponsors)!  You&apos;ve
created something great, and we hope to be a part of it for many years to come!  Don&apos;t forget, the
<a href="https://www.thatconference.com/Resources/ImportantDates">Call for Speakers</a> is coming up Feb 1st, 2017 
(through March 15th), so start preparing your abstracts!</p>
</div>]]></content>
    </entry>
    
    <entry>
      <title>Wish List Processing with Azure Service Fabric</title>
      <link href="http://www.virtual-olympus.com/posts/2016/12/wish-list-processing-with-service-fabric/"/>
      <updated>2016-12-12T00:00:00.000Z</updated>
      <id>/posts/2016/12/wish-list-processing-with-service-fabric/</id>
      <content type="html"><![CDATA[<div><h4 id="originally-published-on-the-skyline-technologies-blog-https-www-skylinetechnologies-com-blog-skyline-blog-december_2016-wish_list_processing_with_azure_service_fabric-">Originally Published on the <a href="https://www.skylinetechnologies.com/Blog/Skyline-Blog/December_2016/Wish_List_Processing_with_Azure_Service_Fabric">Skyline Technologies Blog</a></h4>
<h2 id="wish-list-processing-today">Wish List Processing Today</h2>
<p>Santa&apos;s Super Software Elves (S3E) are constanty looking to improve Santa&apos;s ability to process
wish lists as painlessly as possible.  It&apos;s pretty important to all of us at North Pole Central
Operations that deserving kids throughout the world get just what they were hoping for Christmas
every year.  During one of our routine architecture review meetings, the team decided it was time
to look into replacing our current Wish List Processing Services with something a bit more flexible
and future-proof.</p>
<p>We here on S3E are certainly no slouches when it comes to technology, and we&apos;re willing to leverage
&apos;The Cloud&apos; in any way we can to make sure there are presents to open on Christmas Day.  We were early
adopters of Azure&apos;s Platform-as-a-Service Web and Worker roles (PaaS v1), exposing our wish list submission
API to those enterprising kids of the world who wished to have direct access to Santa (Of course, we
also provided a handy web application that the mail elves could use for manual entry as well).  Our
current Wish List Processing Service looks a bit like this.</p>
<p><img src="http://www.virtual-olympus.com/posts/2016/12/wish-list-processing-with-service-fabric/WishListPaasV1Layout.png" alt="PaaS v1 Layout"></p>
<p>As you can see, there is a standard web / worker role layout with some &apos;glue&apos; in between to hold the
persistent data, and handle communications between the web and worker roles.  In this case, we used
the various Azure Storage technologies (Blobs, Queues and Tables) to provide that glue.  Person data
was stored in Azure Table Storage and Workflows were managed by populating the appropriate Storage Queues.
The Worker Role(s) handled shuffling data around and making sure the millions of nice kids around the
world had something to open Christmas morning.</p>
<h2 id="the-limitations">The Limitations</h2>
<p>While our current solution is working well, the scaling capabilities are pretty coarse grained.  We
can play around a bit with the number of instances of the Web and Worker roles, but we don&apos;t really
have a way of utilizing any of the &apos;unused&apos; compute power that our Web/Worker role instances may
have.  We also have to provide pretty much all the &apos;glue&apos; code ourselves, making sure the two roles
work together seamlessly.  There&apos;s really no built-in facility to manage those
occasional &apos;uh oh&apos; moments (we have them here at the North Pole too).  While PaaS v1 does have the
concept of &apos;deployment slots&apos;, leveraging them to manage service health based rollback required a
lot of manual scripting.</p>
<p>We also want to be as cost conscious as possible (we elves need to eat too), so getting more from
less compute resources seemed like a no brainer.  When utilizing Web/Worker roles, you &apos;scale&apos; one
or the other by essentially spinning up a new virtual machine, dedicated to that particular task.
Any work sharing arrangement, similar to our current solution, requires manual coding.  Getting more
done per machine pretty much directly correlates to writing more code.</p>
<h2 id="enter-service-fabric">Enter Service Fabric</h2>
<p>One of the promises of Azure Service Fabric is more efficient use of the resources that a given VM
provides.  This is done primarily by disconnecting the direct relationship that PaaS v1 had between
a role instance and a VM.  This does a couple things for us right away.  First, it lowers deployment
time, as the VM does not need to be re-provisioned as part of the deployment process.  Secondly, it
allows multiple services (roles in PaaS v1) to run on the same VM instance.  By default, you don&apos;t have
control over where your service deploys to, only the number of instances that are deployed.  For those
interested, however, there are knobs and switches you can use to, say, have a cluster of high CPU or 
high memory nodes that certain services are deployed to.</p>
<p>Service Fabric, like PaaS v1, does not require you to manually manage your VM instances / images.
How this capability is delivered, however, is quite different than before.  Service Fabric is really about
leveraging a bunch of existing Azure technologies, rather than providing a &apos;standalone&apos; solution
as in PaaS v1.  Service Fabric uses technologies like Azure Load Balancer, Azure Virtual Machine
Scale Sets and Azure Virtual Networks to provide the operating environment for your services.  When
you configure a Service Fabric Cluster, whether via the <a href="https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-cluster-creation-via-portal">Azure Portal</a> or
<a href="https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-cluster-creation-via-arm">Azure Resource Manager Templates</a>, 
you are asking the Azure infrastructure to setup a suite of existing technologies and glue them
together into a cluster for you.  You can manage then that cluster using the <a href="https://portal.azure.com">Azure Portal</a>, 
<a href="https://github.com/Azure/azure-xplat-cli">Azure Command Line Tools</a> or <a href="https://docs.microsoft.com/en-us/powershell/azureps-cmdlets-docs/">Azure Powershell Cmdlets</a>.</p>
<p><img src="http://www.virtual-olympus.com/posts/2016/12/wish-list-processing-with-service-fabric/ServiceFabricLayout.png" alt="Service Fabric Layout"></p>
<p>In the diagram above, you can see some of the Azure technologies that are used to create a cluster.
At the core, a Virtual Machine Scale Set (VMSS) is used to provide the nodes for the cluster.  These
nodes are linked together with an Azure Virtual Network, and secured with an SSL certificate that is
pulled from Azure Key Vault.  With a little additional work, you can secure the management of your cluster,
including application deployments, with Azure Active Directory.</p>
<p>The fabric is exposed to the public internet in a couple ways.  An Azure
Load Balancer sits in front of the fabric and routinely probes the nodes to determine which services
(ports) are available on each node in the system (this includes any custom application ports
you may need).  Secondly, <a href="https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-visualizing-your-cluster">Service Fabric Explorer</a> gives you a window into your cluster to monitor the
application(s) running there, and the general state of the fabric nodes.  There are toggles that can
be used to simulate node failure, loss of state data, etc, so you can safely test failure scenarios
easily.</p>
<h2 id="service-fabric-service-types">Service Fabric - Service Types</h2>
<p>Before we get into the nuts and bolts of the new proposed solution, it will be good to get some
vocabulary out of the way.  While Service Fabric is really a general purpose &apos;cluster as a service&apos;,
the <a href="https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-get-started">Service Fabric SDK</a> 
has a number of specific concepts that we&apos;ll be leveraging to make everything work.</p>
<h3 id="services">Services</h3>
<p>A Service Fabric &apos;Service&apos; is a piece of code that runs within the cluster.  Each service has address(es)
(or endpoints) that can be called to invoke the service functions.  All services expose their functionality 
by declaring and implementing an <i>Interface</i> and utilizing <i>Service Listeners</i> to receive requests 
from other nodes in the fabric (or from the internet through the load balancer).  Services can be either 
<b>stateful</b> or <b>stateless</b>.  <b>Stateless</b> services generally run with a copy on each node of 
your cluster, they may be truly stateless [just perform operations on data they receive], or state may be 
managed by an external resource [e.g. a database].  <b>Stateful</b> (or Reliable) services, on the other hand, have state 
that is managed by the service fabric runtime (this state is potentially further divided by partition).</p>
<h3 id="actors">Actors</h3>
<p>A Service Fabric &apos;Actor&apos; is a named instance of an object that lives in Service Fabric.  Actors relate
on a certain level to a &apos;Stateful Service&apos;, in that the actor state is managed by service fabric.
However, Actors differ in that they are further managed in a <i>turn</i> or <i>queue</i> based manner.
For example, if multiple requests are made to the same Actor type (e.g. ElfActor) with the same Actor 
ID (e.g. Joe), then that Actor will process the requests in the order they are received.  Actors also
have the ability to fire <a href="https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-reliable-actors-events"><i>best effort</i> events</a> 
to anyone in the cluster that is listening.</p>
<h2 id="wish-list-processing-revisited">Wish List Processing - Revisited</h2>
<p>Finally, let&apos;s take a look at the proposed architecture for our new &apos;v2&apos; Wish List Processing service.
The elves in S3E have come up with the following high-level diagram of the services that will live in the
cluster.</p>
<p><img src="http://www.virtual-olympus.com/posts/2016/12/wish-list-processing-with-service-fabric/WishListHighLevelLayout.png" alt="Wish List Layout"></p>
<p>As with our original solution, the primary &apos;user interface&apos; is a Web API endpoint that runs in the
cluster and is exposed to the public internet via the Azure Load Balancer.  Future versions may bring
over an updated version of the web application portion of the v1 Web Role as a separate service
within the cluster.  Since these are web apps/apis, they are hosted within a <b>stateless</b> service.
When the service receives a new wish list, it looks up the associated person from the &apos;Person&apos; service.</p>
<p>The Person Service is a <b>stateful</b> service, the service holds all known
person data in an <i>IReliableDictionary</i>.  This structure provides synchronized maintenance of the
dictionary contents across all instances of the service.  Furthermore, this particular stateful service
is <b>partitioned</b>, which allows us to divide or shard the data into buckets so one set of service
instances aren&apos;t responsible for all the service data.</p>
<p>Once the API has looked up and assigned the person to the incoming wish list, the list is sent to the
&apos;Review Member Service&apos;, which is another <b>stateless</b> service.  In this case, the set of reviewers
is defined in a configuration value that the service reads on startup.  The service takes the incoming
wish list data and routes it to the &apos;Review Committee&apos; actors, who review the list and approve items.<br>Once the Actor has reviewed the list, it is re-submitted to the Review Member Service.  Once
all reviewers have voted on the list, the list is sent to the &apos;Gift Processing Service&apos; so the approved
wish list items can be fulfilled.</p>
<p>The Gift Processing Service is a <b>stateful</b> service that holds a series of
<i>IReliableQueue</i> instances, one for each type of gift.  In addition to the normal interface-based
set of operations, the Gift Processing Service has a persistent background process that reads data from
these queues and delivers them to the appropriate Gift Maker Actor.  Each Gift Maker elf can only make one gift
at a time, and are only trained to make a single gift type, so Actors provide a good representation.  Once
the Gift Makers finish their work, they forward the wrapped gift to the &apos;Shipping Department&apos;, which
is a single-partition <b>stateful</b> service which keeps an <i>IReliableDictionary</i> of families
and their gifts, so the gifts can be bundled together and sent to the shipping provider, Santa&apos;s 
Sleigh Unlimited (or Amazon Prime Drone Delivery for the technically inclined).</p>
<h2 id="future-enhancements">Future Enhancements</h2>
<p>We here at S3E rarely sleep, so our wish list of features is extensive.  Some future enhancements that
we&apos;re currrently investigating include:</p>
<ul>
<li><p><strong>Mail Elf Utility</strong> - Migration of the existing web application was not part of the scope of our
original plan.  Instead, we&apos;ve updated the existing web application to point to the new Service
Fabric backed services.  In the future, we&apos;d like to bring in the web app as a second &apos;application&apos;
in service fabric, primarily to maintain isolation and separate deployment packages.  Service Fabric
allows any number of applications to run within the fabric, so there&apos;s no problem there, and moving
the app will allow us to decommission our existing web/worker roles completely.</p>
</li>
<li><p><a href="https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-report-health">Service Fabric Health Monitoring</a> - 
We plan to use this to monitor the gift maker queue depth, to
know when we should start training new Gift Makers to cope with demand.  We also plan to leverage the
automated application rollback capabilities that use health monitoring to determine whether or not
a new version of your application is &apos;healthy&apos;.  If the upgrade causes these health checks to fail, the
upgrade is automatically cancelled and rolled back to a previous working state.  This will allow us to extend 
our continuous deployment model that we use in the test / staging environments all the way to the production 
system.</p>
</li>
<li><p><strong>Santa&apos;s Naughty &amp; Nice List</strong> - We plan to create a Web Application to manage the data in the Person Service
such that Santa (and his fleet of Elves on the Shelf) can dynamically update the actual behavior rating of
people registered with the service, compared with the self-reporting that we currently accept with the wish
list submission process.  Again, the plan here is to create a separately deployed application within the
same cluster.</p>
</li>
<li><p><strong>Reviewer Status Monitoring</strong> - We hope to start leveraging Actor Events to help better track how long
reviewers are spending reviewing wish lists, and how long gift makers are taking to make particular gifts.  We
plan to link these data streams to <a href="https://azure.microsoft.com/en-us/services/stream-analytics/">Azure Stream Analytics</a>
so we can be alerted when reviews are taking too long (reviewing lists can be somewhat of a burnout job, even
for elves), or which gifts seem to be the hardest to make (to increase gift maker training)</p>
</li>
</ul>
<p>... and the list goes on, but <a href="https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-reliable-actors-timers-reminders">Actor Timers / Reminders</a>,
  <a href="https://msdn.microsoft.com/en-us/library/system.diagnostics.tracing.eventsource%28v=vs.110%29.aspx?f=255&amp;MSPPError=-2147217396">Logging with EventSource</a> and
  <a href="https://blogs.msdn.microsoft.com/dotnet/2016/10/13/hosting-net-core-services-on-service-fabric/">.NET Core</a> are all on our research backlog.
  There is also a lot of opportunity to leverage other Azure services, like <a href="http://bit.ly/2gOPDPi">Azure Service Bus</a>
  and <a href="http://bit.ly/2hbnBvy">Azure IoT Hub</a> to automate even more of our operations.</p>
<h2 id="wrapping-it-up">Wrapping it up</h2>
<p>At S3E and NPCO, we are always focused on continuous improvement.  Moving wish list processing to Azure
Service Fabric will address many of the scaling and coordination concerns that we have with our existing
Web / Worker Role solution.  The move will also open the door to further improvements with less code.
Using the Service Fabric SDK and Visual Studio 2015 (and soon 2017) allows us to very quickly wire together our new
microservices without needing to worry too much about the details of making them all play nice together.
In the end, it&apos;s all about getting toys out to those millions of nice girls and boys (and a few parents too).
Doing that more efficiently and with fewer operational headaches allows us elves a bit of needed respite, and
maybe the occasional vacation to Maui too ;) (even elves have big dreams).</p>
</div>]]></content>
    </entry>
    
    <entry>
      <title>That Conference 2016 - Let's Get Excited!</title>
      <link href="http://www.virtual-olympus.com/posts/2016/04/that-conference-2016-lets-get-excited/"/>
      <updated>2016-04-26T00:00:00.000Z</updated>
      <id>/posts/2016/04/that-conference-2016-lets-get-excited/</id>
      <content type="html"><![CDATA[<div><h3 id="why-you-should-attend">Why you should attend</h3>
<p><a href="https://www.thatconference.com/">That Conference 2016</a> (Aug. 8 - 10) is one of the truly unique experiences that the upper-Midwest
has to offer for geeks everywhere.  How do I know this?  I&apos;ve been attending, with my family, since 2013.  Over 100* presenters and 
nearly 1000* [or more] of your coworkers, friends and community members will be there... and have I mentioned the bacon smores?!?  Just 
wander over, take a look at these <a href="https://www.thatconference.com/Speakers">speakers</a>, <a href="https://www.thatconference.com/Schedule">build your schedule</a> 
and wonder how you could possibly survive the summer without all this technical goodness and networking with this welcoming 
community.</p>
<p>If you hurry, all this geek-loving, family-friendly, bacon-consuming, robot-exploring and memory-making joy can be yours for only $399.99... Seriously, 
$399.99.  The only catch?  It&apos;ll cost you an extra $100 if you buy your tickets after May 1st, 2016.  If saving money isn&apos;t enough, you&apos;ll
have a chance to meet with <a href="https://www.thatconference.com/Sponsors">Those Sponsors</a>.  Many of the sponsors are among the premier technology
firms in the nation, including my employer, <a href="http://www.skylinetechnologies.com">Skyline</a>.  There&apos;s nowhere else that you can find so
much local talent, and so many fantastic local employers who are eager to talk with you about how they can help you find your dream
career/service provider/etc.</p>
<p>So, I encourage you to check out what is sure to be one of the year&apos;s <a href="https://www.thatconference.com/">premier technical conferences</a>.</p>
<h3 id="what-we-re-doing">What we&apos;re doing</h3>
<p>As I mentioned, I&apos;ve been attending and speaking at That Conference for the last 3 years.  For the last two, my focus has been on
bringing unique experiences to the families that attend the conference.  In 2014, we started with a <a href="https://www.thatconference.com/Sessions/Session/4453">3-day Robotics Camp</a>.
We took our experiences in 2014 and followed up with a <a href="https://www.thatconference.com/Sessions/Session/8095">2-Day Robotics Lab</a> as
part of That Conference 2015.  The feedback from 2015 was amazing, and we saw a lot of kids get really excited about robotics.  Whether
it was building projects with family and friends, programming with siblings or throwing some balls around with a drivable robot, there
were smiles aplenty.  </p>
<p>For That Conference 2016, I&apos;ve been blessed with the opportunity to present beside my son Christopher, and we plan
to take things to the next level with our <a href="https://www.thatconference.com/Sessions/Session/10346">2-Day Robotics / IoT Lab</a>.  We&apos;ll
have Vex IQ robots / simple mechanisms, Vex IQ sensor labs and some pre-built Vex IQ bots like we&apos;ve had previous years, but this
year we are adding in some Arduino-based bots and some IoT sensors/kits running Windows 10 IoT.  I&apos;ll
leave the details to future blog posts, but I hope to see you there this year.  Stop by and check out our Lab, and take some time
to contemplate this little factoid... Christopher is only one of <strong>7 speakers</strong> who are children!  The conference has over 20 family 
track sessions over 3 days, and of those, <em><strong>more than 50%</strong></em> are being delivered at least partially by Geeklings!</p>
<h3 id="and-if-that-wasn-t-enough">And if that wasn&apos;t enough</h3>
<p>Don&apos;t forget that this all happens at an <a href="http://www.kalahariresorts.com/wisconsin">Amazing Waterpark!</a></p>
<p>* Numbers are estimated to protect the innocent (and also because I don&apos;t have exact numbers)</p>
</div>]]></content>
    </entry>
    
    <entry>
      <title>Tiny Epic Galaxies - A Review</title>
      <link href="http://www.virtual-olympus.com/posts/2014/12/tiny-epic-galaxies-review/"/>
      <updated>2014-12-03T00:00:00.000Z</updated>
      <id>/posts/2014/12/tiny-epic-galaxies-review/</id>
      <content type="html"><![CDATA[<div><p>Thanks to a bit of luck (my name got pulled from a raffle), I was recently afforded the opportunity to play 
a prototype of the board game <a href="http://www.tinyepicgalaxies.com">Tiny Epic Galaxies (TEG)</a> - <a href="http://boardgamegeek.com/boardgame/163967/tiny-epic-galaxies">BGG Page</a>.
Having never played an unreleased game before [save the print-and-play offerings from various Kickstarter campaigns],
I was intrigued to give it a try.  After playing numerous rounds with friends and family, what I found was a fairly well balanced
game, with equally well developed instructions, that was in turns fun to play and enigmatic.</p>
<h3 id="what-is-it-">What is it?</h3>
<p>Tiny Epic Galaxies is a 2-4 player light strategy / galaxy building game
created by <a href="https://www.twitter.com/Scott_Almes">Scott Almes</a> and published by <a href="http://www.gamelyngames.com">Gamelyn Games</a>.
This is the 3rd installment in the &apos;Tiny Epic&apos; series, preceeded by <a href="http://gamelyngames.com/cms/TEK">Tiny Epic Kingdoms</a>
and <a href="http://gamelyngames.com/cms/TED">Tiny Epic Defenders</a>.  All three games are intended to be &apos;Micro Games&apos;, delivered in
small (5x7x1-ish) boxes and playable in 30 minutes or less.  TEG departs from the setting/story line of the previous two
games, bringing the story to &apos;space&apos; in the hopes of pulling you into a contest for galactic domination.</p>
<div class="text-center">
    <span class="well" style="display: inline-block; padding: 10px"><img src="http://www.virtual-olympus.com/posts/2014/12/tiny-epic-galaxies-review/tiny_epic_galaxies_contents.jpg" alt="Tiny Epic Galaxies"><br><small>Game (Prototype) Contents</small></span>
</div>

<h3 id="how-does-it-work-">How does it work?</h3>
<p>The game is played in rounds, with the level of the players&apos; Galaxy determining how many ships they have in play, how many
dice they roll and how many victory points their galaxy affords them.  Each player takes a turn by rolling the dice and
&apos;locking in&apos; actions.  Other players, who have culture points remaining, can piggy-back off the current player&apos;s last move by
spending one of their culture points to duplicate the last locked action.  Players move to and persuade planets to join their
Galaxy, gaining victory points and powers they can use with the appropriate dice roll.  Once a player reaches 21 combined victory 
points [from captured planets and the players&apos; Galaxy], all other players have a single turn to match or exceed the winning player&apos;s 
victory point total.  In the end, the player with the most victory points has won the &apos;Quest for Galactic Domination&apos;.</p>
<h4 id="game-setup">Game Setup</h4>
<p>Setting things up for a game is pretty straightforward, just give each player the following components:</p>
<ul>
<li>A Galaxy card</li>
<li>Set of 4 ships</li>
<li>A cube marker [energy]</li>
<li>A disc marker [culture] </li>
<li>A hex cylinder [galaxy level]</li>
</ul>
<p>Players start with their &apos;base&apos; Galaxy - A home planet with 2 ships, 2 energy and 1 culture.  The remaining two ships are placed in 
reserve, for use after the Galaxy has been upgraded.  The 30 planet cards are then shuffled and the number of players + 2 planets 
are dealt face-up in the center, with the others held face-down in reserve to be used during play.</p>
<div class="text-center">
    <span class="well" style="display: inline-block; padding: 10px"><img src="http://www.virtual-olympus.com/posts/2014/12/tiny-epic-galaxies-review/tiny_epic_galaxies_starting_player_card.jpg" alt="Starting Galaxy Setup"><br><small>Starting Galaxy Setup</small></span>
</div>

<h4 id="gameplay">Gameplay</h4>
<p>Play then proceeds by selecting a starting player.  The instructions suggest the last person to finish a sci-fi novel, but we just
chose at random [or the youngest player when playing with my kids].  The base Galaxy affords the players 4 dice to roll, so player one
kicks things off by rolling their four dice and deciding which to keep and which to re-roll.  One re-roll is free, and all additional
re-rolls consume one energy.</p>
<div class="text-center">
    <span class="well" style="display: inline-block; padding: 10px"><img src="http://www.virtual-olympus.com/posts/2014/12/tiny-epic-galaxies-review/tiny_epic_galaxies_die_faces.jpg" alt="The Dice"><br><small>The Dice</small></span>
</div>

<p>There are 6 possible actions for each die [pictured above].  Actions include basic movement, energy/culture capture, colonization 
and &apos;Galaxy action&apos; [officially a &apos;Colony Action&apos;].  As each die is &apos;locked&apos; the current player performs that action and sets that die aside.<br>Then any player who has culture points remaining can choose to duplicate the just-locked action by spending one culture point.  That player then 
immediately takes that action, <em>before the current player can proceed with their next action</em>.  If more than one out-of-turn player wants to act, 
actions are performed in turn-order.</p>
<p>The remaining dice are then locked, one at a time, with the current player choosing to use their re-roll(s) at any point during their turn.<br>If a planned action is nullified by another person&apos;s out-of-turn action, the player can use their free re-roll [or spend energy if available] to &apos;replan&apos;
on the fly.  Once the player has activated all the dice they plan to use, play proceeds clockwise around the table.  The current player
<em>does not</em> need to use all their rolled dice, and any dice which are not activated cannot be duplicated by other players.</p>
<h4 id="the-planets">The Planets</h4>
<div class="text-center">
    <span class="well" style="display: inline-block; padding: 10px"><img src="http://www.virtual-olympus.com/posts/2014/12/tiny-epic-galaxies-review/tiny_epic_galaxies_planet.jpg" alt="A Planet"><br><small>A Planet Card</small></span>
</div>

<p>Each planet arrayed in the center of the table has 4 basic components:</p>
<ul>
<li>A - Resource [energy or culture]</li>
<li>B - &apos;Colonization&apos; Track [$ or !]</li>
<li>C - Power / Action</li>
<li>D - Victory Points</li>
</ul>
<h4 id="movement-and-colonization">Movement and Colonization</h4>
<div class="text-center">
<span class="well" style="display: inline-block; padding: 10px;"><img src="http://www.virtual-olympus.com/posts/2014/12/tiny-epic-galaxies-review/teg_die_move.jpg" alt="Move Die"></span>
</div>

<p>Using a move action die allows a player to move their ship to any planet card that does not currently host one of their ships. Each planet 
card has two possible landing sites.  The first landing site is the planet&apos;s surface, which can be occupied by only a single ship.  Landing here 
activates that planet&apos;s &quot;power&quot; immediately.  The second possible landing site is the start of the &apos;colonization&apos; track.  Any number of players 
can be vying for colonization of the planet at the same time.  When moving a ship that currently resides on a planet card, the player <em>must</em> move 
their ship OFF the current card.  Ships cannot be moved between the colonization track and planet surface without first leaving the planet.  The only
card which may house more than one ship / player is the player&apos;s Galaxy card.  Ships that have been displaced, or which move newly into service
are placed on the home planet.</p>
<div class="text-center">
<span class="well" style="display: inline-block; padding: 10px"><img src="http://www.virtual-olympus.com/posts/2014/12/tiny-epic-galaxies-review/teg_die_diplomacy.jpg" alt="Diplomacy Die"></span>
<span class="well" style="display: inline-block; padding: 10px"><img src="http://www.virtual-olympus.com/posts/2014/12/tiny-epic-galaxies-review/teg_die_invest.jpg" alt="Invest Die"></span>
</div>

<p>Using a colonizing action [$ or !] allows the player to move one of their ships on a matching planet up one &apos;space&apos; on the colonizing track, 
towards the colonization symbol.  When the symbol at the end of the track is reached, that planet is claimed by the player and becomes part of 
their Galaxy.  Once colonized the planet loses its resource generating ability, but the colonizing player gains both the victory points and planet 
&quot;power&quot; to use as a &apos;Galaxy&apos;/&apos;Colony&apos; action.  All ships currently occupying the planet card are immediately returned to their home planet.</p>
<h4 id="resource-gathering">Resource Gathering</h4>
<div class="text-center">
<span class="well" style="display: inline-block; padding: 10px"><img src="http://www.virtual-olympus.com/posts/2014/12/tiny-epic-galaxies-review/teg_die_energy.jpg" alt="Energy Die"></span>
<span class="well" style="display: inline-block; padding: 10px"><img src="http://www.virtual-olympus.com/posts/2014/12/tiny-epic-galaxies-review/teg_die_culture.jpg" alt="Culture Die"></span>
</div>

<p>When activating an energy or culture die, players initiate a &apos;resource gathering&apos; action.  Each planet card that provides the activated 
resource and currently hosts a player&apos;s ship supplies one &apos;point&apos; of that resource to the player&apos;s reserves.  <em>NOTE: This includes the
player&apos;s home planet if the activated resource is energy.</em>  Energy and Culture reserves have a maximum capacity of seven (7).  Once the 
reserves are full, furthur gathering of that resource has no effect.</p>
<h4 id="galaxy-or-colony-actions">Galaxy [or Colony] Actions</h4>
<div class="text-center">
<span class="well" style="display: inline-block; padding: 10px"><img src="http://www.virtual-olympus.com/posts/2014/12/tiny-epic-galaxies-review/teg_die_colony.jpg" alt="Colony Die"></span>
</div>

<p>The final die face is the &apos;Galaxy&apos; or &apos;Colony&apos; action.  Initially this action can only be used to &apos;upgrade&apos; the Galaxy, providing more
dice / turn or more ships to deploy.  When upgrading the Galaxy, the associated victory points and any additional ships are activated immediately, 
but new dice do not come into play until the player&apos;s next turn.  If additional planets have been pulled into the Galaxy, a single planet&apos;s power 
can be choosen instead of the base action.  Planetary actions range from purely selfish [+1 culture/energy, combined energy+culture upgrades] to 
mildy disruptive [steal a culture/energy, move enemy ships down the colonizing track] all the way to devious [move ships to other planets, 
re-roll unactivated dice].  Planetary actions <em>always</em> override the base game rules/flow, and can be leveraged to great effect by saavy players.</p>
<div class="text-center">
<span class="well" style="display: inline-block; padding: 10px"><img src="http://www.virtual-olympus.com/posts/2014/12/tiny-epic-galaxies-review/tiny_epic_galaxies_game_in_progress.jpg" alt="Game In Progress"><br><small>Game in Progress</small></span>

<span class="well" style="display: inline-block; padding: 10px"><img src="http://www.virtual-olympus.com/posts/2014/12/tiny-epic-galaxies-review/tiny_epic_galaxies_player_card.jpg" alt="Player Galaxy"><br><small>Player Card</small></span>
</div>

<h3 id="experience-impressions">Experience / Impressions</h3>
<p>I had an opportunity to play the prototype with multiple groups of family and friends over the last few weeks, and the overall feeling was
pretty well spread across the board.  It feels rather clear to me that board gaming experience matters.  Those who played games often seemed to 
pick up Galaxies more quickly, while those who didn&apos;t game often were more likely to get &apos;bogged down&apos; in all the rules and potential 
strategies.  The game also benefits from multiple playthroughs.  I know I didn&apos;t feel entirely comfortable with the rules and 
strategy until my third game, and I lost a few players midway through their first game due to the perceived complexity.</p>
<p>While a majority of the people I played with were adults, I ended up playing the game most often with my two elementary / middle school 
aged sons.  I would feel safe recommending this game even to elementary school children [say, 7yr+], especially if the children have shown
an aptitude for strategy and are interested in board games.  After a few rounds, even my youngest son was able to negotiate a reasonable
strategy and be somewhat competitive.  Middle school aged kids [10yr+] should have no problems picking up the game, <em>IF</em> you can convince
them to sit down for a family game night :).</p>
<p>As I mentioned initially, the rules are fairly well written for a prototype.  I missed the ability to land on the planet&apos;s surface
on our first play through, and didn&apos;t remember we could re-roll using energy until the middle of the second game.  Games, especially with
new players, tended to start out pretty slowly.  However, once most players understood the rules, play cadence picked up significantly.<br>While we were never able to get a 4-player game completed in 30 minutes, we were able to keep it under an hour most times.  The average play 
time for our groups was around 45 minutes, and it seemed like the &apos;sweet spot&apos; was 3 players.  Two player games were fun, but the game really 
opened up once you hit the third player.  Four players was equally fun, but the game seemed to get a little more drawn out, and was hard to 
keep inside the 60 minute window that most of my play sessions had.</p>
<p>Given that this is the third installment in the &apos;Tiny Epic&apos; series of games, it seems appropriate to compare/contrast this game with the
other games in the series.  Having backed the Kickstarter for Tiny Epic Defenders, I had a copy of the print-and-play, and have played with
many of the same groups where I prototype&apos;d Galaxies.  Interestingly enough, it was a pretty even split between the two groups as to which of the
two games was preferred.  It feels like the &apos;hook&apos; for Defenders is a bit stronger within my play circles, although I personally prefer 
Galaxies.  While I don&apos;t feel that the rule sets between the two games are much different from a complexity standpoint, friends and family
consistently rated Galaxies as &apos;harder to understand&apos;, even if they liked it as much or better than Defenders.  It may be due to the competitive 
nature of Galaxies vs. Defenders co-op play which encourages sharing of strategies/suggestions.  While I also own Tiny Epic Kingdoms, I have not 
yet had a chance to play it (it&apos;s a Christmas gift for the kids), so I can&apos;t make any personal comparisons there.</p>
<h3 id="clarifications-house-rule-suggestions">Clarifications / House Rule Suggestions</h3>
<p>As this is a prototype, rule clarifications were to be expected.  Gamelyn Games staff were very responsive to Twitter questions, and we
were able to get a few questions cleared up pretty quickly.  Of course, I didn&apos;t always like the answers :)</p>
<ul>
<li>Colonized planets are officially replaced at the end of each round.  However, in our play sessions, we found that following this rule caused
a pretty heavy &apos;last player handicap&apos; and that play moved much more smoothly [and fairly] if colonized planets were replaced immediately.</li>
<li>The rules are unclear about how many players can occupy the planet&apos;s surface, but based on the explicit call-out of multiple colonizing players, 
we chose to limit the planet surface to a single ship.</li>
<li>Planet powers/actions generally override any normal game rule, but some planet rules are somewhat confusing.  We usually just decided what 
the power &apos;meant&apos; when the planet joined the center of the table, and could usually come to a reasonable consensus quickly.</li>
<li>Replacing colonized planets immediately helped even out the overall game, but it feels like adding +1 [culture OR energy] by player position 
would help to further balance play.  In this way later players get more opportunity to use previous player actions.  I haven&apos;t played enough
rounds with this rule to tell whether it unbalances the game, but it feels like a good fit thus far.</li>
</ul>
<h3 id="conclusion">Conclusion</h3>
<p>Overall I was very pleased with the play experience of Tiny Epic Galaxies.  The strong blend of luck and strategy combined with relatively quick pacing 
means that this game will have a place on my game shelf for a long time to come.  There is enough of a hook to pull players in, and once the rules 
are well understood, the game plays quickly.  Replayability is high, and the game felt a bit different each time we played.  Strategies that 
worked in previous games were easily countered or non-functional in future games due to the mix of planets and luck of the dice roll.</p>
<h4 id="the-good">The Good</h4>
<ul>
<li>Quick, Light Strategy Game with just enough luck thrown in to keep you guessing</li>
<li>Multitude of different strategies possible, no &apos;one sure way to win&apos;</li>
<li>Accessible to kids [10+ for sure, 7+ is possible]</li>
<li>45-60 minute play times [with 4 players]</li>
</ul>
<h4 id="the-bad">The Bad</h4>
<ul>
<li>Some planets actions are unclear</li>
<li>How you&apos;ll feel if you miss out on the Kickstarter [starts Jan 8th, 2015]</li>
</ul>
<h4 id="the-ugly">The Ugly</h4>
<ul>
<li>It&apos;s not available for Christmas 2014</li>
</ul>
</div>]]></content>
    </entry>
    
    <entry>
      <title>That Conference 2014 - It's Almost Here!</title>
      <link href="http://www.virtual-olympus.com/posts/2014/07/that-conference-2014-its-almost-here/"/>
      <updated>2014-07-29T00:00:00.000Z</updated>
      <id>/posts/2014/07/that-conference-2014-its-almost-here/</id>
      <content type="html"><![CDATA[<div><h3 id="the-pitch">The Pitch</h3>
<p><a href="https://www.thatconference.com/">That Conference 2014</a> (Aug. 11 - 13) could very well be the time of your life [weddings, children 
and first dates not-with-standing], but if you don&apos;t attend, you&apos;ll never know.  Over 150* presenters and nearly 1000* [or more] of your 
closest friends are scheduled to be there... and have I mentioned the bacon smores?!?  Seriously, just wander over and take a look at 
the <a href="https://www.thatconference.com/Speakers">amazing speaker</a> filled <a href="https://www.thatconference.com/Schedule">schedule</a> and wonder 
how you could possibly survive without all this community and technical training goodness.</p>
<p>There&apos;s a catch though, ticket sales close next Monday (Aug. 4)!  Come join our amazing community of developers [and their families]
at what is sure to be one of the year&apos;s <a href="https://www.thatconference.com/">premier technical conferences</a>.</p>
<h3 id="what-we-re-doing">What we&apos;re doing</h3>
<p>OK, so sales pitch aside, I&apos;ve been given the amazing opportunity to run a 3-day Robotics Camp at the conference this year.
Why is this amazing?  Seriously?  Did you not just hear me say <strong><em>3-Day Robotics Camp</em></strong>?  The camp will be held as part of That
Conference&apos;s <a href="https://www.thatconference.com/Schedule/FamilySchedule">Family Track</a> and will take place during the normal session
times throughout all three days.  We&apos;ll be using the <a href="http://www.vexrobotics.com/vexiq/">VEX IQ</a> robotics system and walking kids
through the process from a bin full of parts to a finished robot, with a side of competition and a kicker of badge ribbons.</p>
<p>There have been a lot of folks involved in making this thing a success, but I&apos;ll save that for the postmortem report.  For now
head over and <a href="https://www.thatconference.com/Sessions/session/4453">check out our Day 1 abstract</a> and then get those tickets
purchased.  We look forward to seeing you there!</p>
<p>P.S.</p>
<h2 id="-did-i-mention-it-s-all-happening-at-a-freaking-waterpark-http-www-kalahariresorts-com-wisconsin-"><a href="http://www.kalahariresorts.com/wisconsin">Did I mention it&apos;s all happening at a freaking Waterpark!</a></h2>
<p>* Numbers are estimated to protect the innocent (and also because I don&apos;t have exact numbers)</p>
</div>]]></content>
    </entry>
    
    <entry>
      <title>Windows 8 DevCamp Postmortem</title>
      <link href="http://www.virtual-olympus.com/posts/2013/01/windows-8-devcamp-postmortem/"/>
      <updated>2013-01-15T00:00:00.000Z</updated>
      <id>/posts/2013/01/windows-8-devcamp-postmortem/</id>
      <content type="html"><![CDATA[<div><p>Last fall [Sep. 2012], my company <a href="http://www.skylinetechnologies.com/">Skyline Technologies</a>, put together a Windows 8 DevCamp for our associates. &#xA0;The purpose of the camp was to accelerate our employees learning of the Windws 8 development stack, have loads of fun and produce some publication worthy apps to the Windows 8 Store. &#xA0;I&apos;ve been meaning to write up a postmortem on the whole experience for quite some time, what follows is a postmortem on the DevCamp as a whole AND some specifics about our particular application, and represents my personal opinions on things. &#xA0;I haven&apos;t had a chance to crowd-source the analysis with the other product owners to see if they had similar experiences.</p>
<h2 id="what-went-right">What went right</h2>
<h3 id="participant-sourced-ideas">Participant Sourced Ideas</h3>
<p>Prior to the DevCamp, the camp leads sent out a call for proposals to all participants who had signed up for the camp. &#xA0;Participants were asked to submit 1 or more application ideas which would be voted on by the group, and the top 5 would be implemented as part of the DevCamp. &#xA0;This was a great opportunity for participants to flex their design and leadership muscles, and most [if not all] of the people whose proposals won ended up as the product owner for their idea. &#xA0;This was a great way for developers to get a chance to &apos;own&apos; the end product, providing additional incentive to push through the final publication and delivery process.</p>
<h3 id="great-people-awesome-team">Great People, Awesome Team</h3>
<p>Skyline, as a rule, hires some of the best people I&apos;ve ever had the pleasure of working with, hands down. &#xA0;The group that I worked with to deliver our Windows 8 app, Game Manager - Soccer, was a great mix of seasoned XAML devs, fairly new recruits and seasoned devs with little XAML specific experience. &#xA0;Nobody on the team had any significant real-world Windows Store [/Modern UI/Metro] development experience to speak of. &#xA0;Over the two days of the dev camp, and the follow-on work to complete the app for publication we ended up bringing the entire team up to speed on Windows Store development and had a great team dynamic that kept things fun. &#xA0;I heard similar stories from every other team at the camp, and everyone I&apos;ve talked to thus far has expressed an interest in doing future camps.</p>
<h3 id="good-technology-split">Good Technology Split</h3>
<p>It turns out that after the voting was in, and product owners had chosen their desired technology stack, we had an even split between C#/XAML and HTML5/JS. &#xA0;I was a bit suprised, being a XAML-geek myself, that more teams hadn&apos;t chosen the XAML stack. &#xA0;After going through the camp and talking with my colleagues, the &apos;HTML5 guys&apos; were equally baffled that anyone would choose the XAML stack. &#xA0;The even split in technologies meant that our DevCamp participants could really pick and choose a team that fit both an app they were interested in and a technology stack that they had a passion for. &#xA0;Win-Win for all involved.</p>
<h3 id="design-work-project-scope">Design Work / Project Scope</h3>
<p>The team did a great job whittling down and mercilessly cutting scope to be able to fit the v1 release into the 200-300 hr window that the DevCamp required. &#xA0;Building out screen designs and the planning that went into the application prior to DevCamp weekend made a huge difference in our ability to set focus and successfully deliver the quality of work that came out of the initial weekend. &#xA0;We had learned this lesson a bit after our last company GiveCamp, and the DevCamp helped solidify that vision/requirement for future camps. &#xA0;The good thing about needing to cut scope was that it allowed us to focus on quality for the pieces we were able to include, and to enhance the user experience beyond what we could have done had we kept the initial scope intact.</p>
<h3 id="surface-rt">Surface RT</h3>
<p>Who doesn&apos;t love to get new hardware! &#xA0;Skyline generously handed out new Surface RT devices to all participants in the DevCamp as a reward for the time they put in on the project. &#xA0;Not only is this a cool device, but it also allows us to test the application on &apos;baseline&apos; ARM hardware to ensure that we are meeting the performance requirements of the system. &#xA0;Using the RT allowed our team to find a number of performance related bugs before we published, which means a better experience for our users, and better ratings for the app overall.</p>
<h2 id="what-went-wrong">What went wrong</h2>
<h3 id="project-scope">Project Scope</h3>
<p>Surprise surprise, scoping is good and bad! &#xA0;Scoping a project is always hard, and even with the ruthless cutting of project scope, we STILL underestimated the total effort required to deliver the application. &#xA0;I think a large part of this was caused by some of the items I&apos;ll get into below, and was certainly effected by our relative inexperience in the Windows Store app development space, but future efforts will definitely be tempered by this lesson. &#xA0;In the case of our application, we really targeted what I [as product owner] felt was a minimum viable product feature set, so treading that line will always be hard. &#xA0;When building/planning your applications, always keep in mind whether your minimum requirements put your project &apos;out of scope&apos; for an effort such as a DevCamp.</p>
<h3 id="follow-through">Follow Through</h3>
<p>This point is a hard one to swallow, and I don&apos;t fault any of our team members for it because, in the end, &apos;real life&apos; is far more important than &apos;hitting a date&apos;. &#xA0;What went wrong in this process is that the scope [covered above] required a significant effort &apos;post DevCamp&apos; to push through to publication. &#xA0;As a result, a small portion of the overall project team ended up completely a lion&apos;s share of the remaining work and bug identification/fixes. &#xA0;That extended effort was &apos;part of agreement&apos; when signing up for the project, but unforseens and real life milestones tend to get in the way of the project plan sometimes. &#xA0;To be clear, THAT&apos;S A GOOD THING, and one of the great things about working for a company like Skyline. &#xA0;The work-life balance is extremely important to the company, and to all our team members, so when real-life steps in, the project takes a back seat. &#xA0;Bad news for the project, good news [usually] for those involved.</p>
<h3 id="local-data-model">Local Data Model</h3>
<p>As part of scoping things down, we went with a local in-memory data model for our &apos;data access&apos; approach. &#xA0;This was, I think, necessary in the end due to time constraints and project resources, but it did introduce a &apos;cognitive disconnect&apos; for many on the team whose day-to-day job is n-tier/service-based application development. &#xA0;It also introduced a number of bottlenecks and data management issues that simply don&apos;t exist when you have a &apos;real&apos; backend to talk to, and when your source of truth doesn&apos;t &apos;handle&apos; identity mapping, concurrency checks, relationships, etc. &#xA0;In the end, the &apos;simple&apos; approach which avoided SQLlite or some other &apos;real&apos; database backend, required a lot of not-so-simple code to ensure we were always maintaining references during serialization/deserialization, passing data around between ViewModels, etc. &#xA0;To add to this, our application supported data synchronization through the built-in WinRT &apos;roaming&apos; folder from the start... until we discovered that the current defaults within WinRT limit that storage to 100KB of data. &#xA0;As a result, we had to eliminate a &apos;free&apos; feature and replace it with a far more complicated [and error prone] LiveSDK/SkyDrive approach [which we are planning to deliver in our first post-v1 release].</p>
<h3 id="testing-feedback">Testing / Feedback</h3>
<p>Developing &apos;commercial&apos; software requires an entirely new level of testing/QA/etc compared with Line-of-Business applications. &#xA0;Now, to be clear, I think LOB apps could benefit from the robust level of testing and validation that <em>should</em> go into commercial software development, but the reality is that most LOB applications &apos;feel&apos; more flexible in this department from the business/financial side of the house. &#xA0;We grossly underestimated the effort required to adequately test the application, and the number of users required to do so effectively. &#xA0;As a result, bug reports were late getting in and fixed and one or two people ended up doing a majority of the testing [which isn&apos;t always fun]. &#xA0;On future projects, having a dedicated &apos;beta&apos; group that we can publish our application to ahead of time and gather feedback from will be on the top of the priority list.</p>
<h4 id="_sidebar_"><em>SIDEBAR</em></h4>
<address>As a brief aside, having a user-facing feedback site is also important. &#xA0;We looked at <a href="http://www.uservoice.com/">UserVoice</a>&#xA0;and <a href="https://getsatisfaction.com/">GetSatisfaction</a>, but both required fairly hefty fees for a non-single user account that we could use to gather feedback for the application [especially for a free app]. &#xA0;This is still something I want to do, and am pushing for, as it allows our user community to talk with us about their requirements/needs, something we don&apos;t always have during the initial application development. If anyone has any free or low-cost alternatives to these sites, I&apos;d love to hear about it [leave a comment below].</address><address></address>

<h3 id="store-publication">Store Publication</h3>
<p>The publication process was... interesting. &#xA0;To be sure, it only took a couple attempts to get the application certified/published successfully, and I&apos;m very thankful to the testers that helped us out and the team members that fixed bugs like mad, but the feedback from failed certifications needs serious work. &#xA0;During certification, it was identified that our application experienced crashes, however, the certification results did not include any details about these failures, or what portions of the application were being tested when the failures occurred. &#xA0;This makes the &apos;failure&apos; result as close to useless as possible, and forced us to revisit the application and &apos;fix&apos; things that weren&apos;t breaking locally [i.e. &apos;might&apos; have been bugs] and really go out of our way to just try to guess what they might have tried that could have caused the error. &#xA0;As an example, one of our team members discovered that if you put &apos;too much&apos; text in our text boxes, the application would appear to freeze [and sometimes crash]. &#xA0;That&apos;s a great find, and certainly not something I would have thought to test for prior to this project, but if that was indeed what caused the crash during certification, it would have been great to have them tell us that so we could address it more directly. &#xA0;Microsoft, if you&apos;re listening, recording a screencast of the testing/certification process that you can attach to failed certifications would go a LONG way towards producing better quality apps and shortening the turnaround time on publication failures.</p>
<h3 id="conclusion">Conclusion</h3>
<p>Overall the DevCamp went better than I thought possible. &#xA0;The camp was an awesome experience, both from a development and personal standpoint. &#xA0;Our team did an amazing job and I think all the team members would [and should] be proud of what we were able to accomplish. &#xA0;The lessons learned from this camp will be applied to the next one, and I look forward to future camps and continuing to make great software for Skyline and its many clients. &#xA0;Thanks to everyone on the team, and at Skyline in general, for your support in making this camp and <a href="http://www.skylinetechnologies.com/Services/mobile/Pages/Windows-8-apps.aspx">the applications</a> that came from it happen!</p>
<p>... And ..., if you&apos;re a soccer coach [or know one], go out there and grab <a href="http://apps.microsoft.com/windows/en-US/app/game-manager-soccer/69141643-9a9b-4f23-8b6d-2c5172d86bb4">Game Manager - Soccer</a>&#xA0;[or any of our <a href="http://www.skylinetechnologies.com/Services/mobile/Pages/Windows-8-apps.aspx">other Windows 8 applications</a>]! &#xA0;Leave us some feedback so we can continue to improve and go out there and build your own Windows Store applications!</p>
<p><img src="http://www.virtual-olympus.com/posts/2013/01/windows-8-devcamp-postmortem/GameManagerAppStore.png" alt="Game Manager - Soccer"></p>
</div>]]></content>
    </entry>
    
    <entry>
      <title>Migrating to the Orchard</title>
      <link href="http://www.virtual-olympus.com/posts/2013/01/migrating-to-the-orchard/"/>
      <updated>2013-01-05T00:00:00.000Z</updated>
      <id>/posts/2013/01/migrating-to-the-orchard/</id>
      <content type="html"><![CDATA[<div><p>Over the last [almost 1 year! <img src="http://www.virtual-olympus.com/posts/2013/01/migrating-to-the-orchard/wlEmoticon-surprisedsmile_2.png" alt="Surprised smile">] I&#x2019;ve been in the process of migrating my website/blog to a new blogging platform.&#xA0; I had been looking at <a href="http://www.orchardproject.net/">Orchard CMS</a> for quite some time, and was interested in trying it out for myself before recommending it to friends and colleagues for their sites [those that I maintain and those that I don&#x2019;t].&#xA0; Unfortunately, real life tends to intervene when least expected, and the time that I had to dedicate to migrating the blog disappeared.&#xA0; So, here I am, finally, on the new platform and while the process wasn&#x2019;t always as straightforward as I hoped, it&#x2019;s now &#x2018;done&#x2019;.&#xA0; I hope to now be able to dedicate some additional time to actually producing content [the driving reason for the initial move].</p>
<h2 id="so-hellip-why-">So&#x2026; why?</h2>
<p>There are a number of reasons, but the driving reason was that my old platform <a href="http://www.dotnetblogengine.net/">BlogEngine.NET</a>, while it was certainly capable, was starting to feel rather long in the tooth.&#xA0; It was still WebForms-based, I was moving to MVC development on my sites, and I could never really crack the theming nut to get a look and feel that I was truly happy with.&#xA0; The platform has served me well over the years, but I do most of my writing with Windows Live Writer, and there appeared to be a bug in BlogEngine.NET that was preventing publishing of posts with &#x2018;too many&#x2019; images, or maybe it was &#x2018;too long&#x2019;&#x2026; I could never figure out exactly what the problem was, but that was the trigger and was why I haven&#x2019;t gotten back around to blogging since.</p>
<p><img src="http://www.virtual-olympus.com/posts/2013/01/migrating-to-the-orchard/OldBlog_3.png" alt="OldBlog" title="OldBlog"></p>
<p>Orchard provides a number of &#x2018;bonus&#x2019; features [for me], it&#x2019;s based on MVC/Razor which is a big benefit as it aligns pretty closely with what I&#x2019;m &#x2018;used to&#x2019;, which means I can get up an running on changes/modifications right away.&#xA0; Its modular system should also allow me to selectively override the portions that I care about without changing the source/original copies of things.&#xA0; There are a lot of modules already pre-built, which is nice, and I&#x2019;ve been able to find most of what I need to provide feature parity out of the box.&#xA0; One thing that&#x2019;s missing&#x2026; out-of-the-box reCaptcha support for comment entry, but I&#x2019;ve found a <a href="http://www.outlooksharp.de/blog/how-to-integrate-recaptcha-in-orchard">blog post</a> that outlines the process of getting that added to the comments area, so hopefully I&#x2019;ll get that worked out soon.</p>
<p>Also, the Orchard theme I&#x2019;ve used supports out-of-the-box responsive design as well, so it should show up much better on mobile devices, and I don&#x2019;t have two different themes for the different devices.&#xA0; This is becoming more important these days, and so having this support without much effort on my part is a big win.</p>
<p><img src="http://www.virtual-olympus.com/posts/2013/01/migrating-to-the-orchard/NewBlog_3.png" alt="NewBlog"><img src="http://www.virtual-olympus.com/posts/2013/01/migrating-to-the-orchard/NewBlogThin_3.png" alt="NewBlogThin"></p>
<p>&#xA0;</p>
<h2 id="in-closing">In Closing</h2>
<p>Welcome to my new blog, and I hope to get back here posting much more regularly, with both the technical content you&#x2019;re used to and more observations on the state of technology in general.</p>
<p>&#xA0;</p>
<p>Thanks for reading!</p>
</div>]]></content>
    </entry>
    
    <entry>
      <title>TPL Dataflow–An [Extremely Short] Introduction</title>
      <link href="http://www.virtual-olympus.com/posts/2012/04/TPL-Dataflow–An-Extremely-Short-Introduction/"/>
      <updated>2012-04-16T00:00:00.000Z</updated>
      <id>/posts/2012/04/TPL-Dataflow–An-Extremely-Short-Introduction/</id>
      <content type="html"><![CDATA[<div><p>In the process of preparing my talk for the <a href="http://www.dayofdotnet.fvnug.org/">2012 Fox Valley Day of .NET</a>, I decided that the best way to get a reasonable talk laid out is to write a blog series about it <img src="http://www.virtual-olympus.com/posts/2012/04/TPL-Dataflow&#x2013;An-Extremely-Short-Introduction/wlEmoticon-smile.png" alt="Smile">.&#xA0; Maybe that means I&#x2019;m weird, I don&#x2019;t know, but it does mean that I&#x2019;ll actually have some new entries for the blog after far, far too long.&#xA0; I need to strike that balance between &#x2018;long ass boring&#x2019; and &#x2018;you are done already?&#x2019;, hopefully this will be a good way to get there.&#xA0; I&#x2019;ll go into a lot more detail about the project and resulting solution here than I ever could in a talk, so I&#x2019;ll apologize in advance if you&#x2019;re attending and see something here you were hoping I&#x2019;d elaborate on in my session.&#xA0; If you see these, and have specific questions, I&#x2019;ll be glad to answer them here or in person.</p>
<p>So, obviously, I&#x2019;m not going to outline the history of multi-threaded programming, or even the complete history of multi-threaded programming in the context of the .NET Framework. I will start out trying to set the context for the world we&#x2019;re currently faced with, and lay out what I hope to accomplish in this series. Future articles will delve more deeply into specific topics around Dataflow, and we&#x2019;ll see our simple app hopefully mature into a full-fledged test-bed for Dataflow experimentation.</p>
<h2 id="-nbsp-">&#xA0;</h2>
<h2 id="where-are-we-">Where are we?</h2>
<p>The 4.0 .NET Framework introduced a new concept for dealing with multi-threaded programming, the Task Parallel Library [or TPL from here on out].&#xA0; The TPL sought to pull out the &#x2018;good&#x2019; bits of parallel programming, from both best practices to burnt fingers, and roll them into a nice, easy-to-use framework.&#xA0; For the most part, at least in my experience, Microsoft succeeded in this goal.&#xA0; Certainly it wasn&#x2019;t perfect, and there were bits missing [many of which appear in the .NET 4.5 preview], but it was an excellent &#x2018;1.0&#x2019;.</p>
<p>Those who used the TPL built up various solutions for retrieving the data to process, bundling it up, spinning up tasks to do the processing and generally &#x2018;managing&#x2019; the flow of data through your application to get your job done.&#xA0; Stephen Toub explained this approach very well in <a href="http://channel9.msdn.com/events/BUILD/BUILD2011/SAC-808T">his 2011 //BUILD session</a>, talking about the &#x2018;data first&#x2019; nature of the existing TPL and some of the limitations of the approach.&#xA0; TPL Dataflow [TDF] really turns things on their head a bit, switching to a &#x2018;computation first&#x2019; model, whereby you setup the computation and then &#x2018;wait&#x2019; for data to flow into the network for processing.</p>
<p>To be sure, everything you can do with TDF you can do with TPL or TPL+Rx or TPL+(your library of choice), and many of you have already built similar solutions to the framework.&#xA0; What&#x2019;s exciting about TDF is that a lot of the &#x2018;stuff&#x2019; that needed to be managed as part of the &#x2018;overhead&#x2019; of a project is now handled &#x2018;out of the box&#x2019;, and we can move from concept to solution quickly and spend more time on the rules/scalability/robustness/documentation side of the equation than we ever had time for previously.</p>
<p>&#xA0;</p>
<h2 id="what-is-tpl-dataflow-tdf-anyway-in-100-words-or-less-">What is TPL Dataflow [TDF] Anyway [in 100 words or less]?</h2>
<p>TPL Dataflow is a set of Interfaces (IDataflowBlock, ITargetBlock, ISourceBlock and IPropagateBlock) and some implementing classes that can be used to build data processing networks.&#xA0; The classes are located in the System.Threading.Tasks.Dataflow namespace, and are part of .NET Framework 4.5 [currently in beta].&#xA0; The interfaces/classes are designed from the ground up to support multi-threaded, asynchronous programming and can be used to solve many classes of problems that were difficult to do with the TPL natively.</p>
<p><strong><em>Sidebar:</em></strong> These are .NET 4.5 classes, so you <strong><em>WILL NOT</em></strong> be using them in new &#x2018;Windows 8/RT Metro&#x2019; applications as they are not part of the surface area exposed by the new Windows Runtime.&#xA0; You may be able to use them &#x2018;wrapped&#x2019; in a WinRT component, but I haven&#x2019;t explored that option yet, and I&#x2019;m not sure that you&#x2019;d want to in any case.&#xA0; You <strong><em>WILL</em></strong> be using these classes on the &#x2018;backend&#x2019; that you write to service all these &#x2018;consumption&#x2019; Metro apps that you are building.</p>
<p>&#xA0;</p>
<h2 id="so-where-am-i-going-with-this-">So Where am I Going With This?</h2>
<p>The long term goal is a series of articles featuring these little guys (OK, so yes, they are currently big):</p>
<p><a href="http://www.virtual-olympus.com/Media/Default/OldBlogImages/TPLemming.png"><img src="http://www.virtual-olympus.com/posts/2012/04/TPL-Dataflow&#x2013;An-Extremely-Short-Introduction/TPLemming_thumb.png" alt="TPLemming"></a></p>
<p>I&#x2019;m sure you&#x2019;re as pleased to meet them as they are to meet you. <img src="http://www.virtual-olympus.com/posts/2012/04/TPL-Dataflow&#x2013;An-Extremely-Short-Introduction/wlEmoticon-smile.png" alt="Smile">&#xA0; I hope to use these TPLemmings to help demonstrate how to use the various classes that TDF offers, and have a little fun at the same time!&#xA0; Unfortunately you won&#x2019;t be able to do any more than meet them today, but I do hope you&#x2019;ll come back and say &#x2018;Hi&#x2019;.&#xA0; After all they&#x2019;ve got stuff to show you!</p>
<p>&#xA0;</p>
<h2 id="conclusion">Conclusion</h2>
<p>This article really serves as an introduction to the series, and gives you an idea of what TPL Dataflow is.&#xA0; Future articles will cover the interfaces and classes supplied by TDF and go into detail on what types of problems they can solve.&#xA0; And because I&#x2019;d be remiss if I didn&#x2019;t include <em>some</em> &#x2018;code&#x2019; in the article, I&#x2019;ll close with this little snippet.</p>
<p>Save the image above to your HDD, and then create a new [empty] WPF application.&#xA0; Include the PNG file in an &#x2018;Assets&#x2019; folder in the project, and then paste the following XAML into MainWindow.xaml:</p>
<pre class="highlight"><code class="hljs xml">    <span class="hljs-tag">&lt;<span class="hljs-name">Image</span> <span class="hljs-attr">x:Name</span>=<span class="hljs-string">&quot;lemming&quot;</span> <span class="hljs-attr">Source</span>=<span class="hljs-string">&quot;Assets/TPLemming.png&quot;</span> <span class="hljs-attr">Stretch</span>=<span class="hljs-string">&quot;None&quot;</span> <span class="hljs-attr">HorizontalAlignment</span>=<span class="hljs-string">&quot;Center&quot;</span> <span class="hljs-attr">RenderTransformOrigin</span>=<span class="hljs-string">&quot;0.5,0.5&quot;</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Image.Resources</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Storyboard</span> <span class="hljs-attr">x:Key</span>=<span class="hljs-string">&quot;Walk&quot;</span> <span class="hljs-attr">AutoReverse</span>=<span class="hljs-string">&quot;True&quot;</span> <span class="hljs-attr">RepeatBehavior</span>=<span class="hljs-string">&quot;Forever&quot;</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">DoubleAnimationUsingKeyFrames</span> <span class="hljs-attr">Storyboard.TargetProperty</span>=<span class="hljs-string">&quot;(UIElement.RenderTransform).(TranslateTransform.X)&quot;</span> <span class="hljs-attr">Storyboard.TargetName</span>=<span class="hljs-string">&quot;lemming&quot;</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">DiscreteDoubleKeyFrame</span> <span class="hljs-attr">KeyTime</span>=<span class="hljs-string">&quot;0:0:0.5&quot;</span> <span class="hljs-attr">Value</span>=<span class="hljs-string">&quot;-55&quot;</span> /&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">DiscreteDoubleKeyFrame</span> <span class="hljs-attr">KeyTime</span>=<span class="hljs-string">&quot;0:0:1&quot;</span> <span class="hljs-attr">Value</span>=<span class="hljs-string">&quot;61&quot;</span> /&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">DoubleAnimationUsingKeyFrames</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">PointAnimationUsingKeyFrames</span> <span class="hljs-attr">Storyboard.TargetProperty</span>=<span class="hljs-string">&quot;(UIElement.Clip).(PathGeometry.Figures)[0].(PathFigure.StartPoint)&quot;</span> <span class="hljs-attr">Storyboard.TargetName</span>=<span class="hljs-string">&quot;lemming&quot;</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">PointKeyFrameCollection</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">DiscretePointKeyFrame</span> <span class="hljs-attr">KeyTime</span>=<span class="hljs-string">&quot;0:0:0.5&quot;</span> <span class="hljs-attr">Value</span>=<span class="hljs-string">&quot;122,0&quot;</span> /&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">DiscretePointKeyFrame</span> <span class="hljs-attr">KeyTime</span>=<span class="hljs-string">&quot;0:0:1&quot;</span> <span class="hljs-attr">Value</span>=<span class="hljs-string">&quot;0,0&quot;</span> /&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">PointKeyFrameCollection</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">PointAnimationUsingKeyFrames</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">PointAnimationUsingKeyFrames</span> <span class="hljs-attr">Storyboard.TargetProperty</span>=<span class="hljs-string">&quot;(UIElement.Clip).(PathGeometry.Figures)[0].(PathFigure.Segments)[0].(LineSegment.Point)&quot;</span> <span class="hljs-attr">Storyboard.TargetName</span>=<span class="hljs-string">&quot;lemming&quot;</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">PointKeyFrameCollection</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">DiscretePointKeyFrame</span> <span class="hljs-attr">KeyTime</span>=<span class="hljs-string">&quot;0:0:0.5&quot;</span> <span class="hljs-attr">Value</span>=<span class="hljs-string">&quot;244,0&quot;</span> /&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">DiscretePointKeyFrame</span> <span class="hljs-attr">KeyTime</span>=<span class="hljs-string">&quot;0:0:1&quot;</span> <span class="hljs-attr">Value</span>=<span class="hljs-string">&quot;122,0&quot;</span> /&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">PointKeyFrameCollection</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">PointAnimationUsingKeyFrames</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">PointAnimationUsingKeyFrames</span> <span class="hljs-attr">Storyboard.TargetProperty</span>=<span class="hljs-string">&quot;(UIElement.Clip).(PathGeometry.Figures)[0].(PathFigure.Segments)[1].(LineSegment.Point)&quot;</span> <span class="hljs-attr">Storyboard.TargetName</span>=<span class="hljs-string">&quot;lemming&quot;</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">PointKeyFrameCollection</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">DiscretePointKeyFrame</span> <span class="hljs-attr">KeyTime</span>=<span class="hljs-string">&quot;0:0:0.5&quot;</span> <span class="hljs-attr">Value</span>=<span class="hljs-string">&quot;244,244&quot;</span> /&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">DiscretePointKeyFrame</span> <span class="hljs-attr">KeyTime</span>=<span class="hljs-string">&quot;0:0:1&quot;</span> <span class="hljs-attr">Value</span>=<span class="hljs-string">&quot;122,244&quot;</span> /&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">PointKeyFrameCollection</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">PointAnimationUsingKeyFrames</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">PointAnimationUsingKeyFrames</span> <span class="hljs-attr">Storyboard.TargetProperty</span>=<span class="hljs-string">&quot;(UIElement.Clip).(PathGeometry.Figures)[0].(PathFigure.Segments)[2].(LineSegment.Point)&quot;</span> <span class="hljs-attr">Storyboard.TargetName</span>=<span class="hljs-string">&quot;lemming&quot;</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">PointKeyFrameCollection</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">DiscretePointKeyFrame</span> <span class="hljs-attr">KeyTime</span>=<span class="hljs-string">&quot;0:0:0.5&quot;</span> <span class="hljs-attr">Value</span>=<span class="hljs-string">&quot;122,244&quot;</span> /&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">DiscretePointKeyFrame</span> <span class="hljs-attr">KeyTime</span>=<span class="hljs-string">&quot;0:0:1&quot;</span> <span class="hljs-attr">Value</span>=<span class="hljs-string">&quot;0,244&quot;</span> /&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">PointKeyFrameCollection</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">PointAnimationUsingKeyFrames</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">Storyboard</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">Image.Resources</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Image.Triggers</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">EventTrigger</span> <span class="hljs-attr">RoutedEvent</span>=<span class="hljs-string">&quot;FrameworkElement.Loaded&quot;</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">BeginStoryboard</span> <span class="hljs-attr">Storyboard</span>=<span class="hljs-string">&quot;{StaticResource Walk}&quot;</span> /&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">EventTrigger</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">Image.Triggers</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">Image.RenderTransform</span>&gt;</span>
             <span class="hljs-tag">&lt;<span class="hljs-name">TranslateTransform</span> <span class="hljs-attr">X</span>=<span class="hljs-string">&quot;61&quot;</span>/&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">Image.RenderTransform</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Image.Clip</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">PathGeometry</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">PathFigure</span> <span class="hljs-attr">IsClosed</span>=<span class="hljs-string">&quot;True&quot;</span> <span class="hljs-attr">StartPoint</span>=<span class="hljs-string">&quot;0,0&quot;</span>&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">LineSegment</span> <span class="hljs-attr">Point</span>=<span class="hljs-string">&quot;122,0&quot;</span> /&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">LineSegment</span> <span class="hljs-attr">Point</span>=<span class="hljs-string">&quot;122,244&quot;</span> /&gt;</span>
                    <span class="hljs-tag">&lt;<span class="hljs-name">LineSegment</span> <span class="hljs-attr">Point</span>=<span class="hljs-string">&quot;0,244&quot;</span> /&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">PathFigure</span>&gt;</span>
            <span class="hljs-tag">&lt;/<span class="hljs-name">PathGeometry</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">Image.Clip</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">Image</span>&gt;</span>
</code></pre>
<p>Enjoy!</p>
</div>]]></content>
    </entry>
    
    <entry>
      <title>Binding Flagged Enumerations</title>
      <link href="http://www.virtual-olympus.com/posts/2011/10/Binding-Flagged-Enumerations/"/>
      <updated>2011-10-13T00:00:00.000Z</updated>
      <id>/posts/2011/10/Binding-Flagged-Enumerations/</id>
      <content type="html"><![CDATA[<div><h2 id="introduction">Introduction</h2>
<p>Recently a tweet brought my attention to <a href="http://blog.arsanth.com/index.php/2011/10/11/arsanth-october-11th/">this blog post</a> by <a href="http://twitter.com/#!/san0x">@san0x</a>, regarding the difficulties of binding flagged enumerations to UI fields in a meaningful and easy-to-use fashion.&#xA0; The post was largely dealing with ways to work around the limitation of the IValueConverter, and its &#x2018;context agnostic&#x2019; processing of values during the conversion process.&#xA0; The IValueConverter does not know the context of the value being converted, only the value itself and an [unbindable] conversion parameter.</p>
<h2 id="scenario">Scenario</h2>
<p>I&#x2019;ll avoid going into great detail about the scenario here, as it&#x2019;s explained in detail in the linked post above, but the main focus is binding a series of checkboxes to a single flagged enumeration value.&#xA0; The classes I&#x2019;ll use in my example are adapted from the original post, I&#x2019;ve included them here as a convenience to the reader.</p>
<pre class="highlight"><code class="hljs c">    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> Species : ViewModelBase
    {
        <span class="hljs-comment">/// </span>
        <span class="hljs-comment">/// The  property&apos;s name.</span>
        <span class="hljs-comment">/// </span>
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">const</span> <span class="hljs-built_in">string</span> NamePropertyName = <span class="hljs-string">&quot;Name&quot;</span>;

        <span class="hljs-keyword">private</span> <span class="hljs-built_in">string</span> _name = String.Empty;

        <span class="hljs-comment">/// </span>
        <span class="hljs-comment">/// The species name</span>
        <span class="hljs-comment">/// </span>
        <span class="hljs-keyword">public</span> <span class="hljs-built_in">string</span> Name
        {
            get
            {
                <span class="hljs-keyword">return</span> _name;
            }

            <span class="hljs-built_in">set</span>
            {
                <span class="hljs-keyword">if</span> (_name == value)
                {
                    <span class="hljs-keyword">return</span>;
                }

                var oldValue = _name;
                _name = value;

                <span class="hljs-comment">// Update bindings, no broadcast</span>
                RaisePropertyChanged(NamePropertyName);
            }
        }

        <span class="hljs-comment">/// </span>
        <span class="hljs-comment">/// The  property&apos;s name.</span>
        <span class="hljs-comment">/// </span>
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">const</span> <span class="hljs-built_in">string</span> FlagsPropertyName = <span class="hljs-string">&quot;Flags&quot;</span>;

        <span class="hljs-keyword">private</span> SpeciesFlag _flags = SpeciesFlag.None;

        <span class="hljs-comment">/// </span>
        <span class="hljs-comment">/// The properties of the species, as a flagged enumeration</span>
        <span class="hljs-comment">/// </span>
        <span class="hljs-keyword">public</span> SpeciesFlag Flags
        {
            get
            {
                <span class="hljs-keyword">return</span> _flags;
            }

            <span class="hljs-built_in">set</span>
            {
                <span class="hljs-keyword">if</span> (_flags == value)
                {
                    <span class="hljs-keyword">return</span>;
                }

                var oldValue = _flags;
                _flags = value;

                <span class="hljs-comment">// Update bindings, no broadcast</span>
                RaisePropertyChanged(FlagsPropertyName);
            }
        }
    }
</code></pre>
<pre class="highlight"><code class="hljs c">    [Flags]
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">enum</span> SpeciesFlag : byte
    {
        None = <span class="hljs-number">0</span>,
        BreathesAir = <span class="hljs-number">0x1</span>,
        BreathesWater = <span class="hljs-number">0x2</span>,
        Photosynthesizes = <span class="hljs-number">0x4</span>,
        Eats = <span class="hljs-number">0x8</span>
    }
</code></pre>
<p>Note: My examples use the excellent <a href="http://galasoft.ch/mvvm/">MVVM Light Toolkit</a> by @LBugnion, but are NOT intended to be examples of best practices when using the toolkit</p>
<p>&#xA0;</p>
<h2 id="potential-solutions">Potential Solutions</h2>
<p>Many developers [myself included], when presented with these types of problems, take a similar route to @san0x, attempting to coerce the value converter into something that is context-aware in any number of ways.&#xA0; My personal investigations led me to first investigate using WPF <a href="http://www.switchonthecode.com/tutorials/wpf-tutorial-using-multibindings">MultiBinding</a> [a little used, but occasionally very handy feature].&#xA0; The promise of the MultiBinding was that I could pass in a number of bound values, and get back a suitable result [true/false].&#xA0; As things usually go [for me at least], this worked fabulously for the first 50% of the problem, binding from the source &#x2013;&gt; the CheckBox.IsSelected property worked just as expected with a binding very similar to this:</p>
<pre class="highlight"><code class="hljs xml"><span class="hljs-tag">&lt;<span class="hljs-name">CheckBox.IsChecked</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">MultiBinding</span> <span class="hljs-attr">Mode</span>=<span class="hljs-string">&quot;TwoWay&quot;</span> 
                   <span class="hljs-attr">Converter</span>=<span class="hljs-string">&quot;{StaticResource FlaggedEnumToBoolMultiConverter}&quot;</span> <span class="hljs-attr">ConverterParameter</span>=<span class="hljs-string">&quot;BreathesAir&quot;</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Binding</span> <span class="hljs-attr">Path</span>=<span class="hljs-string">&quot;Species&quot;</span> /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Binding</span> <span class="hljs-attr">Path</span>=<span class="hljs-string">&quot;Species.Flags&quot;</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">MultiBinding</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">CheckBox.IsChecked</span>&gt;</span>
</code></pre>
<p>&#xA0;</p>
<p>This allowed me to reflect the flag value on the CheckBox, and changes to the value were automatically reflected on the UI without a lot of additional work.&#xA0; The issue, of course, was how to update the underlying object when the CheckBox itself is used to change the value.&#xA0; This is much harder, because the IMultiValueConverter::ConvertBack method has two problems:</p>
<ol>
<li>Only a single [boolean] value, and [object] parameter are passed to the ConvertBack method.</li>
<li>ConvertBack must pass back an array of values, one for each Binding contained in the MultiBinding.</li>
</ol>
<p>So&#x2026; we&#x2019;re stuck&#x2026; there&#x2019;s no way to convert from a single boolean back into a Species and its flags while only effecting the single &#x2018;bit&#x2019; or &#x2018;bits&#x2019; we care about.&#xA0; We simply do not have enough information available to us as the time of conversion.&#xA0; Sure, there are workarounds, and one such workaround is listed in <a href="http://blog.arsanth.com/index.php/2011/10/12/arsanth-october-12th/">@san0x&#x2019;s follow-up post</a> [using a standard IValueConverter], but in the end, those workarounds all &#x2018;smell&#x2019; like hacks to me.&#xA0; They all involve keeping the context of the binding around in some fashion during conversion.</p>
<h2 id="reframing-the-problem">Reframing the Problem</h2>
<p>My suggestion on Twitter was to utilize the ViewModel to expose the individual flags as bindable properties to the View.&#xA0; This successfully reframes the problem, but does suffer from the requirement that you update your ViewModel every time your enumeration changes [the View needs to be updated with any solution, since we&#x2019;re using individual CheckBox(s)].&#xA0; This &#x2018;smells&#x2019; better to me simply because it does what ViewModel&#x2019;s are supposed to do, abstract away the underlying model when necessary to make data binding feasible.&#xA0; It also doesn&#x2019;t resort to any of the same hacks required to get binding to work properly, and context is retained because it&#x2019;s handled by the bound view model.</p>
<h2 id="proposed-solution">Proposed Solution</h2>
<p>So with the reframing of the question in mind, I moved on to whether or not it would be possible to simplify the process of binding to that flagged enumeration.&#xA0; I wanted to minimize coding effort, and have the solution work for any general flagged enumeration.&#xA0; Back in the .NET 1.x/2.x days, I had worked on a number of projects that leveraged the <a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.icustomtypedescriptor.aspx">ICustomTypeDescriptor</a> and it&#x2019;s siblings to provide customized design and run-time behavior for objects and properties.&#xA0; Silverlight 5 and .NET 4.5 bring the <a href="http://msdn.microsoft.com/en-us/library/system.reflection.icustomtypeprovider(v=vs.110).aspx">ICustomTypeProvider</a> to bear on the problem, and could be used in those environments.&#xA0; For this post, since we&#x2019;re running WPF and .NET 4.0, I&#x2019;m going to utilize <a href="http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject.aspx">DynamicObject</a> to provide for runtime binding of the flagged enumeration values.</p>
<h3 id="the-flaggedenumviewmodel-class">The FlaggedEnumViewModel Class</h3>
<p>I&#x2019;ll start by introducing the class that enables runtime binding and implements the bits necessary for the bindings to resolve properly:</p>
<pre class="highlight"><code class="hljs undefined">    public class FlaggedEnumViewModel&lt;TEnum&gt;: DynamicObject, INotifyPropertyChanged
    {
        private Func&lt;TEnum&gt; _getter;
        private Action&lt;TEnum&gt; _setter;

        public FlaggedEnumViewModel(Func&lt;TEnum&gt; getter, Action&lt;TEnum&gt; setter)
        {
            if (!typeof(TEnum).IsEnum) 
                throw new ArgumentException(&quot;This type must only be used with enumerations.&quot;);

            _getter = getter;
            _setter = setter;
        }

        public override DynamicMetaObject GetMetaObject(System.Linq.Expressions.Expression parameter)
        {
            return base.GetMetaObject(parameter);
        }
        public override IEnumerable&lt;string&gt; GetDynamicMemberNames()
        {
            return Enum.GetNames(typeof(TEnum)).Select(i =&gt; &quot;Has&quot; + i);
        }

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            if (!binder.Name.ToLower().StartsWith(&quot;has&quot;) &apos;&apos; binder.Name.Length &lt; 4)
            {
                result = null;
                return false;
            }

            long checkedFlag = Convert.ToInt64(Enum.Parse(typeof(TEnum), binder.Name.Substring(3), true));
            long currentValue = Convert.ToInt64(_getter());

            result = (checkedFlag &amp; currentValue) != 0;
            return true;
        }

        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            if (!binder.Name.ToLower().StartsWith(&quot;has&quot;) &apos;&apos; binder.Name.Length &lt; 4)
            {
                return false;
            }

            long checkedFlag = Convert.ToInt64(Enum.Parse(typeof(TEnum), binder.Name.Substring(3), true));
            long currentValue = Convert.ToInt64(_getter());

            if ((bool)value == true)
            {
                currentValue &apos;= checkedFlag;
            }
            else
            {
                currentValue &amp;= ~checkedFlag;
            }

            _setter((TEnum)Enum.ToObject(typeof(TEnum), currentValue));

            OnPropertyChanged(binder.Name);

            return true;
        }

        protected void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
</code></pre>
<p>&#xA0;</p>
<p>In the above code, I&#x2019;ll call attention to three bits:</p>
<ol>
<li>The constructor takes a &#x2018;getter&#x2019; and &#x2018;setter&#x2019; argument that wraps access to the underlying flagged enum store.</li>
<li>The TryGetMember method handles converting from the flagged value to a boolean</li>
<li>The TrySetMember method handles converting from the boolean back to the flagged value</li>
</ol>
<p>&#xA0;</p>
<h3 id="the-view-viewmodel">The View/ViewModel</h3>
<p>Utilizing the class is fairly straightforward, in my ViewModel, I&#x2019;ve exposed a property [WrappedFlags] of the FlaggedEnumViewModel type that I use for binding on the UI, and the &#x2018;Species&#x2019; property notifies that both properties change whenever the Species property changes.&#xA0; This is sufficient to enable TwoWay binding on the View.</p>
<pre class="highlight"><code class="hljs c">    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> MainViewModel : ViewModelBase
    {
        <span class="hljs-keyword">public</span> <span class="hljs-built_in">string</span> Welcome
        {
            get
            {
                <span class="hljs-keyword">return</span> <span class="hljs-string">&quot;Sample Flagged Enum Editor&quot;</span>;
            }
        }

        <span class="hljs-comment">/// &lt;summary&gt;</span>
        <span class="hljs-comment">/// Initializes a new instance of the MainViewModel class.</span>
        <span class="hljs-comment">/// &lt;/summary&gt;</span>
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">MainViewModel</span><span class="hljs-params">()</span>
        </span>{
            <span class="hljs-keyword">if</span> (IsInDesignMode)
            {
                <span class="hljs-comment">// Code runs in Blend --&gt; create design time data.</span>
            }
            <span class="hljs-keyword">else</span>
            {
                <span class="hljs-comment">// Code runs &quot;for real&quot;</span>
            }

            LoadRandomSpecies = <span class="hljs-keyword">new</span> RelayCommand(() =&gt; AssignRandomSpecies());
            WrappedFlags = <span class="hljs-keyword">new</span> FlaggedEnumViewModel&lt;SpeciesFlag&gt;(
                                   () =&gt; Species.Flags, 
                                   (v) =&gt; Species.Flags = v);
        }

        <span class="hljs-comment">/// &lt;summary&gt;</span>
        <span class="hljs-comment">/// The &lt;see cref=&quot;Species&quot; /&gt; property&apos;s name.</span>
        <span class="hljs-comment">/// &lt;/summary&gt;</span>
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">const</span> <span class="hljs-built_in">string</span> SpeciesPropertyName = <span class="hljs-string">&quot;Species&quot;</span>;

        <span class="hljs-keyword">private</span> Species _species = <span class="hljs-keyword">new</span> Species() { Name = <span class="hljs-string">&quot;Sample Species&quot;</span> };

        <span class="hljs-comment">/// &lt;summary&gt;</span>
        <span class="hljs-comment">/// The Species we&apos;re working with</span>
        <span class="hljs-comment">/// &lt;/summary&gt;</span>
        <span class="hljs-keyword">public</span> Species Species
        {
            get
            {
                <span class="hljs-keyword">return</span> _species;
            }

            <span class="hljs-built_in">set</span>
            {
                <span class="hljs-keyword">if</span> (_species == value)
                {
                    <span class="hljs-keyword">return</span>;
                }

                var oldValue = _species;
                _species = value;

                <span class="hljs-comment">// Update bindings, no broadcast</span>
                RaisePropertyChanged(SpeciesPropertyName);
                RaisePropertyChanged(<span class="hljs-string">&quot;WrappedFlags&quot;</span>);
            }
        }

        <span class="hljs-keyword">public</span> FlaggedEnumViewModel&lt;SpeciesFlag&gt; WrappedFlags { get; <span class="hljs-keyword">private</span> <span class="hljs-built_in">set</span>; }

        <span class="hljs-keyword">public</span> RelayCommand LoadRandomSpecies { get; <span class="hljs-keyword">private</span> <span class="hljs-built_in">set</span>; }

        <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">AssignRandomSpecies</span><span class="hljs-params">()</span>
        </span>{
            Random rnd = <span class="hljs-keyword">new</span> Random();
            byte value = (byte)rnd.Next(<span class="hljs-number">0</span>, <span class="hljs-number">16</span>);

            Species = <span class="hljs-keyword">new</span> Species()
            {
                Name = <span class="hljs-string">&quot;Random Species &quot;</span> + value.ToString(),
                Flags = (SpeciesFlag)value
            };
        }
    }
</code></pre>
<p>&#xA0;</p>
<p>Lastly, the view code is pretty basic, I&#x2019;ll just call out one of the CheckBox elements to show how the binding was done:</p>
<pre class="highlight"><code class="hljs xml">    <span class="hljs-tag">&lt;<span class="hljs-name">CheckBox</span> <span class="hljs-attr">Content</span>=<span class="hljs-string">&quot;Breathes Air&quot;</span> 
               <span class="hljs-attr">IsChecked</span>=<span class="hljs-string">&quot;{Binding Path=WrappedFlags.HasBreathesAir, Mode=TwoWay}&quot;</span> /&gt;</span>
</code></pre>
<p>&#xA0;</p>
<h2 id="conclusion">Conclusion</h2>
<p>Transitioning from a converter-based approach to enhancing the ViewModel makes the problem much easier to implement and troubleshoot, it also avoids many of the pitfalls of introducing state to your I[Multi]ValueConverter instances.&#xA0; Utilizing a DynamicObject class derivative enables you to write much less code and get the same overall benefit at runtime.&#xA0; In a future post, I hope to find time to walk through enhancing the design-time experience to support setting up bindings in the VS2010 XAML designer.&#xA0; I look forward to hearing your comments, or seeing alternative solutions to the problem.</p>
<p>Thanks for reading!</p>
<p>Sample Code: <a href="http://www.virtual-olympus.com/posts/2011/10/Binding-Flagged-Enumerations/WPFBindingFlaggedEnum-20111013.zip">WPFBindingFlaggedEnum-20111013.zip (19 kb)</a></p>
</div>]]></content>
    </entry>
    
    <entry>
      <title>Creating a bootable Win8 VHD from the #BldWin USB Drive</title>
      <link href="http://www.virtual-olympus.com/posts/2011/09/Creating-a-bootable-Win8-VHD-from-the-BldWin-USB-Drive/"/>
      <updated>2011-09-13T00:00:00.000Z</updated>
      <id>/posts/2011/09/Creating-a-bootable-Win8-VHD-from-the-BldWin-USB-Drive/</id>
      <content type="html"><![CDATA[<div><h1 id="intro">Intro</h1>
<p>Everyone who attended //BUILD this year received two things:</p>
<ol>
<li>A new Samsung Developer tablet which I won&#x2019;t detail here, there&#x2019;s sure to be loads of information out there beyond what I could provide here</li>
<li>A 32GB USB stick with all the Win8 //BUILD bits on it</li>
</ol>
<p>So, naturally, my quest was to get my laptop and tablet talking to each other, both using the Windows 8 developer preview.&#xA0; To do that, I needed to get Win8 running on the laptop.&#xA0; The &#x2018;best&#x2019; option I saw, given that the USB stick contains ONLY 64-bit stuff, was to go &#x2018;to the metal&#x2019; and create a bootable VHD.</p>
<h1 id="how-to-do-it">How to do it</h1>
<p>The steps here are pretty straightforward, so I&#x2019;ll just lay them out for you here.&#xA0; NOTE:&#xA0; This requires Window 7 Enterprise or Ultimate to be installed on the destination machine:</p>
<h3 id="1-nbsp-create-a-new-empty-vhd">1.&#xA0; Create a new empty VHD</h3>
<ol>
<li>Right-click your computer and choose &#x2018;Manage&#x2019;</li>
<li>Switch to the &#x2018;Disk Management&#x2019; area</li>
<li>Choose Action-&gt;Create VHD</li>
<li>I chose a basic 32GB partition [fixed size] and choose a location.&#xA0; For this example, I created one on my hard drive in &#x201C;C:\Virtual Machines\Win8.vhd&#x201D; and click &#x2018;OK&#x2019;</li>
<li>Right-click on the newly attached VHD and choose &#x2018;Initialize Disk&#x2019;, I chose the MBR option, then click OK</li>
<li>Detach the resulting VHD</li>
</ol>
<h3 id="2-plug-in-build-usb-drive">2. Plug in //BUILD USB Drive</h3>
<p>You can do this step whenever you like while the computer is rebooting, I chose to just do it before I started the reboot process.</p>
<h3 id="3-nbsp-reboot-your-computer">3.&#xA0; Reboot your Computer</h3>
<p>This step is crucial, and your machine MUST be setup to boot from any plugged in USB device.</p>
<h3 id="4-nbsp-enter-win8-setup-but-not-all-the-way-">4.&#xA0; Enter Win8 setup [but not all the way]</h3>
<p>When the computer boots, you&#x2019;ll be presented with the Win8 setup process, choose your keyboard layout and such and enter the setup process BUT DO NOT CLICK &#x2018;INSTALL&#x2019;.</p>
<h3 id="5-nbsp-enter-the-lsquo-repair-rsquo-area">5.&#xA0; Enter the &#x2018;Repair&#x2019; area</h3>
<p>Below the &#x2018;Install Now&#x2019; button, there should be a repair link that lets you repair a PC.&#xA0; Somewhere in this menu is an option to launch a command window [under Advanced &#x2013;&gt; Command Prompt ??].&#xA0; Do this and then enter the DISKPART utility.</p>
<h3 id="6-nbsp-select-and-attach-the-empty-vhd">6.&#xA0; SELECT and ATTACH the empty VHD</h3>
<p>Once in DISKPART, you need to select and attach your VHD [yes, this feels backwards].&#xA0; This will enable setup to see the drive and continue.&#xA0; This requires two commands:</p>
<ol>
<li>SELECT VDISK FILE=&#x201D;C:\Virtual Machines\Win8.vhd&#x201D;</li>
<li>ATTACH VDISK</li>
<li>EXIT</li>
</ol>
<h3 id="7-nbsp-resume-installation-process">7.&#xA0; Resume installation process</h3>
<p>Once done attaching the VHD, you can proceed with the install.&#xA0; To do this, I just went back up to the root drive &#x2018;X:&#x2019; in my case, and typed &#x2018;setup.exe&#x2019;.&#xA0; This re-launches the setup UI and allows you to click &#x2018;Install Now&#x2019;.&#xA0; During the install process, choose &#x2018;Custom&#x2019;.</p>
<h3 id="8-nbsp-finish-vhd-setup">8.&#xA0; Finish VHD Setup</h3>
<p>Inside the custom setup, when choosing the destination for the install, make sure you choose the newly attached VHD [usually the 30ish GB area listed as &#x2018;Unallocated&#x2019;].&#xA0; Select that partition and click &#x2018;New&#x2019; to create a new partition on the VHD, selecting the default size.&#xA0; Then click &#x2018;Format&#x2019; to format the associated partition.&#xA0; Finally select the newly formatted partition and click &#x2018;Next&#x2019;.</p>
<p>NOTE:&#xA0; The UI will tell you that it can&#x2019;t install to that partition, but ignore the error and just click &#x2018;Next&#x2019;.</p>
<h3 id="9-nbsp-wait-hellip-until-the-install-process-finishes-and-when-it-starts-to-reboot-pull-the-usb-stick">9.&#xA0; WAIT&#x2026; until the install process finishes, and when it starts to reboot, pull the USB stick</h3>
<p>I don&#x2019;t know if this is strictly necessary, but I did it to ensure I didn&#x2019;t boot back to the USB again in error.&#xA0; Win8 will have taken over your boot process and will complete the install and present you with the &#x2018;developer preview&#x2019; software agreements and whatnot.</p>
<h3 id="10-nbsp-there-is-no-10">10.&#xA0; There is no #10</h3>
<p>&apos;That&#x2019;s it&apos;!&#xA0; Everything is working as expected, enjoy your new Win8 laptop!</p>
<p>&#xA0;</p>
<p>It should be noted, that just like Win7, when the machine is starting up [after BIOS], you can hit F8 to get the boot menu [this is slow to come up], and choose &#x2018;another OS&#x2019; and then choose to boot onto your Windows 7 machine as you used to.&#xA0; You can probably also use bcdedit to set your Win7 install to be the default and use F8 from there to get into Win8 as desired.&#xA0; I won&#x2019;t detail those bits here, since they&#x2019;ve been covered numerous times on other blogs.</p>
<p>&#xA0;</p>
<p>That&#x2019;s it, and as always, anything you do to your machine using these steps IS YOUR RESPONSIBILITY.&#xA0; I accept no liability for any damage resulting from following these instructions <img src="http://www.virtual-olympus.com/posts/2011/09/Creating-a-bootable-Win8-VHD-from-the-BldWin-USB-Drive/wlEmoticon-smile.png" alt="Smile"></p>
</div>]]></content>
    </entry>
    
</feed>