/////////////////////////////////// // Process parameters via callback void AssDialogueBlockOverride::ProcessParameters(void (*callback)(wxString,int,AssOverrideParameter *,void *),void *userData) { AssOverrideTag *curTag; AssOverrideParameter *curPar; // Find tags for (std::vector<AssOverrideTag*>::iterator cur=Tags.begin();cur!=Tags.end();cur++) { int n = 0; curTag = *cur; // Find parameters for (std::vector<AssOverrideParameter*>::iterator curParam=curTag->Params.begin();curParam!=curTag->Params.end();curParam++) { curPar = *curParam; if (curPar->GetType() != VARDATA_NONE && curPar->ommited == false) { // Do callback (*callback)(curTag->Name,n,curPar,userData); // Go recursive if it's a block parameter //if (curPar->classification == VARDATA_BLOCK) { if (curPar->GetType() == VARDATA_BLOCK) { curPar->AsBlock()->ProcessParameters(callback,userData); } } n++; } } }
void AssDialogueBlockOverride::ProcessParameters(AssDialogueBlockOverride::ProcessParametersCallback callback,void *userData) { for (std::vector<AssOverrideTag*>::iterator cur=Tags.begin();cur!=Tags.end();cur++) { AssOverrideTag *curTag = *cur; // Find parameters for (unsigned n = 0; n < curTag->Params.size(); n++) { AssOverrideParameter *curPar = curTag->Params[n]; if (curPar->GetType() != VARDATA_NONE && !curPar->omitted) { (*callback)(curTag->Name,n,curPar,userData); // Go recursive if it's a block parameter if (curPar->GetType() == VARDATA_BLOCK) { curPar->Get<AssDialogueBlockOverride*>()->ProcessParameters(callback,userData); } } } } }
//////// // Copy void AssOverrideParameter::CopyFrom (const AssOverrideParameter ¶m) { switch(param.GetType()) { case VARDATA_INT: SetInt(param.AsInt()); break; case VARDATA_FLOAT: SetFloat(param.AsFloat()); break; case VARDATA_TEXT: SetText(param.AsText()); break; case VARDATA_BOOL: SetBool(param.AsBool()); break; case VARDATA_COLOUR: SetColour(param.AsColour()); break; case VARDATA_BLOCK: SetBlock(param.AsBlock()); break; default: DeleteValue(); } classification = param.classification; ommited = param.ommited; }
///////////////////// // Parses parameters void AssOverrideTag::ParseParameters(wxString text) { // text is all text following the name until the next \ or the end of the override block // Tokenize text, attempting to find all parameters wxArrayString paramList; wxString work; { if (text.IsEmpty() || text[0] != _T('(')) { // There's just one (or none at all) parameter (because there's no parantheses) // This means text is all our parameters paramList.Add(text.Trim(true).Trim(false)); // Only using goto here to avoid yet another nested block (keeps the code cleaner!) goto end_tokenizing; } // Ok, so there are parantheses used here, so there may be more than one parameter // Enter fullscale parsing! size_t i = 0, textlen = text.Length(); size_t start = 0; int parDepth = 1; while (i < textlen && parDepth > 0) { // Just skip until next ',' or ')', whichever comes first // (Next ')' is achieved when parDepth == 0) start = ++i; while (i < textlen && parDepth > 0) { if (text[i] == _T('(')) parDepth++; if (text[i] == _T(')')) parDepth--; // parDepth 1 is where we start, and the tag-level we're interested in parsing on if (text[i] == _T(',') && parDepth == 1) break; if (parDepth < 0) { wxLogWarning(_T("Unmatched parenthesis near '%s'!\nTag-parsing incomplete."), text.SubString(i, 10).c_str()); goto end_tokenizing; } if (parDepth == 0) { // We just ate the paranthesis ending this parameter block // Make sure it doesn't get included in the parameter text break; } i++; } // i now points to the first character not member of this parameter work = text.SubString(start, i-1); work.Trim(true).Trim(false); paramList.Add(work); wxLogDebug(_T("Got parameter: %s"), work.c_str()); } if (i+1 < textlen) { // There's some additional garbage after the parantheses // Just add it in for completeness paramList.Add(text.Mid(i+1)); } } // This label is only gone to from inside the previous block, if the tokenizing needs to end early end_tokenizing: int curPar = 0; size_t totalPars = paramList.GetCount(); // Get optional parameters flag ASS_ParameterOptional parsFlag = OPTIONAL_0; switch (totalPars) { case 1: parsFlag = OPTIONAL_1; break; case 2: parsFlag = OPTIONAL_2; break; case 3: parsFlag = OPTIONAL_3; break; case 4: parsFlag = OPTIONAL_4; break; case 5: parsFlag = OPTIONAL_5; break; case 6: parsFlag = OPTIONAL_6; break; case 7: parsFlag = OPTIONAL_7; break; } // Find prototype bool clipOnce = true; AssOverrideTagProto *proto = NULL; for (std::list<AssOverrideTagProto>::iterator cur=AssOverrideTagProto::proto.begin();cur!=AssOverrideTagProto::proto.end();cur++) { if (Name == (*cur).name) { if (Name == _T("\\clip") && totalPars != 4 && clipOnce) { clipOnce = false; continue; } proto = &(*cur); break; } } if (proto == NULL) { throw _T("Couldn't find tag prototype while parsing."); } // Get parameters size_t n=0; wxString curtok = _T(""); if (curPar < (signed)totalPars) { curtok = paramList[curPar]; curPar++; } // For each parameter while (n < proto->params.size()) { AssOverrideParamProto *curproto = &proto->params[n]; bool isDefault = false; n++; // Create parameter AssOverrideParameter *newparam = new AssOverrideParameter; // Check if it's optional and not set (set to default) if (!(curproto->optional & parsFlag)) { if (curproto->defaultValue.GetType() != VARDATA_NONE) { isDefault = true; newparam->CopyFrom(curproto->defaultValue); } newparam->ommited = true; // This parameter doesn't really count against the number of parsed parameters, // since it's left out. Don't count it. curPar--; } if (isDefault == false) { // Determine parameter type and set value switch (curproto->type) { case VARDATA_INT: { long temp = 0; curtok.ToLong(&temp); newparam->SetInt(temp); break; } case VARDATA_FLOAT: { double temp = 0.0; curtok.ToDouble(&temp); newparam->SetFloat(temp); break; } case VARDATA_TEXT: { newparam->SetText(curtok); break; } case VARDATA_BOOL: { long temp = false; curtok.ToLong(&temp); newparam->SetBool(temp != 0); break; } case VARDATA_BLOCK: { AssDialogueBlockOverride *temp = new AssDialogueBlockOverride; temp->text = curtok; temp->ParseTags(); newparam->SetBlock(temp); break; } } // Get next actual parameter if (curPar < (signed)totalPars) { // Unless this parameter was omitted (in which case the token shouldn't be eaten) if (!newparam->ommited) { curtok = paramList[curPar]; } curPar++; } else curtok = _T(""); } // Add to list newparam->classification = curproto->classification; Params.push_back(newparam); } }
void AssOverrideTag::ParseParameters(const wxString &text, AssOverrideTagProto::iterator proto_it) { Clear(); // Tokenize text, attempting to find all parameters std::vector<wxString> paramList = tokenize(text); size_t totalPars = paramList.size(); int parsFlag = 1 << (totalPars - 1); // Get optional parameters flag // vector (i)clip is the second clip proto_ittype in the list if ((Name == "\\clip" || Name == "\\iclip") && totalPars != 4) { ++proto_it; } unsigned curPar = 0; for (size_t n = 0; n < proto_it->params.size(); n++) { AssOverrideParamProto *curproto = &proto_it->params[n]; // Create parameter AssOverrideParameter *newparam = new AssOverrideParameter; newparam->classification = curproto->classification; Params.push_back(newparam); // Check if it's optional and not present if (!(curproto->optional & parsFlag) || curPar >= totalPars) { newparam->omitted = true; continue; } wxString curtok = paramList[curPar++]; if (curtok.empty()) { curPar++; continue; } wxChar firstChar = curtok[0]; bool auto4 = (firstChar == '!' || firstChar == '$' || firstChar == '%') && curproto->type != VARDATA_BLOCK; if (auto4) { newparam->Set(curtok); } else { switch (curproto->type) { case VARDATA_INT: { long temp; curtok.ToLong(&temp); newparam->Set<int>(temp); break; } case VARDATA_FLOAT: { double temp; curtok.ToDouble(&temp); newparam->Set(temp); break; } case VARDATA_TEXT: newparam->Set(curtok); break; case VARDATA_BOOL: { long temp; curtok.ToLong(&temp); newparam->Set<bool>(temp != 0); break; } case VARDATA_BLOCK: { AssDialogueBlockOverride *temp = new AssDialogueBlockOverride(curtok); temp->ParseTags(); newparam->Set(temp); break; } default: break; } } } }