-
首页
-
C4D R23.110 C++ SDK
C4DThread
Manual
内容表
关于
C4DThread
is the base class for custom classic threads in
Cinema 4D
. It can be used to perform operations on multiple cores or in the background.
-
警告
-
Threads must not use any OS functions. This is strictly forbidden. The only system calls allowed are memory (de-)allocations.
-
For custom
MAXON API
threads see
线程手册
and
作业手册
.
// This example contains a custom thread and a MessageData plugin.
// The thread renders the given BaseDocument and sends a core message when it has finished.
// This core message is caught by the MessageData plugin that will display the render result
// in the Picture Viewer.
// the render thread
class
RenderThread :
public
C4DThread
{
private
:
BaseDocument
* _doc;
BaseBitmap
* _bitmap;
public
:
RenderThread() { _doc =
nullptr
; }
~RenderThread() { this->DeleteDoc(); }
void
DeleteDoc() {
BaseDocument::Free
(_doc); }
// Sets the document and bitmap.
// The thread takes the ownership of the given BaseDocument.
void
SetData(
BaseDocument
*
const
doc,
BaseBitmap
*
const
bitmap)
{
this->DeleteDoc();
_doc = doc;
_bitmap = bitmap;
}
void
Main
()
{
if
(_doc ==
nullptr
)
return
;
if
(_bitmap)
{
RenderData
*
const
rdata = _doc->
GetActiveRenderData
();
const
BaseContainer
renderSettings = rdata->
GetData
();
const
RENDERFLAGS
flags =
RENDERFLAGS::NODOCUMENTCLONE
;
BaseThread
*
const
thread = this->
Get
();
RenderDocument
(_doc, renderSettings,
nullptr
,
nullptr
, _bitmap, flags, thread);
}
// send core message that the thread finished
SpecialEventAdd
(CUSTOM_ID_RENDER_FINISH);
this->DeleteDoc();
}
const
Char
*
GetThreadName
() {
return
"RenderThread"
; }
};
// the MessageData plugin
class
RenderThreadMessages :
public
MessageData
{
Bool
CoreMessage
(
Int32
id
,
const
BaseContainer
& bc)
{
if
(
id
== CUSTOM_ID_RENDER_FINISH)
{
if
(g_displayBitmap)
{
ShowBitmap
(g_displayBitmap);
}
}
return
true
;
}
};
// This example shows how to create and start a new custom thread instance.
// allocate thread if needed
if
(g_renderThread ==
nullptr
)
{
ifnoerr
(g_renderThread =
NewObj
(RenderThread))
{
if
(g_renderThread ==
nullptr
)
return
false
;
}
}
// check if the thread is running
if
(g_renderThread->IsRunning())
{
// stop the thread
g_renderThread->End(
true
);
}
// thread takes ownership of the document clone but not of the bitmap!
g_renderThread->SetData(documentClone, g_displayBitmap);
const
Bool
started = g_renderThread->Start();
Creation
A custom thread class is created by implementing a class based on
C4DThread
:
// This example shows the most simple C4DThread based custom thread.
class
ExampleThread :
public
C4DThread
{
public
:
ExampleThread() { }
virtual
void
Main
() { }
virtual
const
Char
*
GetThreadName
()
{
return
"ExampleThread"
;
}
};
Now an instance of this custom thread class can be created and used:
// thread stored in a global variable
ExampleThread* g_exampleThread =
nullptr
;
static
maxon::Result<void>
CreateExampleThread()
{
iferr_scope
;
// create thread instance on demand
if
(g_exampleThread ==
nullptr
)
{
g_exampleThread =
NewObj
(ExampleThread)
iferr_return
;
}
return
maxon::OK
;
}
// delete thread stored in the global variable
MAXON_INITIALIZATION
(
nullptr
, []()
{
DeleteObj
(g_exampleThread);
});
Custom Threads
A custom thread class has to implement these virtual functions:
// This example just prints some text to the console for 60 seconds.
// (TestDBreak() will stop it earlier)
void
Main()
{
// save start time for TestDBreak()
_startTime =
GeGetTimer
();
// activity loop
for
(
Int32
i = 0; i < 60; ++i)
{
ApplicationOutput
(
"perform background action "
+
String::IntToString
(i));
// check if the thread should be stopped
if
(this->TestBreak())
return
;
GeSleep
(1000);
}
}
// This example just returns the thread name
const
Char
* GetThreadName()
{
return
"ExampleCustomThread"
;
}
// This example checks how long the thread is running.
// If the thread is running for longer than 20 seconds it should stop.
Bool
TestDBreak()
{
if
(_startTime == -1)
return
true
;
const
Int32
time =
GeGetTimer
();
// check if 20000 milliseconds have passed
if
((time - _startTime) > 20000)
return
true
;
return
false
;
}
-
注意
-
To send a message from a thread to the main thread use
SpecialEventAdd()
。见
Core Messages Manual
.
使用
The custom thread can be started and stopped with these functions:
// This example starts the given thread object.
const
Bool
started = g_exampleThread->Start();
if
(started ==
false
)
return
maxon::UnexpectedError(
MAXON_SOURCE_LOCATION
);
-
注意
-
The THREADPRIORITY should typically not be changed.
读取
Further thread properties are accessed with:
// check if the thread is running
if
(g_exampleThread->IsRunning())
{
// stop the thread
g_exampleThread->End(
true
);
}
延伸阅读
BaseContainer GetData()
定义:
c4d_baselist.h:2266
#define DeleteObj(obj)
定义:
newobj.h:159
virtual Bool CoreMessage(Int32 id, const BaseContainer &bc)=0
Int32 GeGetTimer(void)
定义:
c4d_general.h:449
#define ifnoerr(...)
The opposite of iferr.
定义:
errorbase.h:385
RENDERRESULT RenderDocument(BaseDocument *doc, const BaseContainer &rdata, ProgressHook *prog, void *private_data, BaseBitmap *bmp, RENDERFLAGS renderflags, BaseThread *th, WriteProgressHook *wprog=nullptr, void *data=nullptr)
RENDERFLAGS
定义:
ge_prepass.h:4423
return OK
定义:
apibase.h:2532
void SpecialEventAdd(Int32 messageid, UInt p1=0, UInt p2=0)
#define iferr_return
定义:
resultbase.h:1434
#define MAXON_SOURCE_LOCATION
定义:
memoryallocationbase.h:66
#define MAXON_INITIALIZATION(...)
定义:
module.h:735
BaseThread * Get(void) const
定义:
c4d_thread.h:88
static String IntToString(Int32 v)
定义:
c4d_string.h:495
#define iferr_scope
定义:
resultbase.h:1343
maxon::Int32 Int32
定义:
ge_sys_math.h:58
#define ApplicationOutput(formatString,...)
定义:
debugdiagnostics.h:207
void GeSleep(Int32 milliseconds)
Bool ShowBitmap(const Filename &fn)
static void Free(BaseDocument *&bl)
virtual const Char * GetThreadName(void)=0
RenderData * GetActiveRenderData(void)
#define NewObj(T,...)
定义:
newobj.h:108
定义:
c4d_basedocument.h:136
maxon::Bool Bool
定义:
ge_sys_math.h:53
maxon::Char Char
定义:
ge_sys_math.h:54
定义:
c4d_basedocument.h:490
virtual void Main(void)=0
定义:
c4d_basecontainer.h:46
@ NODOCUMENTCLONE
Set to avoid an automatic clone of the scene sent to RenderDocument().