| 654 | } |
| 655 | |
| 656 | void asCScriptObject::CallDestructor() |
| 657 | { |
| 658 | // Only allow the destructor to be called once |
| 659 | if( isDestructCalled ) return; |
| 660 | |
| 661 | asIScriptContext *ctx = 0; |
| 662 | bool isNested = false; |
| 663 | bool doAbort = false; |
| 664 | |
| 665 | // Make sure the destructor is called once only, even if the |
| 666 | // reference count is increased and then decreased again |
| 667 | isDestructCalled = true; |
| 668 | |
| 669 | // Call the destructor for this class and all the super classes |
| 670 | asCObjectType *ot = objType; |
| 671 | while( ot ) |
| 672 | { |
| 673 | int funcIndex = ot->beh.destruct; |
| 674 | if( funcIndex ) |
| 675 | { |
| 676 | if( ctx == 0 ) |
| 677 | { |
| 678 | // Check for active context first as it is quicker |
| 679 | // to reuse than to set up a new one. |
| 680 | ctx = asGetActiveContext(); |
| 681 | if( ctx ) |
| 682 | { |
| 683 | if( ctx->GetEngine() == objType->GetEngine() && ctx->PushState() == asSUCCESS ) |
| 684 | isNested = true; |
| 685 | else |
| 686 | ctx = 0; |
| 687 | } |
| 688 | |
| 689 | if( ctx == 0 ) |
| 690 | { |
| 691 | // Request a context from the engine |
| 692 | ctx = objType->engine->RequestContext(); |
| 693 | if( ctx == 0 ) |
| 694 | { |
| 695 | // TODO: How to best report this failure? |
| 696 | return; |
| 697 | } |
| 698 | } |
| 699 | } |
| 700 | |
| 701 | int r = ctx->Prepare(objType->engine->scriptFunctions[funcIndex]); |
| 702 | if( r >= 0 ) |
| 703 | { |
| 704 | ctx->SetObject(this); |
| 705 | |
| 706 | for(;;) |
| 707 | { |
| 708 | r = ctx->Execute(); |
| 709 | |
| 710 | // If the script tries to suspend itself just restart it |
| 711 | if( r != asEXECUTION_SUSPENDED ) |
| 712 | break; |
| 713 | } |
no test coverage detected