Revision: 4436
          http://cel.svn.sourceforge.net/cel/?rev=4436&view=rev
Author:   jorrit
Date:     2011-09-19 12:57:14 +0000 (Mon, 19 Sep 2011)
Log Message:
-----------
- Fixed meshselect property class so that it is more robust while sending
  out messages by protecting the current entity against deletion.
- Fixed the inventory UI classes so that they remove their inventory listeners
  when they are being closed.
- Added a method to DynamicWorld plugin to find a factory by name.
- Added a method to DynamicWorld plugin to find a dynamic object by entity.
- Added the ability to elcmtest to drop items on the ground from the player
  inventory. Currently works only for templates in the inventory and it will
  drop one instance at a time. For now you can only drop gold. You get an
  error if you try to drop anything else as the factories are not defined
  fully yet.
- Added the ability to elcmtest to pick up items and put them in the player
  inventory.

Modified Paths:
--------------
    cel/trunk/apps/elcmtest/elcmtest.cpp
    cel/trunk/apps/elcmtest/elcmtest.h
    cel/trunk/data/elcmtest.xml
    cel/trunk/include/propclass/dynworld.h
    cel/trunk/include/tools/uitools/inventory.h
    cel/trunk/plugins/propclass/dynworld/dynworld.cpp
    cel/trunk/plugins/propclass/dynworld/dynworld.h
    cel/trunk/plugins/propclass/mesh/meshfact.cpp
    cel/trunk/plugins/propclass/mesh/meshfact.h
    cel/trunk/plugins/tools/uitools/inventory/inventory.cpp
    cel/trunk/plugins/tools/uitools/inventory/inventory.h
    cel/trunk/plugins/tools/uitools/inventory2/inventory2.cpp
    cel/trunk/plugins/tools/uitools/inventory2/inventory2.h

Modified: cel/trunk/apps/elcmtest/elcmtest.cpp
===================================================================
--- cel/trunk/apps/elcmtest/elcmtest.cpp        2011-09-19 11:37:49 UTC (rev 
4435)
+++ cel/trunk/apps/elcmtest/elcmtest.cpp        2011-09-19 12:57:14 UTC (rev 
4436)
@@ -12,6 +12,7 @@
 #include "propclass/jump.h"
 #include "propclass/inv.h"
 #include <physicallayer/propclas.h>
+#include <physicallayer/entitytpl.h>
 #include <behaviourlayer/behave.h>
 #include <celtool/stdparams.h>
 
@@ -305,10 +306,39 @@
 
 void ElcmTest::SelectEntity (iCelEntity* entity)
 {
+  iPcInventory* inv = uiInventory->GetInventory ();
+  if (!inv) return;
+  //inv->RemoveEntity (entity);
 }
 
 void ElcmTest::SelectTemplate (iCelEntityTemplate* tpl)
 {
+  iPcInventory* inv = uiInventory->GetInventory ();
+  if (!inv) return;
+
+  if (!dynworld->FindFactory (tpl->GetName ()))
+  {
+    printf ("This item cannot be dropped!\n");
+    fflush (stdout);
+    return;
+  }
+
+  size_t idx = inv->FindEntityTemplate (tpl);
+  if (idx == csArrayItemNotFound)
+  {
+    printf ("Weird? Where did it go?\n");
+    return;
+  }
+  //int amount = inv->GetEntityTemplateAmount (idx);
+  inv->RemoveEntityTemplate (tpl, 1);  // @@@ Temporary!
+
+  csRef<iPcMesh> pcmesh = celQueryPropertyClassEntity<iPcMesh> (playerEntity);
+  csReversibleTransform trans = pcmesh->GetMesh ()->GetMovable 
()->GetFullTransform ();
+  trans.SetOrigin (trans.GetOrigin () + trans.GetFront () / 5.0f + trans.GetUp 
());
+  iDynamicObject* obj = dynworld->AddObject (tpl->GetName (), trans);
+  csRef<iCelParameterBlock> params;
+  params.AttachNew (new celVariableParameterBlock ());
+  obj->SetEntity (tpl->GetName (), params);
 }
 
 void ElcmTest::SelectEntity (iCelEntity* entity, bool left)
@@ -381,6 +411,27 @@
     }
     return true;
   }
