[Openal-devel] FreeALUT stream proof-of-concept

Sherief N. Farouk sherief at mganin.com
Sun Jun 8 18:11:02 PDT 2008


> Because the implementation may change, and if the implementation is
> exposed to
> the user app it'll break ABI if it ever changes. The object should be
> passible between C and C++ (use the C++ interface in C++ code, even if
> the
> object is created in C code, and vice versa).

[Sherief N. Farouk] 
A part has to be exposed to the user. Exposing stream::stream() is no
different than exposing CreateStreamFromFile for this case.

> Unless you're talking about something like this:
> 
> struct ALUTstream {
>     virtual ALboolean ALUT_APIENTRY IsPlaying ()
>     { return This->IsPlaying(); }
>     virtual ALboolean ALUT_APIENTRY Poll ()
>     { return This->Poll(); }
>     virtual ALboolean ALUT_APIENTRY PlayOnSource (ALuint sourceID)
>     { return This->PlayOnSource(sourceID); }
>     virtual ALboolean ALUT_APIENTRY Stop ()
>     { return This->Stop(); }
> 
>     ALUTstream(a,b,c) : This(alutCreateStreamFromFile(a,b,c))
>     { }
>     virtual ~ALUTstream()
>     { delete This; };
> 
> private:
>     ALUTstream *This;
> };

[Sherief N. Farouk] 
No. And there's something fundamentally wrong with that sample. If
ALUTstream is the C object, how can a call like This->PlayOnSource(sourceID)
work? There's no "this" parameter in C, so the only case this is
syntactically correct C is when ALUTstream has a member that's a pointer to
function called PlayOnSource. But then that function doesn't have sufficient
information: only parameter is a source ID. You can have the C-function be
merely thunks that call the C++ code in the end. Same pointer can be used
for both objects in this case.


> But that's pretty ugly, with more levels of indirection. Plus, there's
> a
> problem when you do something like this:
> 
> {
>     alut::stream stream(a,b,c);
>     stream.PlayOnSource(sourceID);
>     alcMakeContextCurrent(NULL);
> }
> 
> The stream will attempt to destroy itself when it goes out of scope,
> but
> because there's a NULL context, it can't stop the source, and
> detach/delete
> the (internal) AL buffers. As it is right now, alutDestroyStream will
> return
> AL_FALSE and delete will throw an exception (what exactly it'll throw
> I've
> not determined yet). This lets you check the error and retry destroying
> it.
> 
> However, in the case above, an exception would be thrown but the object
> is
> invariably lost, so the AL buffers are leaked because they couldn't be
> deleted and there's no way to get them.

[Sherief N. Farouk] 
If you have live objects after you call alcMakeContextCurrent(NULL), You're
beyond help anyway, and you totally and absolutely deserve what's coming to
you. This is the C++ equivalent of someone calling AL functions after a
MakeContextCurrent(NULL) call - they had it coming! :)

- Sherief



More information about the Openal-devel mailing list