[Openal-devel] Using C++ in ALUT?
Chris Robinson
chris.kcat at gmail.com
Mon Jun 2 23:09:14 PDT 2008
Oops. Realized I accidently sent this message to Killian directly yesterday by
accident. Since it contains info on how it'd work, I think it's relevant to
resend (sorry Killian)..
On Sunday 01 June 2008 11:23:01 pm you wrote:
> IMO,
> Depends on who "owns" the code .
> But you could wrap it (and don't compile it, but offer it as a header
> (so you don't get overhead)) :
> Ow and we'd need a new standard to allow this (otherwise it will not
> work on all openal implementations) very important !!!
Thanks for the input. Actually, in my mind it would work something like this..
* alut.h:
#ifdef __cplusplus
extern "C" {
#endif
...
typedef struct alutStream alutStream;
ALUT_API alutStream* ALUT_APIENTRY alutCreateStreamFromFile(const char*);
ALUT_API ALboolean ALUT_APIENTRY alutIsStreamPlaying(alutStream*);
ALUT_API void ALUT_APIENTRY alutDestroyStream(alutStream*);
...
#ifdef __cplusplus
}
// Extra C++ stuff
struct alutStream {
virtual ALboolean ALUT_APIENTRY IsPlaying() = 0;
...
virtual ~alutStream(){};
};
#endif
* implementation.cpp (in the lib):
#include "AL/alut.h"
struct StreamImpl : public alutStream {
virtual ALboolean ALUT_APIENTRY IsPlaying()
{
return (this->Pos >= this->EndPos);
}
...
StreamImpl(const char *fname)
{
...create/initialize everything...;
}
virtual ~StreamImpl()
{
if(SourceID)
alSourcei(SourceID, AL_BUFFER, 0);
alDeleteBuffers(BufferCount, Buffers);
}
private:
ALuint BufferCount;
ALuint *Buffers;
...
};
extern "C" {
ALUT_API alutStream* ALUT_APIENTRY alutCreateStreamFromFile(const char *fname)
{
return new StreamImpl(fname);
}
ALUT_API ALboolean ALUT_APIENTRY alutIsStreamPlaying(alutStream *stream)
{
return stream->IsPlaying();
}
ALUT_API void ALUT_APIENTRY alutDestroyStream(alutStream *stream)
{
delete stream;
}
...
}
***
All C users would see is an opaque alutStream pointer, and a C++ user would
see the public interface functions. In both cases, it'll use the fully
implemented StreamImpl struct/class, but they won't see anything that we
don't choose to make public.
Additionally, through the magic of inheritance, it'll allow crafty developers
to override the default implemention, while keeping the API calls exactly the
same. eg:
usercode.cpp:
struct MyStream : public alutStream {
virtual ALboolean ALUT_APIENTRY IsPlaying()
{
return this->WhenISayItsDone;
}
...
};
alutStream *stream1 = new MyStream;
alutStream *stream2 = alutCreateStreamFromFile("somefile.ogg");
Then both:
if(alutIsStreamPlaying(stream1) &&
alutIsStreamPlaying(stream2))
and
if(stream1->IsPlaying() && stream2->IsPlaying())
are perfectly valid, with completely expected and standard C++ behavior. This
could be very useful, for example, if a developer doesn't want to assume the
user's ALUT can support, say, MP3 for licensing reasons, though the developer
has it licensed but doesn't want to sacrifice what else the user's ALUT can
handle (eg. Vorbis, FLAC). They can make their own implementation to deal
with MP3 and use it as needed, while using alutCreateStreamBlah for
everything else.
More information about the Openal-devel
mailing list