+  else if (msg_id == msgPickupTpl)
+  {
+    const celData* data = params->GetParameterByIndex (0);
+    if (data->type != CEL_DATA_STRING)
+      return ReportError ("Invalid parameter for 'pickup' message. Expected 
string.");
+    iCelEntity* ent = pl->FindEntity (data->value.s->GetData ());
+    iDynamicObject* dynobj = dynworld->FindDynamicObject (ent);
+    if (dynobj)
+    {
+      iCelEntityTemplate* tpl = pl->FindEntityTemplate (dynobj->GetFactory 
()->GetName ());
+      if (tpl)
+      {
+        csRef<iPcInventory> inventory = 
celQueryPropertyClassEntity<iPcInventory> (
+           playerEntity);
+       inventory->AddEntityTemplate (tpl, 1);
+        dynworld->DeleteObject (dynobj);
+        pl->RemoveEntity (ent);
+      }
+    }
+    return true;
+  }
   return false;
 }
 
@@ -482,6 +533,7 @@
   elcm->SetUnloadCheckFrequency (30);
 
   msgInventory = pl->FetchStringID ("elcm.inventory");
+  msgPickupTpl = pl->FetchStringID ("elcm.pickup.tpl");
 
   ceguiPrinter.AttachNew (new CeguiPrinter (this));
   pl->CallbackEveryFrame (ceguiPrinter, CEL_EVENT_POST);

Modified: cel/trunk/apps/elcmtest/elcmtest.h
===================================================================
--- cel/trunk/apps/elcmtest/elcmtest.h  2011-09-19 11:37:49 UTC (rev 4435)
+++ cel/trunk/apps/elcmtest/elcmtest.h  2011-09-19 12:57:14 UTC (rev 4436)
@@ -53,6 +53,7 @@
 
   csRef<iMessageReceiver> receiver;
   csStringID msgInventory;
+  csStringID msgPickupTpl;
 
   /// Physics.
   csRef<iDynamics> dyn;

Modified: cel/trunk/data/elcmtest.xml
===================================================================
--- cel/trunk/data/elcmtest.xml 2011-09-19 11:37:49 UTC (rev 4435)
+++ cel/trunk/data/elcmtest.xml 2011-09-19 12:57:14 UTC (rev 4436)
@@ -1,9 +1,11 @@
 <library>
   <textures>
-    <texture name="parket.jpg"> <file>/lib/stdtex/parket.jpg</file> </texture>
+    <texture name="wood"> <file>/lib/stdtex/parket.jpg</file> </texture>
+    <texture name="marble"> <file>/lib/stdtex/andrew_marble4.jpg</file> 
</texture>
   </textures>
   <materials>
-    <material name="wood"> <texture>parket.jpg</texture> </material>
+    <material name="wood"> <texture>wood</texture> </material>
+    <material name="marble"> <texture>marble</texture> </material>
   </materials>
 
   <meshfact name="GlowBox">
@@ -17,14 +19,100 @@
     </params>
   </meshfact>
 
+  <meshfact name="Gold">
+    <plugin>crystalspace.mesh.loader.factory.genmesh</plugin>
+    <params>
+      <box>
+        <min x="-.1" y="0" z="-.1" />
+        <max x=".1" y=".2" z=".1" />
+      </box>
+      <material>marble</material>
+    </params>
+  </meshfact>
+
   <addon plugin="cel.addons.dynamicworld.loader">
     <dynworld name="world" />
-    <factory name="GlowBox" maxradius="1.0" imposterradius="-1.0" mass="1">
-      <box /> 
-    </factory>
+    <factory name="GlowBox" maxradius="1.0" imposterradius="-1.0" mass="1"> 
<box /> </factory>
+    <factory name="Gold" maxradius="0.8" imposterradius="-1.0" mass=".4"> <box 
/> </factory>
   </addon>
 
