| 504 | } |
| 505 | |
| 506 | void CScriptArray::SetValue(std::uint32_t index, void* value) |
| 507 | { |
| 508 | // At() will take care of the out-of-bounds checking, though |
| 509 | // if called from the application then nothing will be done |
| 510 | void* ptr = At(index); |
| 511 | if (ptr == nullptr) return; |
| 512 | |
| 513 | if ((subTypeId & ~asTYPEID_MASK_SEQNBR) && !(subTypeId & asTYPEID_OBJHANDLE)) { |
| 514 | asITypeInfo* subType = objType->GetSubType(); |
| 515 | if (subType->GetFlags() & asOBJ_ASHANDLE) { |
| 516 | // For objects that should work as handles we must use the opHndlAssign method |
| 517 | // TODO: Must support alternative syntaxes as well |
| 518 | // TODO: Move the lookup of the opHndlAssign method to Precache() so it is only done once |
| 519 | String decl = StringView(subType->GetName()) + "& opHndlAssign(const "_s + StringView(subType->GetName()) + "&in)"_s; |
| 520 | asIScriptFunction* func = subType->GetMethodByDecl(decl.data()); |
| 521 | if (func != nullptr) { |
| 522 | // TODO: Reuse active context if existing |
| 523 | asIScriptEngine* engine = objType->GetEngine(); |
| 524 | asIScriptContext* ctx = engine->RequestContext(); |
| 525 | ctx->Prepare(func); |
| 526 | ctx->SetObject(ptr); |
| 527 | ctx->SetArgAddress(0, value); |
| 528 | // TODO: Handle errors |
| 529 | ctx->Execute(); |
| 530 | engine->ReturnContext(ctx); |
| 531 | } else { |
| 532 | // opHndlAssign doesn't exist, so try ordinary value assign instead |
| 533 | objType->GetEngine()->AssignScriptObject(ptr, value, subType); |
| 534 | } |
| 535 | } else { |
| 536 | objType->GetEngine()->AssignScriptObject(ptr, value, subType); |
| 537 | } |
| 538 | } else if (subTypeId & asTYPEID_OBJHANDLE) { |
| 539 | void* tmp = *(void**)ptr; |
| 540 | *(void**)ptr = *(void**)value; |
| 541 | objType->GetEngine()->AddRefScriptObject(*(void**)value, objType->GetSubType()); |
| 542 | if (tmp != nullptr) |
| 543 | objType->GetEngine()->ReleaseScriptObject(tmp, objType->GetSubType()); |
| 544 | } else if (subTypeId == asTYPEID_BOOL || |
| 545 | subTypeId == asTYPEID_INT8 || |
| 546 | subTypeId == asTYPEID_UINT8) { |
| 547 | *(char*)ptr = *(char*)value; |
| 548 | } else if (subTypeId == asTYPEID_INT16 || |
| 549 | subTypeId == asTYPEID_UINT16) { |
| 550 | *(short*)ptr = *(short*)value; |
| 551 | } else if (subTypeId == asTYPEID_INT32 || |
| 552 | subTypeId == asTYPEID_UINT32 || |
| 553 | subTypeId == asTYPEID_FLOAT || |
| 554 | subTypeId > asTYPEID_DOUBLE) { // enums have a type id larger than doubles |
| 555 | *(int*)ptr = *(int*)value; |
| 556 | } else if (subTypeId == asTYPEID_INT64 || |
| 557 | subTypeId == asTYPEID_UINT64 || |
| 558 | subTypeId == asTYPEID_DOUBLE) { |
| 559 | *(double*)ptr = *(double*)value; |
| 560 | } |
| 561 | } |
| 562 | |
| 563 | CScriptArray::~CScriptArray() |