[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Future direction of PenguinPlay
I agree that we should use existing libraries whenever this is practical,
adding our own code when nessecary.
However, I also think we should do something else aswell: Create a
standardised interface.
What I mean by this is that A) all projects in PPlay should follow the same
paradigm of interface design B) if something is done in one way in one
place, then it should be done in the same way everywhere else C) programmers
using PPlay should never have to know what library is used to implement the
PPlay interface they are using.
This has a couple of consequences:
* Porting
If we don't provide a interface and hide the implementation (which library
is used), porting to any platform is impossible if ALL the libraries we use
are not also ported. To expect them to be that sounds a bit utopian to me.
If the specific library used is hidden, this allows people to switch the
library used behind the scenes without changing a line of their own code.
The impact on porting this would have should be obvious. Also, if library
developers begin creating PPlay interfaces to their libraries, clients of
PPlay will be able to choose the library whose performance specs best suit
their specific program, and even check each possible candidate out without
almost no effort. Getting library designers to offer PPlay interfaces,
though, might prove to be a bit tricky, and that really would be *our*
job...
* Effeciency
Some might be bothered by the prospect of creating a level of indirection
between the utilised libraries and the interface exposed to the PPlay
client. However, I don't think there will be any noticeable, if any at all,
performance loss by doing this.
If the design paradigm used is sound and optimised for ease-of-use and
effeciency, ie we do everything the best possible way, then this way of
doing things might actually in some areas make things faster.
* Impact of rate of development of client programs
Programmer time is, in most cases, worth much more than computer time. If
people only have to learn one way of doing things and one interface to use
PPlay, then development with PPlay will be much more rapid. Win32 users
expect this kind of thing (not all people at Microsoft is complete morons).
--
Also, we should define the interface strictly enough for it to be possible
for people to create a library whose native interface *is* the PPlay
interface.
Let me take an example on what I mean by "if something is done in one way in
one place, then it should be done in the same way everywhere else": Streams.
Streams covers a pretty basic need most everybody has at some time or
another: getting data from one place, to another. The cool thing about them
it that you push or offer data to a stream in one end, and it comes out the
other. This is cool because the reciecing end doesn't have to care where the
data came from, and the providing end doens't have to care where it goes.
Ideally, getting data from a file, memory, database or other location should
all be done in the exact same way (except for setting it up initially, of
course).
Data might also get altered while being transfered from one location to
another. We might call suchs a thing a filter.
Imagine a 2D program (like Penguin2D) wanting to load a file with graphics.
It might then request this file from PenguinFile, specifying only the
filename (not the extension) and what kind of data it wants (graphics), and
in what format it wants it.
PenguinFile would then solve this request by looking up the file, and
assuming that the file existed, it would then check that the file actually
did contain the type of data requested (atleast in debug builds). If the
format requested matched the format of the file, then all PFile would need
to do was to plug-in the file to a stream and pass this stream back to the
2D program (or perhaps plug-in the providing end of a passed-in stream).
However, if the 2D program had requested the file in a format different from
the format of the file, then PenguinFile would do things a little
differently. It would first create a stream with the file as the source
(providing end). Then it would request a converter filter that would convert
the data in the file to the appropiate format and, assuming this request
could be fulfilled, it would take the output of the file stream and pipe it
in to the filter, it would then pass the filter stream to the 2D program.
Another case could be if the file was found to reside somewhere else than
the local maschine. All PFile would have to do in suchs a case would be to
request a stream providing the data in the file from PenguinNet and pass
this stream to the 2D program, possibly passing it through a filter to get
the format right.
The same thing could be done for, say, a database if we choose to implement
that.
The point is that the 2D program shouldn't know nor care where its data is
coming from, it just needs to trust that if an error doesn't occur, that the
data its getting is the data it wants.
Theoreticly, the data could be coming from the keyboard, or even a mouse or
any number of other places like a microphone, a real phone or a real music
keyboard (those that looks like shrunken pianoes). the point is that the
same kind of streams should be used all over, and all data transfer should
be done using suchs streams (ok, copying one array to another might not
require a stream, but you get the general idea).
The format-converting could be set-up when PenguinPlay is initialised (or,
really, at any other time). All that's needed would be to tell PenguinPlay:
this filter will convert x to y.
The point is that everybody gets the needed data in exactly the format
needed. I'm not suggesting that every transfer from one place to another
should require a translation filter, btw (especially not in-memory
transfers).
For time-critical transfers, most of the dynamic binding of the streams
could be illiminated by templates. Implementing caching like filters
(except, of course, that caching doesn't change the data, of course), and
then using templates to bind them to filters in a non-dynamic way might be a
good idea. Different situations would then could use the same filter (say,
gif-file -> bmp-target and in-memory-gif -> bmp-target), but use different
caching schemes, while avoiding too much dynamic indirection (this would of
course only be a good idea in some cases).
Another thing could be threads: it would be VERY uncool having two different
ways to do threading. All parts of PenguinPlay should use the same threading
scheme, regardless of how its implemented.
Alerting one piece of code what happends in another piece of code is also a
thing that should be uniform all over (ie, events). PenguinEvent.
What do you think of this (providing a uniform interface) ? What do you
think of the streaming/translation scheme I've talked about here?