+    <addon plugin="cel.addons.questdef" >
+
+      <quest name="pickableObject">
+       <state name="init">
+         <trigger type="meshselect">
+           <fireon entity="$this" />
+           <reward type="debugprint" message="pickme" />
+           <reward type="message" entity="world" id="elcm.pickup.tpl">
+             <par name="entity" string="$this" />
+           </reward>
+           <reward type="newstate" state="init" />
+         </trigger>
+       </state>
+      </quest>
+
+      <quest name="jumperQuest">
+       <state name="init">
+         <trigger type="meshselect">
+           <fireon entity="$this" />
+           <reward type="debugprint" message="select" />
+           <reward type="action" entity="$this" pc="pcphysics.object" 
id="AddForceOnce">
+             <par name="force" vector3="0,4,0" />
+           </reward>
+           <reward type="message" entity="world" id="elcm.inventory">
+             <par name="entity" string="$this" />
+           </reward>
+           <reward type="newstate" state="init" />
+         </trigger>
+       </state>
+      </quest>
+
+      <quest name="glowQuest">
+        <state name="init">
+         <oninit>
+           <reward sequence='animglow' type='sequence' entity='$this' 
entity_tag='glow' />
+         </oninit>
+         <trigger type="sequencefinish">
+           <fireon entity="$this" sequence="animglow" entity_tag='glow'/>
+           <reward type="newstate" state="init2" />
+         </trigger>
+        </state>
+       <state name="init2">
+         <trigger type="timeout">
+           <fireon timeout='1' />
+           <reward type="newstate" state="init" />
+         </trigger>
+       </state>
+        <sequence name="animglow">
+          <op entity="$this" type="ambientmesh" duration="$dur" >
+           <abscolor red="0" green="0" blue="1" />
+          </op>
+         <delay time="$dur" />
+          <op entity="$this" type="ambientmesh" duration="$dur" >
+           <abscolor red="1" green="0" blue="0" />
+          </op>
+         <delay time="$dur" />
+        </sequence>
+      </quest>
+    </addon>
+
+    <addon plugin="cel.addons.celentitytpl" entityname="Base" >
+      <propclass name="pcobject.mesh" />
+      <propclass name="pcobject.mesh.select">
+        <action name="SetCamera" >
+          <par name="entity" string="player" />
+        </action>
+      </propclass>
+      <propclass name="pclogic.quest" tag="pickup">
+        <action name="NewQuest" >
+          <par name="name" string="pickableObject" />
+        </action>
+        <property name="state" string="init" />
+      </propclass>
+    </addon>
+
     <addon plugin="cel.addons.celentitytpl" entityname="Gold" >
+      <template name="Base" />
       <characteristic name="weight" value="0.02" />
     </addon>
     <addon plugin="cel.addons.celentitytpl" entityname="Diamond" >
@@ -92,53 +180,6 @@
        </selector>
     </addon>
 
-    <addon plugin="cel.addons.questdef" >
-
-      <quest name="jumperQuest">
-       <state name="init">
-         <trigger type="meshselect">
-           <fireon entity="$this" />
-           <reward type="debugprint" message="select" />
-           <reward type="action" entity="$this" pc="pcphysics.object" 
id="AddForceOnce">
-             <par name="force" vector3="0,4,0" />
-           </reward>
-           <reward type="message" entity="world" id="elcm.inventory">
-             <par name="entity" string="$this" />
-           </reward>
-           <reward type="newstate" state="init" />
-         </trigger>
-       </state>
-      </quest>
-
-      <quest name="glowQuest">
-        <state name="init">
-         <oninit>
-           <reward sequence='animglow' type='sequence' entity='$this' 
entity_tag='glow' />
-         </oninit>
-         <trigger type="sequencefinish">
-           <fireon entity="$this" sequence="animglow" entity_tag='glow'/>
-           <reward type="newstate" state="init2" />
-         </trigger>
-        </state>
-       <state name="init2">
-         <trigger type="timeout">
-           <fireon timeout='1' />
-           <reward type="newstate" state="init" />
-         </trigger>
-       </state>
-        <sequence name="animglow">
-          <op entity="$this" type="ambientmesh" duration="$dur" >
-           <abscolor red="0" green="0" blue="1" />
-          </op>
-         <delay time="$dur" />
-          <op entity="$this" type="ambientmesh" duration="$dur" >
-           <abscolor red="1" green="0" blue="0" />
-          </op>
-         <delay time="$dur" />
-        </sequence>
-      </quest>
-    </addon>
-
     <addon plugin="cel.addons.celentitytpl" entityname="GlowBox" >
       <propclass name="pcobject.mesh" />
       <propclass name="pcobject.mesh.select">

