Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- set_max_file_asset_metadata_cf(Value** arg_list, int count)
- {
- // setMAXFileAssetMetadata <filename> <array of AssetMetadata_StructDef instances>
- check_arg_count_with_keys(setMAXFileAssetMetadata, 2, count);
- TSTR fileName = arg_list[0]->to_filename();
- AssetId assetId;
- if (IAssetManager::GetInstance()->StringToAssetId(fileName, assetId))
- fileName = IAssetManager::GetInstance()->GetAsset(assetId).GetFileName();
- const TCHAR* scene_dir = MAXScript_interface->GetDir(APP_SCENE_DIR);
- TCHAR buf[MAX_PATH] = {0};
- five_typed_value_locals(Name* struct_name, StructDef* sd, Value* assetId, Value* filename, Value* assetType);
- // for each element of <array of AssetMetadata_StructDef instances>, make sure it's an AssetMetadata_StructDef instance
- // collect elements as AssetMetaData instances.
- vl.struct_name = (Name*)Name::intern(ASSETMETADATA_DEFSTRUCT_NAME);
- vl.sd = (StructDef*)globals->get(vl.struct_name)->eval();
- Array* metadata_array = (Array*)arg_list[1];
- type_check(metadata_array, Array, _T("setMAXFileAssetMetadata"));
- MaxSDK::Array<AssetMetaData> new_assetMetaData(metadata_array->size);
- for (int i = 0; i < metadata_array->size; i++)
- {
- Struct* element = (Struct*)metadata_array->data[i];
- if (!is_struct(element))
- throw RuntimeError(MaxSDK::GetResourceStringAsMSTR(IDS_EXPECTED_ASSETMETADATA_DEFSTRUCT), element);
- StructDef *sdef = element->definition;
- if (sdef != vl.sd)
- throw RuntimeError(MaxSDK::GetResourceStringAsMSTR(IDS_EXPECTED_ASSETMETADATA_DEFSTRUCT), element);
- vl.assetId = element->member_data[1];
- vl.filename = element->member_data[2];
- vl.assetType = element->member_data[3];
- bool success = IAssetManager::GetInstance()->StringToAssetId(vl.assetId->to_string(), new_assetMetaData[i].assetId);
- if (!success)
- throw RuntimeError(MaxSDK::GetResourceStringAsMSTR(IDS_CANNOT_CONVERT_ASSETID), vl.assetId);
- TSTR assetFileName = vl.filename->to_filename();
- AssetId assetId;
- if (IAssetManager::GetInstance()->StringToAssetId(assetFileName, assetId))
- assetFileName = IAssetManager::GetInstance()->GetAsset(assetId).GetFileName();
- new_assetMetaData[i].filename = assetFileName;
- new_assetMetaData[i].assetType = vl.assetType->to_string();
- }
- // find the file
- if (MSZipPackage::search_current_package(fileName, buf) ||
- SearchPath(scene_dir, fileName, NULL, MAX_PATH, buf, NULL) ||
- SearchPath(NULL, fileName, NULL, MAX_PATH, buf, NULL))
- {
- // This opens the file as an OLE structured storage file with read/write access
- STGOPTIONS StgOptions = { 0};
- StgOptions.usVersion = 1; /* Win2k+ */
- StgOptions.ulSectorSize = 4096; /* 512 limits us to 2GB */
- DWORD mode = (STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE);
- IStorage* pIStorage = NULL;
- HRESULT hres = StgOpenStorageEx(WStr(buf), mode, STGFMT_DOCFILE, 0, &StgOptions, NULL,
- IID_IStorage, (void **) &pIStorage);
- if (hres != S_OK || pIStorage == NULL)
- return_value(&false_value);
- // define AutoPtr for guaranteed cleanup of pIStorage
- MaxSDK::AutoPtr<IUnknown, IUnknownDestructorPolicy> pIStorageAutoPtr(pIStorage);
- // This opens the Asset Metadata stream with read/write access
- LPSTREAM pIStream;
- hres = pIStorage->OpenStream(L"FileAssetMetaData2", NULL, mode, 0, &pIStream);
- if (hres != S_OK || pIStream == NULL)
- return_value(&false_value); // valid for old files
- // define AutoPtr for guaranteed cleanup of pIStream
- MaxSDK::AutoPtr<IUnknown, IUnknownDestructorPolicy> pIStreamAutoPtr(pIStream);
- // get the length of the stream
- STATSTG statstg;
- pIStream->Stat(&statstg,STATFLAG_NONAME);
- unsigned __int64 nBytes = statstg.cbSize.QuadPart;
- unsigned __int64 nBytesRead = 0;
- // read from the stream while there are bytes left.
- MaxSDK::Array<AssetMetaData> assetMetaDataArray;
- AssetMetaData assetMetaData;
- while (nBytesRead < nBytes)
- {
- // load an asset's metadata
- if (!ReadAssetMetaData(pIStream, assetMetaData, nBytesRead))
- throw RuntimeError(MaxSDK::GetResourceStringAsMSTR(IDS_ERROR_READING_ASSETMETADATA_STREAM));
- // see if user has specified data for this asset id
- for (int i = 0; i < new_assetMetaData.length(); i++)
- {
- if (new_assetMetaData[i].assetId == assetMetaData.assetId)
- {
- // assetType has to match, Case-insensitive compare
- if (_wcsicmp(new_assetMetaData[i].assetType, assetMetaData.assetType) != 0)
- {
- TSTR errorMsg;
- errorMsg.printf(MaxSDK::GetResourceStringAsMSTR(IDS_INCORRECT_ASSETTYPE), vl.assetId->to_string(),
- assetMetaData.assetType.data(), new_assetMetaData[i].assetType.data());
- throw RuntimeError(errorMsg);
- }
- assetMetaData.filename = new_assetMetaData[i].filename;
- break;
- }
- }
- assetMetaDataArray.append(assetMetaData);
- }
- // done reading asset metadata, reset stream and rewrite it.
- LARGE_INTEGER zero = {0, 0};
- pIStream->Seek(zero, STREAM_SEEK_SET, NULL);
- ULARGE_INTEGER uzero = {0, 0};
- pIStream->SetSize(uzero);
- for (int i = 0; i < assetMetaDataArray.length(); i++)
- {
- ULONG nb;
- // store assetId, assetType width in characters, assetType as unicode string - null terminated,
- // filename width in characters, filename as unicode string - null terminated
- AssetMetaData &assetMetaData = assetMetaDataArray[i];
- pIStream->Write(&assetMetaData.assetId,sizeof(assetMetaData.assetId),&nb);
- int len = assetMetaData.assetType.Length();
- pIStream->Write(&len,sizeof(len),&nb);
- if (len != 0)
- pIStream->Write(assetMetaData.assetType.data(),len*sizeof(wchar_t),&nb);
- wchar_t null_char = 0;
- pIStream->Write(&null_char,sizeof(null_char),&nb);
- len = assetMetaData.filename.Length();
- pIStream->Write(&len,sizeof(len),&nb);
- if (len != 0)
- pIStream->Write(assetMetaData.filename.data(),len*sizeof(wchar_t),&nb);
- pIStream->Write(&null_char,sizeof(null_char),&nb);
- }
- }
- else
- throw RuntimeError(MaxSDK::GetResourceStringAsMSTR(IDS_FILE_NOT_FOUND), arg_list[0]);
- return_value(&true_value);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement