Hey,
there is no shame in using the 'old' stuff since it is part of our API (and it will stay like that). I just point it out whenever a user is dealing with one of the hollowed out types.
My guess would be that there is a threading issue or threading safety mechanism in the way. I think the memory struct stuff is internally using locks to avoid race conditions/corrupted data. When the renderer backend is doing its threading thing, this could cause issues.
But ramdisk should work because our assets use the concept heavily (most assets are only a 'promise' which will only be truly created once accessed). You would even profit from the ramdisk caching in the temp folder of Cinema 4D.
So, in its simplest form, this should just look like this:
void RenderMyDoc(...)
{
// --- Error Handling and Resource Management ----------------------------------------------------
// Declare heap allocated resources that must be freed once the function exists either normally or
// through an error.
HeapRescource * myResource = nullptr;
BaseBitmap * bmp = nullptr;
// Catch any Maxon API error and turn them into the return type of this function and do optional
// logging. We could also free resources here, but then we would have to do it twice, once for
// normal exit and once for error exit.
iferr_scope_handler
{
// DiagnosticOutput("Error during RenderMyDoc: @", err);
return;
};
// finally is Maxon API syntax to execute code once a scope (not necessarily a function) is left,
// no matter if it is left through normal execution or through an error. This way we can ensure
// that resources are freed.
finally
{
if (myResource)
HeapResource::Free(myResource);
if (bmp)
BaseBitmap::Free(bmp);
};
// Allocate all the resources we need. When we use AutoAlloc<T>, we would not need the finally block
// above, but not all types have an AutoAlloc allocator.
myResource = HeapResource::Alloc();
if (!myResource)
return maxon::OutOfMemoryError(MAXON_SOURCE_LOCATION, "Failed to allocate heap resource.");
bmp = ...
// --- Main Logic --------------------------------------------------------------------------------
// Create our ramdisk mounting point and an URL within it. In practice, we probably would want this
// ramdisk mounting point to be a class member or even a global singleton.
RamDiskRef mountingPoint = RamDiskInterface::Create("net.mycompany.ramdisk.foo"_s) iferr_return;
const Url ramdiskUrl = (mountingPoint.GetRoot() + "my_virtual.psd"_s) iferr_return;
// Call BaseBitmap::Save with the ramdisk URL converted to a Filename.
bmp->Save(cinema::MaxonConvert(ramdiskUrl), ...);
// ...
}
Cheers,
Ferdinand