Modified: cel/trunk/include/propclass/dynworld.h
===================================================================
--- cel/trunk/include/propclass/dynworld.h      2011-09-19 11:37:49 UTC (rev 
4435)
+++ cel/trunk/include/propclass/dynworld.h      2011-09-19 12:57:14 UTC (rev 
4436)
@@ -247,6 +247,11 @@
    */
   virtual iDynamicFactory* GetFactory (size_t index) const = 0;
 
+  /**
+   * Find a factory.
+   */
+  virtual iDynamicFactory* FindFactory (const char* name) const = 0;
+
   
//------------------------------------------------------------------------------
 
   /**
@@ -273,6 +278,11 @@
   virtual void DeleteObjects () = 0;
 
   /**
+   * Find a dynamic object from the entity.
+   */
+  virtual iDynamicObject* FindDynamicObject (iCelEntity* entity) const = 0;
+
+  /**
    * Set the sector for this dynamic world.
    */
   virtual void Setup (iSector* sector, iDynamicSystem* dynSys) = 0;

Modified: cel/trunk/include/tools/uitools/inventory.h
===================================================================
--- cel/trunk/include/tools/uitools/inventory.h 2011-09-19 11:37:49 UTC (rev 
4435)
+++ cel/trunk/include/tools/uitools/inventory.h 2011-09-19 12:57:14 UTC (rev 
4436)
@@ -46,6 +46,8 @@
   virtual void Open (const char* title, iPcInventory* inventory) = 0;
   /// Close the inventory.
   virtual void Close () = 0;
+  /// While the inventory is open you can query the inventory.
+  virtual iPcInventory* GetInventory () const = 0;
 
   /// Add a new selection listener.
   virtual void AddSelectionListener (iUIInventorySelectionCallback* cb) = 0;

Modified: cel/trunk/plugins/propclass/dynworld/dynworld.cpp
===================================================================
--- cel/trunk/plugins/propclass/dynworld/dynworld.cpp   2011-09-19 11:37:49 UTC 
(rev 4435)
+++ cel/trunk/plugins/propclass/dynworld/dynworld.cpp   2011-09-19 12:57:14 UTC 
(rev 4436)
@@ -597,6 +597,14 @@
   factories.Delete (static_cast<DynamicFactory*> (factory));
 }
 
+iDynamicFactory* celPcDynamicWorld::FindFactory (const char* name) const
+{
+  for (size_t i = 0 ; i < factories.GetSize () ; i++)
+    if (factories[i]->GetCsName () == name)
+      return factories[i];
+  return 0;
+}
+
 void celPcDynamicWorld::DeleteFactories ()
 {
   factory_hash.DeleteAll ();
@@ -660,13 +668,24 @@
   }
 }
 
+iDynamicObject* celPcDynamicWorld::FindDynamicObject (iCelEntity* entity) const
+{
+  //@@@ Not very efficient!
+  for (size_t i = 0 ; i < objects.GetSize () ; i++)
+  {
+    if (objects[i]->GetEntity () == entity)
+      return objects[i];
+  }
+  return 0;
+}
+
 void celPcDynamicWorld::RemoveSafeEntities ()
 {
   csSet<csPtrKey<iCelEntity> >::GlobalIterator it = safeToRemove.GetIterator 
();
   while (it.HasNext ())
   {
     iCelEntity* entity = it.Next ();
-    printf ("Actually remove entity %s\n", entity->QueryObject ()->GetName 
()); fflush (stdout);
+    printf ("Actually remove entity %s\n", entity->GetName ()); fflush 
(stdout);
     pl->RemoveEntity (entity);
   }
   safeToRemove.DeleteAll ();

Modified: cel/trunk/plugins/propclass/dynworld/dynworld.h
===================================================================
--- cel/trunk/plugins/propclass/dynworld/dynworld.h     2011-09-19 11:37:49 UTC 
(rev 4435)
+++ cel/trunk/plugins/propclass/dynworld/dynworld.h     2011-09-19 12:57:14 UTC 
(rev 4436)
@@ -259,6 +259,7 @@
   const csPDelArray<DOCollider>& GetColliders () const { return colliders; }
   iMeshFactoryWrapper* GetMeshFactory () const { return factory; }
   virtual const char* GetName () const { return name; }
+  const csString& GetCsName () const { return name; }
   celPcDynamicWorld* GetWorld () const { return world; }
   iImposterFactory* GetImposterFactory () const { return imposterFactory; }
 };
