THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 19/12/2006 at 10:13, xxxxxxxx wrote:
Cinema 4D Version: 8.204
Platform: Windows ;
Language(s) : C++ ;
We do several actions by threads. I learned, that initiating a gui-operation by a thread is dangerous - that might intercept cinema in the wrong moment and cause a desaster. We go through the whole project by a thread to test our model ( apply testcases on objects, materials, etc. ), that seems to be safe. We do a xml export with an own thread, seems to be safe. I have real big problems now in our import which works with an own thread to modify the model. We have a gui for it, and I buffered operations like write things to a log window by a thread safe fifo queue. But by system is still unstable.
Here what I have: Described in a simplified way, a GeDialog which has a log window, and an import thread running, adding stuff to the model like objects or materials or modifying existing ones. The import thread wants to write informations to the log, and from what I learnd, I implemented a thread safe fifo between the import thread and the log. The GeDialog has a timer, and whenever cinema now thinks it is the right time to do it, it takes a look on the fifo and checks for new log messages in order to display them. That mechanism normally works, for example in that thing which applies testcases to our model. But in case of the import, it has problems. I wrote a test, an import which writes a log entry, gets the active document and creates an object, and that 1000 times in a loop...all fine, works perfect. But I have other imports - of course the real ones to be delivered, not the test one - and they don't work fine. Everythign stops, and most of the times the call stack does not help me, sometimes I see the CDialogCallBack in c4d_gui.cpp.
Any hints what may go wrong? Ah yeah, and of course, to fullfill our delivery dates, the problem has to be solved until friday....besides other problems...nono, I don't panic yet...not yet, maybe tomorrow or so
On 22/12/2006 at 05:05, xxxxxxxx wrote:
*gets the active document and creates an object*
Does this mean your thread adds objects to the document which is displayed in the editor ?
Sorry if i state the obvious, but if so, this is going to cause crashes for sure. Imagine Cinema traversing the object hierarchy to display stuff while your thread modifies some pointer to add an object... no good..
It should be safe however to create a new document that is owned by your thread, add some objects, and when the thread is done, add all the objects to the active document.
The gui stuff with the queue sounds alright. Gui functions are indeed not thread safe.
Important functions are EventAdd and SpecialEventAdd. These are thread safe and allow you to send messages from the thread to Cinemas main event loops which gives them to the various CoreMessage functions.
Your dialog should intercept a custom message send by the thread before it terminates ( or simply use polling in the timer ). Then you can fetch your imported objects and add them to any document.
On 22/12/2006 at 05:24, xxxxxxxx wrote:
Yes, that it does....indeed we already have many imports doing that, worked fine, but we have more complex ones now, here we had problems. And now I understand why the queue stuff made it worse, the timer caused cinema to do something several times per second, and maybe by that it did some additional updates...
What we did was building an own wizard for imports, where after file and module selection we have module dependent setting pages which may depend on the data in the file, and then a processing page, with a log, progress bar, etc.... And to have the GUI always updated and reacting to the user, we did make an own thread for the import process, which does alot of modifications on the project.
Hm damn, seems we have to make a real big change. Ok, I did something now, it runs quiet stable, but still creating all the project data with an own thread. So, ok for the moment, but I don't have an idea yet what to change not to throw everything away we have. Did I overlook something, or do you have an idea how to make what I wrote above?
On 22/12/2006 at 06:29, xxxxxxxx wrote:
Hmm.. as i said if you just load the data and build some "private" objects everything should be fine, because Cinema doesn't touch them unless you put them in the active document. So just don't do that! Keep the objects for youself, and add them to the document when all the work is done.
You could also let the thread only build one object. Then put this object in the document, and restart the thread to process the next object.
On 22/12/2006 at 06:41, xxxxxxxx wrote:
Ok, will try that next year, I don't know if the first approach with a second document will work for us, have to see.
What we do is supporing a Re-Import: We import a big scene, the user may add things by hand, and if we get a new input file, then we just update the model. Every object knows where it was imported from by unique IDs, so updates can be performed with an import. That is an important feature for us, because we don't get everything in an input format, for other things we just get styleguides and have to model them by hand. And during one project we get a dozen and more updates with modified import files from the customers....weird stuff we are doing here That approach together with the solution of a second document would mean to change nearly everything I guess.
Well, I'll think about it next year, so happy xmas to you forum and a good new year!
On 22/12/2006 at 08:59, xxxxxxxx wrote:
Happy xmas to all.
Don't misunderstand me. What i'm saying is simply that any modification to the active document should be synchronized with the main thread. Hence, you actually have to do it in the main thread at places where you can be sure that cinema doesn't access the data. For exmaple, another possibility would be to use a message plugin:
MyObjectData *p = LengthyImportOperationThatReturnsObject()
PutObjectInThreadSafeFIFO( p )
GeSpecialEvent( IMPORT_UPDATE )
void MyMessagePlugin::CoreMessage( id )
MyObjectData *p = GetObjectFromThreadSafeFIFO( p )
UpdateDocument( p, GetActiveDocument() )
Maybe that would work better for you. Good luck.