Development roadmap

in
Plump release timeline follows the most established pattern in the free software development world: new releases will be available when they are ready. No attempt to provide release dates are made.

Plump is actively mantained. Bugs are fixed as they are discovered. Development is dictated by the needs of users. New feature requests are considered and implemented as required.

If you are a developer using plump, chances are you will want to improve some parts of the code or to add new functionality. You are encouraged to improve plump and then contribute your changes back to the community in the form of a patch. Your patch should be accompanied by a description of the changes and a motivation of the reasons why this patch is useful and what problem it solves.


Milestones (sync'ed with CVS repository every hour)
_________________
The Plump project
~~~~~~~~~~~~~~~~~

MILESTONES
----------


Milestone 0.0.2
~~~~~~~~~~~~~~~
dispose of callbacks in favour of plugin::run() solution


Milestone 0.0.4
~~~~~~~~~~~~~~~
implement parallel plugin activator


Milestone 0.0.6
~~~~~~~~~~~~~~~
add tests, ensure satisfactory code coverage


Milestone 0.0.8
~~~~~~~~~~~~~~~
API freeze


Milestone 0.0.9
~~~~~~~~~~~~~~~
code cleanup
  hunting REVISIT and TODO string in the source code down
  singleton implementation


Milestone 0.1.0
~~~~~~~~~~~~~~~
1.0 release


______________________
Why not use callbacks?
~~~~~~~~~~~~~~~~~~~~~~

...in a nutshell... to remind me why, expand to let other people understand...

users of plugins should not be required to know how to use plugins.
they should just be able to run a plugin.

hence run() method.
TODO list (sync'ed with CVS repository every hour)
_________________
The Plump project
~~~~~~~~~~~~~~~~~

TODO list
---------

* example program / tutorial
   * cowsay-cowthink-cowshout example
     update it to use new non-callback architecture
   * currency converter example
     write it up

* add cowsay tutorial to test suite
   add debugging functionality to the script
   fix problem that causes shell executing script to quit
   fix plugin order - log comparison problem

* documentation
   write documentation that explains the framework's design, overview
   and implementation

* ParallelPluginActivator
   needs implementing

* revisit the section marked REVISIT
   to be done before 0.1.0 release
   :-)

* tests/invalid_handle
   Find a way to obtain an invalid handle to a module (lt_dlhandle
   object) and update the tests (comment out the code already written
   or write new test code) to test correct behaviour.
   
   An idea would be to implement a module that does not expose the
   expected interface (PluginInterface's methods) and check that the
   framework recognized the error and handles it gracefully.

* test library
   TODO: move the setUp and tearDown methods used in tests into a test
   library. These functions are used in different tests
   (e.g. PluginManagerTest) and the code is unchanged... this code
   duplication should be avoided!  Consider putting this methods in a
   common file.

* autoconf'ize header files
   e.g. insert #ifdef HAVE_CONFIG_H and similar ifdef's

* All the error messages should be identified by an int and read from an error messages file.
   gettext will probably take care of that. Should research into it.

* PlumpMemoryException and other exception classes
   constructor should do something meaningful with the string passed in!

* add tests that cause the exceptions to be thrown!


Done TODOs
----------

* add cowsay tutorial to test suite
   write a script that executes the steps described in the tutorial

* plump website
   finish pages and publish website
   * take website out of beta
     move it to root of http://plump.sf.net
   * change documentation and development menu pages
   * add information regarding CVS branches, tag and access

* change the way plugins with custom init data are built
   plugins that require init data should take the form of a void*
   passed in the plugins constructor. Change pluginFactory and
   pluginInstance to support this. The user should only have to supply
   a plugin constructor which takes a void* and not modify
   pluginFactory.

   pluginFactory does not need initPluginInstance method.
   pluginInstance needs a constructor which takes a void*.
   plugins need a extern "C" create function which takes a void*.
   plugins need a constructor which takes a void* and uses that any
   way they want.

   It would be great if pluginInstance could new a copy of the object
   pointed to by the void*, but there is no way to know what object
   void* is pointing to, so we cannot copy it. The plugin writer
   should take care to save a copy of the object in the plugin itself.

* PluginManager:
   Need a method that takes a list of plugin names and a list of
   initialization data and builds the PluginInstance objects (using
   PluginFactory) from the modules having those names.

   Write tests.

* logger
   design, implement and integrate a logging facility
   
   or alternatevily, use log4cpp

* plump namespace
   move all objects within namespace plump

* PluginManager deprecated methods
   get rid of deprecated methods (callback and forEach)

   used only for testing

* insert copyright notice at beginning of every file

* add #include  to every header file (except test and demo files)

* PluginInstance should inherit from PluginInterface
   rather than having a pointer to it. That embodies the concept that
   PluginInstance implents PluginInterface.
  
   Unfortunately, that cannot be accomplished because the
   PluginInterface object is dynamically created from a dynamically
   linked module.

class PluginInterface {
public:
	PluginInterface() = 0;

};

class PluginInstance : public PluginInterface {
 // ...
};

   If I make this change, handling of 0 pointer in
   pluginFactory.cxx:43 won't be required.


* PluginInstance(lt_dlhandle) and PluginInstance(lt_dlhandle, void*) 
   should be unified into a single overloaded constructor

PluginInstance::PluginInstance(lt_dlhandle, void* = 0);

PluginInstance::PluginInstance(lt_dlhandle handle, void* data)
{
  // ...

  if (data)
  {
	create_init_symbol = lt_dlsym( handle, "create_init" );
  }
  else
  {	
	create_symbol = lt_dlsym( handle, "create" );
  }

  // ...

  if (data)
  {
	plugin_instance_ptr = create_init (data);
  }
  else
  {
	plugin_instance_ptr = create();
  }

  // ...

};

* pluginFramework.h:81 should catch a std::bad_alloc exception and throw a PlumpMemoryException

// code snippet

   try
   {
	sm_instance = new PluginFramework();
   }
   catch (const std::bad_alloc& ex)
   {
	throw PlumpMemoryException(
	      "An exception occurred while creating the Plump framework object.\n"
	      "Insufficient memory available"
	      );
   }
   catch (...)
   {
	throw PlumpUnexpectedException();
   }

// end code snippet

* pluginInstance.cxx:36 and pluginInstance:79

   PluginInstance constructor should log the attempted instantiation of
   an invalid module and throw an exception, to be caught by
   PluginFactory, so that the PluginInstance object being constructed
   will be deallocated automatically and its memory freed.
  
  // Build exception string
  std::string error_str;
  lt_dlinfo* module_info = lt_dlgetinfo (handle);
  if (module_info)
  {
	error_str = "Instantiation of an invalid module attempted from file " + module_info->filename + "\n";
  {
  else
  {
	error_str = "Instantiation of an invalid module attempted.\n";
  }

  throw PlumpInvalidModuleException(error_str);


* pluginInstance:44

  This is a critical error. Could be handled by PluginManager or Plump or left to user.

  throw PlumpRuntimeException(
	"Attempted instantiation of a null module handle.\n"
	);

* pluginInstance:107

   we should load the destroy symbol which destroys the
   PluginInterface object contained in the PluginInstance object at
   PluginInstance construction time (in PluginInstance constructor).
   
   Doing that allows us to avoid having to throw an exception in
   PluginInstance destructor (which is always a Bad Thing To Do (TM))
   and definitely makes more sense.
   
   If we can't load the destroy symbol, then we proceed as when we
   can't load the create symbol, i.e. by throwing a
   PlumpInvalidModuleException("Module does not export a destroy
   symbol.\n").


* pluginFramework.h:154

  no need for exception here.
  should probably change debug string to something like:
  "[PluginFramework] No module corresponding to a plugin named " + *it + "was found.\n"


* pluginManager:109

  Logger::getLogger()->error ("[PluginManager] The number of plugin handles and plugin initialization data must be equal.\n" +
                              "[PluginManager] Error: modules = " + modules.size() + "; "init data = " + data.size());

  throw PlumpLogicErrorException(
	"The number of plugin handles and plugin initialization data must be equal.\n"
	);