@@ -405,9 +406,11 @@
   virtual void DeleteFactories ();
   virtual size_t GetFactoryCount () const { return factories.GetSize () ; }
   virtual iDynamicFactory* GetFactory (size_t index) const { return 
factories[index]; }
+  virtual iDynamicFactory* FindFactory (const char* name) const;
 
   virtual iDynamicObject* AddObject (const char* factory,
       const csReversibleTransform& trans);
+  virtual iDynamicObject* FindDynamicObject (iCelEntity* entity) const;
   virtual void ForceVisible (iDynamicObject* dynobj);
   virtual void DeleteObject (iDynamicObject* dynobj);
   virtual void DeleteObjects ();

Modified: cel/trunk/plugins/propclass/mesh/meshfact.cpp
===================================================================
--- cel/trunk/plugins/propclass/mesh/meshfact.cpp       2011-09-19 11:37:49 UTC 
(rev 4435)
+++ cel/trunk/plugins/propclass/mesh/meshfact.cpp       2011-09-19 12:57:14 UTC 
(rev 4436)
@@ -1424,7 +1424,6 @@
        : scfImplementationType (this, object_reg)
 {
   pccamera = 0;
-  sel_entity = 0;
   cur_on_top = false;
   mouse_buttons = CEL_MOUSE_BUTTON1;
 
@@ -1713,6 +1712,10 @@
 void celPcMeshSelect::SendMessage (int t, iCelEntity* ent,
        int x, int y, int but)
 {
+  // Prevent this entity from being deleted during message
+  // handling.
+  csRef<iCelEntity> keepme = entity;
+
   iMessageDispatcher* dispatcher = 0;
   const char* msg = "pcmeshsel_invalid";
   switch (t)

Modified: cel/trunk/plugins/propclass/mesh/meshfact.h
===================================================================
--- cel/trunk/plugins/propclass/mesh/meshfact.h 2011-09-19 11:37:49 UTC (rev 
4435)
+++ cel/trunk/plugins/propclass/mesh/meshfact.h 2011-09-19 12:57:14 UTC (rev 
4436)
@@ -323,7 +323,7 @@
   // If the following var is non-0 then we
   // are busy selecting a mesh and are waiting for a mouse up
   // to arrive.
-  iCelEntity* sel_entity;
+  csWeakRef<iCelEntity> sel_entity;
 
   // Set to true if we are currently on top of the selected entity
   // (in do_follow mode).

Modified: cel/trunk/plugins/tools/uitools/inventory/inventory.cpp
===================================================================
--- cel/trunk/plugins/tools/uitools/inventory/inventory.cpp     2011-09-19 
11:37:49 UTC (rev 4435)
+++ cel/trunk/plugins/tools/uitools/inventory/inventory.cpp     2011-09-19 
12:57:14 UTC (rev 4436)
@@ -162,6 +162,8 @@
 bool celUIInventory::OkButton (const CEGUI::EventArgs& e)
 {
   window->hide();
+  if (inventory && listener)
+    inventory->RemoveInventoryListener (listener);
   inventory = 0;
   return true;
 }
@@ -169,6 +171,8 @@
 bool celUIInventory::CancelButton (const CEGUI::EventArgs& e)
 {
   window->hide();
+  if (inventory && listener)
+    inventory->RemoveInventoryListener (listener);
   inventory = 0;
   return true;
 }
@@ -236,8 +240,9 @@
 
   celUIInventory::inventory = inventory;
 
-  csRef<InvListener> listener;
-  listener.AttachNew (new InvListener (this));
+  if (!listener)
+    listener.AttachNew (new InvListener (this));
+  inventory->RemoveInventoryListener (listener);
   inventory->AddInventoryListener (listener);
 
   UpdateLists (inventory);
@@ -248,6 +253,8 @@
 {
   Setup ();
   window->hide();
+  if (inventory && listener)
+    inventory->RemoveInventoryListener (listener);
   inventory = 0;
 }
 

Modified: cel/trunk/plugins/tools/uitools/inventory/inventory.h
===================================================================
--- cel/trunk/plugins/tools/uitools/inventory/inventory.h       2011-09-19 
11:37:49 UTC (rev 4435)
+++ cel/trunk/plugins/tools/uitools/inventory/inventory.h       2011-09-19 
12:57:14 UTC (rev 4436)
@@ -29,6 +29,7 @@
 #include "tools/uitools/inventory.h"
 
 struct iEngine;
+class InvListener;
 
 class celUIInventory : public scfImplementation2<celUIInventory,
   iUIInventory, iComponent>
@@ -41,6 +42,7 @@
   csStringArray listNames;
 
   CEGUI::Window* window;
+  csRef<InvListener> listener;
 
   csRefArray<iUIInventorySelectionCallback> callbacks;
 
@@ -63,6 +65,7 @@
 
   virtual void Open (const char* title, iPcInventory* inventory);
   virtual void Close ();
+  virtual iPcInventory* GetInventory () const { return inventory; }
 
   virtual void AddSelectionListener (iUIInventorySelectionCallback* cb);
   virtual void RemoveSelectionListener (iUIInventorySelectionCallback* cb);

Modified: cel/trunk/plugins/tools/uitools/inventory2/inventory2.cpp
===================================================================
--- cel/trunk/plugins/tools/uitools/inventory2/inventory2.cpp   2011-09-19 
11:37:49 UTC (rev 4435)
+++ cel/trunk/plugins/tools/uitools/inventory2/inventory2.cpp   2011-09-19 
12:57:14 UTC (rev 4436)
@@ -173,6 +173,10 @@
 bool celUIInventory2::OkButton (const CEGUI::EventArgs& e)
 {
   window->hide();
+  if (inventoryLeft && listener)
+    inventoryLeft->RemoveInventoryListener (listener);
+  if (inventoryRight && listener)
+    inventoryRight->RemoveInventoryListener (listener);
   inventoryLeft = 0;
   inventoryRight = 0;
   return true;
@@ -181,6 +185,10 @@
 bool celUIInventory2::CancelButton (const CEGUI::EventArgs& e)
 {
   window->hide();
+  if (inventoryLeft && listener)
+    inventoryLeft->RemoveInventoryListener (listener);
+  if (inventoryRight && listener)
+    inventoryRight->RemoveInventoryListener (listener);
   inventoryLeft = 0;
   inventoryRight = 0;
   return true;
@@ -265,9 +273,11 @@
   celUIInventory2::inventoryLeft = inventoryLeft;
   celUIInventory2::inventoryRight = inventoryRight;
 
-  csRef<InvListener> listener;
-  listener.AttachNew (new InvListener (this));
+  if (!listener)
+    listener.AttachNew (new InvListener (this));
+  inventoryLeft->RemoveInventoryListener (listener);
   inventoryLeft->AddInventoryListener (listener);
+  inventoryRight->RemoveInventoryListener (listener);
   inventoryRight->AddInventoryListener (listener);
 
   UpdateLists ();
@@ -278,6 +288,10 @@
 {
   Setup ();
   window->hide();
+  if (inventoryLeft && listener)
+    inventoryLeft->RemoveInventoryListener (listener);
+  if (inventoryRight && listener)
+    inventoryRight->RemoveInventoryListener (listener);
   inventoryLeft = 0;
   inventoryRight = 0;
 }

Modified: cel/trunk/plugins/tools/uitools/inventory2/inventory2.h
===================================================================
--- cel/trunk/plugins/tools/uitools/inventory2/inventory2.h     2011-09-19 
11:37:49 UTC (rev 4435)
+++ cel/trunk/plugins/tools/uitools/inventory2/inventory2.h     2011-09-19 
12:57:14 UTC (rev 4436)
@@ -28,6 +28,7 @@
 #include "tools/uitools/inventory2.h"
 
 struct iEngine;
+class InvListener;
 
 class celUIInventory2 : public scfImplementation2<celUIInventory2,
   iUIInventory2, iComponent>
@@ -37,6 +38,7 @@
   csRef<iCEGUI> cegui;
   csRef<iPcInventory> inventoryLeft;
   csRef<iPcInventory> inventoryRight;
+  csRef<InvListener> listener;
 
   csStringArray leftListNames;
   csStringArray rightListNames;

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
BlackBerry&reg; DevCon Americas, Oct. 18-20, San Francisco, CA
Learn about the latest advances in developing for the 
BlackBerry&reg; mobile platform with sessions, labs & more.
See new tools and technologies. Register for BlackBerry&reg; DevCon today!
http://p.sf.net/sfu/rim-devcon-copy1 
_______________________________________________
Cel-cvs-update mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/cel-cvs-update

Reply via email to