ICCItem *CMission::FireOnReward (ICCItem *pData) // FireOnReward // // Fire <OnReward> // // Callers are responsible for discarding the result, if not NULL. { SEventHandlerDesc Event; if (FindEventHandler(EVENT_ON_REWARD, &Event)) { CCodeChainCtx Ctx; Ctx.SaveAndDefineSourceVar(this); Ctx.SaveAndDefineDataVar(pData); ICCItem *pResult = Ctx.Run(Event); if (pResult->IsError()) { ReportEventError(EVENT_ON_REWARD, pResult); Ctx.Discard(pResult); return NULL; } return pResult; } return NULL; }
ICCItem *fnVecCreate (CEvalContext *pCtx, ICCItem *pArguments, DWORD dwData) // fnVecCreate // // Creates a new vector of a given size // // (vecVector size) -> vector // // All elements of the vector are initialized to 0 { CCodeChain *pCC = pCtx->pCC; ICCItem *pArgs; ICCItem *pVector; // Evaluate the argument pArgs = pCC->EvaluateArgs(pCtx, pArguments, CONSTLIT("i")); if (pArgs->IsError()) return pArgs; // Create the table pVector = pCC->CreateVector(pArgs->Head(pCC)->GetIntegerValue()); // Done pArgs->Discard(pCC); return pVector; }
ICCItem *fnCat (CEvalContext *pCtx, ICCItem *pArguments, DWORD dwData) // fnCat // // Concatenates the given strings // // (cat string1 string2 ... stringn) { CCodeChain *pCC = pCtx->pCC; ICCItem *pArgs; ICCItem *pResult; CString sResult; int i; // Evaluate the arguments and validate them pArgs = pCC->EvaluateArgs(pCtx, pArguments, CONSTLIT("*")); if (pArgs->IsError()) return pArgs; // Append each of the items for (i = 0; i < pArgs->GetCount(); i++) sResult.Append(pArgs->GetElement(i)->GetStringValue()); pResult = pCC->CreateString(sResult); // Done pArgs->Discard(pCC); return pResult; }
ICCItem *fnLambda (CEvalContext *pCtx, ICCItem *pArguments, DWORD dwData) // fnLambda // // Lambda expression // // (lambda (args...) code) { CCodeChain *pCC = pCtx->pCC; ICCItem *pItem; CCLambda *pLambda; // Create a lambda expression based on this list pItem = pCC->CreateLambda(pArguments, TRUE); if (pItem->IsError()) return pItem; pLambda = dynamic_cast<CCLambda *>(pItem); // Done return pLambda; }
ICCItem *fnStrCapitalize (CEvalContext *pCtx, ICCItem *pArguments, DWORD dwData) // fnStrCapitalize // // Capitalizes the string // // (strCapitalize string) -> string { CCodeChain *pCC = pCtx->pCC; ICCItem *pArgs; // Evaluate the arguments and validate them pArgs = pCC->EvaluateArgs(pCtx, pArguments, CONSTLIT("s")); if (pArgs->IsError()) return pArgs; CString sString = pArgs->GetElement(0)->GetStringValue(); pArgs->Discard(pCC); // Done sString.Capitalize(CString::capFirstLetter); return pCC->CreateString(sString); }
void CCAtomTable::DestroyItem (CCodeChain *pCC) // DestroyItem // // Destroy this item { int i; // Release all the entries for (i = 0; i < m_Table.GetCount(); i++) { int iKey, iValue; ICCItem *pItem; m_Table.GetEntry(i, &iKey, &iValue); pItem = (ICCItem *)iValue; pItem->Discard(pCC); } // Remove all symbols m_Table.RemoveAll(); // Destroy this item pCC->DestroyAtomTable(this); }
ICCItem *CCPrimitive::Execute (CEvalContext *pCtx, ICCItem *pArgs) // Execute // // Executes the function and returns a result { bool bCustomArgEval = ((m_dwFlags & PPFLAG_CUSTOM_ARG_EVAL) ? true : false); // Evaluate args, if necessary ICCItem *pEvalArgs; if (!bCustomArgEval) { pEvalArgs = pCtx->pCC->EvaluateArgs(pCtx, pArgs, m_sArgPattern); if (pEvalArgs->IsError()) return pEvalArgs; } else pEvalArgs = pArgs; // Invoke the function ICCItem *pResult; bool bReportError = false; try { pResult = m_pfFunction(pCtx, pEvalArgs, m_dwData); } catch (...) { bReportError = true; } // Report error if (bReportError) { CString sArgs; try { sArgs = pEvalArgs->Print(pCtx->pCC); } catch (...) { sArgs = CONSTLIT("[invalid arg item]"); } CString sError = strPatternSubst(CONSTLIT("Exception in %s; arg = %s"), m_sName, sArgs); pResult = pCtx->pCC->CreateError(sError, pEvalArgs); kernelDebugLogMessage(sError.GetASCIIZPointer()); } // Done if (!bCustomArgEval) pEvalArgs->Discard(pCtx->pCC); return pResult; }
void CCSymbolTable::DestroyItem (CCodeChain *pCC) // DestroyItem // // Destroy this item { int i; // Release our parent reference if (m_pParent) m_pParent->Discard(pCC); // Release all the entries for (i = 0; i < m_Symbols.GetCount(); i++) { CObject *pValue = m_Symbols.GetValue(i); ICCItem *pItem = (ICCItem *)pValue; pItem->Discard(pCC); } // Remove all symbols m_Symbols.RemoveAll(); // Destroy this item pCC->DestroySymbolTable(this); }
ICCItem *CCodeChain::LookupGlobal (const CString &sGlobal, LPVOID pExternalCtx) // LookupGlobal // // Returns the binding for this item { CEvalContext EvalCtx; ICCItem *pItem; ICCItem *pResult; // Set up the context EvalCtx.pCC = this; EvalCtx.pLexicalSymbols = m_pGlobalSymbols; EvalCtx.pLocalSymbols = NULL; EvalCtx.pExternalCtx = pExternalCtx; // Create a variable pItem = CreateString(sGlobal); if (pItem->IsError()) return pItem; pResult = Lookup(&EvalCtx, pItem); pItem->Discard(this); return pResult; }
ICCItem *CCLambda::Clone (CCodeChain *pCC) // Clone // // Clone this item { ICCItem *pNew; CCLambda *pClone; pNew = pCC->CreateLambda(NULL, FALSE); if (pNew->IsError()) return pNew; pClone = dynamic_cast<CCLambda *>(pNew); pClone->CloneItem(this); if (m_pArgList) pClone->m_pArgList = m_pArgList->Reference(); else pClone->m_pArgList = NULL; if (m_pCode) pClone->m_pCode = m_pCode->Reference(); else pClone->m_pCode = NULL; return pClone; }
ICCItem *CCLambda::StreamItem (CCodeChain *pCC, IWriteStream *pStream) // StreamItem // // Stream the sub-class specific data { ICCItem *pError; // If we don't have both of these, then it is because we're trying // to save an uninitialized lambda structure ASSERT(m_pArgList); ASSERT(m_pCode); // Write out the argument list pError = pCC->StreamItem(m_pArgList, pStream); if (pError->IsError()) return pError; pError->Discard(pCC); // Write out the code return pCC->StreamItem(m_pCode, pStream); }
ICCItem *CreateListFromBinary (CCodeChain &CC, void const *pvSource, int iLengthBytes) // CreateListFromBinary // // Creates a code chain list from a block of memory { ICCItem *pResult = CC.CreateLinkedList(); if (pResult->IsError()) return pResult; CCLinkedList *pList = (CCLinkedList *)pResult; // CItem is two DWORD long DWORD *pSource = (DWORD *)pvSource; int iCount = AlignUp(iLengthBytes, sizeof(DWORD)) / sizeof(DWORD); for (int i = 0; i < iCount; i++) { ICCItem *pInt = CC.CreateInteger(*pSource++); pList->Append(&CC, pInt, NULL); pInt->Discard(&CC); } return pResult; }
bool GetLinkedFireOptions (ICCItem *pArg, DWORD *retdwOptions, CString *retsError) // GetLinkedFireOptions // // Parses a list of linked fire options { int i; DWORD dwOptions = 0; if (pArg && !pArg->IsNil()) { SDesignLoadCtx LoadCtx; DWORD dwOption; for (i = 0; i < pArg->GetCount(); i++) { ICCItem *pOption = pArg->GetElement(i); if (CDeviceClass::ParseLinkedFireOptions(LoadCtx, pOption->GetStringValue(), &dwOption) != NOERROR) { *retsError = LoadCtx.sError; return false; } dwOptions |= dwOption; } } // Done *retdwOptions = dwOptions; return true; }
CString CreateDataFieldFromItemList (const TArray<CItem> &List) // CreateDataFieldFromItemList // // Creates a data field string from a list of items { int i; CCodeChain &CC = g_pUniverse->GetCC(); CMemoryWriteStream Output(10000); if (Output.Create() != NOERROR) return NULL_STR; Output.Write("='(", 3); for (i = 0; i < List.GetCount(); i++) { ICCItem *pItem = List[i].WriteToCCItem(CC); if (pItem->IsError()) { pItem->Discard(&CC); return NULL_STR; } CString sItem = pItem->Print(&CC); Output.Write(sItem.GetASCIIZPointer(), sItem.GetLength()); Output.Write(" ", 1); pItem->Discard(&CC); } Output.Write(")", 1); Output.Close(); return CString(Output.GetPointer(), Output.GetLength()); }
ICCItem *CCAtomTable::LookupEx (CCodeChain *pCC, ICCItem *pAtom, BOOL *retbFound) // LookupEx // // Looks up the key and returns the association. If no // Association is found, returns an error { ALERROR error; int iValue; ICCItem *pBinding; error = m_Table.Find(pAtom->GetIntegerValue(), &iValue); if (error) { if (error == ERR_NOTFOUND) { if (retbFound) *retbFound = FALSE; return pCC->CreateErrorCode(CCRESULT_NOTFOUND); } else return pCC->CreateMemoryError(); } pBinding = (ICCItem *)iValue; ASSERT(pBinding); if (retbFound) *retbFound = TRUE; return pBinding->Reference(); }
ICCItem *CCodeChain::StreamItem (ICCItem *pItem, IWriteStream *pStream) // StreamItem // // Save the item to an open stream { ALERROR error; DWORD dwClass; ICCItem *pError; // Save out the object class dwClass = pItem->GetClass()->GetObjID(); if (error = pStream->Write((char *)&dwClass, sizeof(dwClass), NULL)) return CreateSystemError(error); // Let the object save itself pError = pItem->Stream(this, pStream); if (pError->IsError()) return pError; pError->Discard(this); // Done return CreateTrue(); }
ICCItem *CCAtomTable::AddEntry (CCodeChain *pCC, ICCItem *pAtom, ICCItem *pEntry) // AddEntry // // Adds an entry to the symbol table and returns // True for success. { ICCItem *pPrevEntry = NULL; int iOldEntry; BOOL bAdded; if (m_Table.ReplaceEntry(pAtom->GetIntegerValue(), (int)pEntry->Reference(), TRUE, &bAdded, &iOldEntry) != NOERROR) return pCC->CreateMemoryError(); // If we have a previous entry, decrement its refcount since we're // throwing it away pPrevEntry = (ICCItem *)iOldEntry; if (!bAdded && pPrevEntry) pPrevEntry->Discard(pCC); SetModified(); return pCC->CreateTrue(); }
ICCItem *CCodeChain::CreateError (const CString &sError, ICCItem *pData) // CreateError // // Creates an item // // sError: Error messages // pData: Item that caused error. { ICCItem *pError; CString sArg; CString sErrorLine; // Convert the argument to a string if (pData) { sArg = pData->Print(this); sErrorLine = strPatternSubst(LITERAL("%s [%s]"), sError, sArg); } else sErrorLine = sError; // Create the error pError = CreateString(sErrorLine); pError->SetError(); return pError; }
int CArmorClass::FireGetMaxHP (CItemCtx &ItemCtx, int iMaxHP) const // FireGetMaxHP // // Fire GetMaxHP event { SEventHandlerDesc Event; if (FindEventHandlerArmorClass(evtGetMaxHP, &Event)) { // Setup arguments CCodeChainCtx Ctx; Ctx.SaveAndDefineSourceVar(ItemCtx.GetSource()); Ctx.SaveAndDefineItemVar(ItemCtx); Ctx.DefineInteger(CONSTLIT("aMaxHP"), iMaxHP); ICCItem *pResult = Ctx.Run(Event); if (pResult->IsError()) ItemCtx.GetSource()->ReportEventError(GET_MAX_HP_EVENT, pResult); else if (!pResult->IsNil()) iMaxHP = Max(0, pResult->GetIntegerValue()); Ctx.Discard(pResult); } return iMaxHP; }
ICCItem *CCodeChain::CreateVectorOld (int iSize) // CreateVectorOld // // Creates a vector of the given number of elements { CCVectorOld *pVector; ICCItem *pError; pVector = new CCVectorOld(this); if (pVector == NULL) return CreateMemoryError(); pError = pVector->SetSize(this, iSize); if (pError->IsError()) { delete pVector; return pError; } pError->Discard(this); // Done return pVector->Reference(); }
ICCItem *CLWindowManager::CreateLWindow (CLWindowOptions *pOptions, CLSizeOptions *pSize, ICCItem *pController) // CLWindowManager // // Create a new window { CLWindow *pNewWindow; ICCItem *pError; pNewWindow = new CLWindow(this); if (pNewWindow == NULL) return m_pCC->CreateMemoryError(); // Initialize pError = pNewWindow->CreateItem(m_pCC, pOptions, pSize, pController); if (pError->IsError()) return pError; pError->Discard(m_pCC); // Add the window to the window manager's list m_WindowList.AppendObject(pNewWindow, NULL); return pNewWindow->Reference(); }
ALERROR CCodeChain::DefineGlobal (const CString &sVar, ICCItem *pValue) // DefineGlobal // // Defines a global variable programmatically { ALERROR error; // Create a string item ICCItem *pVar = CreateString(sVar); // Add the symbol ICCItem *pError; pError = m_pGlobalSymbols->AddEntry(this, pVar, pValue); pVar->Discard(this); // Check for error if (pError->IsError()) error = ERR_FAIL; else error = NOERROR; pError->Discard(this); return error; }
ICCItem *fnShuffle (CEvalContext *pCtx, ICCItem *pArgs, DWORD dwData) // fnShuffle // // Shuffles a list randomly { int i; CCodeChain *pCC = pCtx->pCC; if (pArgs->GetElement(0)->IsNil()) return pCC->CreateNil(); // Create a destination list ICCItem *pResult = pCC->CreateLinkedList(); if (pResult->IsError()) return pResult; CCLinkedList *pList = (CCLinkedList *)pResult; // Copy the list ICCItem *pSource = pArgs->GetElement(0); for (i = 0; i < pSource->GetCount(); i++) pList->Append(pCC, pSource->GetElement(i), NULL); // Shuffle the new list pList->Shuffle(pCC); // Done return pResult; }
int CShieldClass::FireGetMaxHP (CInstalledDevice *pDevice, CSpaceObject *pSource, int iMaxHP) const // FireGetMaxHP // // Fire GetMaxHP event { SEventHandlerDesc Event; if (FindEventHandlerShieldClass(evtGetMaxHP, &Event)) { ASSERT(pSource); ASSERT(pDevice); CCodeChainCtx Ctx; Ctx.SaveAndDefineSourceVar(pSource); Ctx.SaveAndDefineItemVar(pSource->GetItemForDevice(pDevice)); Ctx.DefineInteger(CONSTLIT("aMaxHP"), iMaxHP); ICCItem *pResult = Ctx.Run(Event); if (pResult->IsError()) pSource->ReportEventError(GET_MAX_HP_EVENT, pResult); else if (!pResult->IsNil()) iMaxHP = Max(0, pResult->GetIntegerValue()); Ctx.Discard(pResult); } return iMaxHP; }
ICCItem *fnSubst (CEvalContext *pCtx, ICCItem *pArguments, DWORD dwData) // fnSubst // // Substitutes string parameters // // (subst string arg1 arg2 ... argn) { CCodeChain *pCC = pCtx->pCC; ICCItem *pArgs; // Evaluate the arguments and validate them pArgs = pCC->EvaluateArgs(pCtx, pArguments, CONSTLIT("s*")); if (pArgs->IsError()) return pArgs; CString sPattern = pArgs->GetElement(0)->GetStringValue(); // Do the substitution char szResult[4096]; char *pPos = sPattern.GetASCIIZPointer(); char *pDest = szResult; char *pEndDest = szResult + sizeof(szResult) - 1; while (*pPos != '\0' && pDest < pEndDest) { if (*pPos == '%') { pPos++; int iArg = strParseInt(pPos, 0, &pPos, NULL); if (iArg > 0) { CString sParam = pArgs->GetElement(iArg)->GetStringValue(); char *pParam = sParam.GetASCIIZPointer(); while (*pParam != '\0' && pDest < pEndDest) *pDest++ = *pParam++; pPos++; } else { if (*pPos == '%') *pDest++ = *pPos++; } } else *pDest++ = *pPos++; } // Done *pDest = '\0'; pArgs->Discard(pCC); return pCC->CreateString(CString(szResult)); }
bool IDockScreenDisplay::EvalBool (const CString &sCode, bool *retbResult, CString *retsError) // EvalBool // // Evaluates the given string { CCodeChainCtx Ctx; Ctx.SetScreen(m_pDockScreen); Ctx.SaveAndDefineSourceVar(m_pLocation); Ctx.SaveAndDefineDataVar(m_pData); char *pPos = sCode.GetPointer(); ICCItem *pExp = Ctx.Link(sCode, 1, NULL); ICCItem *pResult = Ctx.Run(pExp); // LATER:Event Ctx.Discard(pExp); if (pResult->IsError()) { *retsError = pResult->GetStringValue(); Ctx.Discard(pResult); return false; } *retbResult = !pResult->IsNil(); Ctx.Discard(pResult); return true; }
ICCItem *fnAppend (CEvalContext *pCtx, ICCItem *pArgs, DWORD dwData) // fnAppend // // Appends two or more elements together { int i, j; CCodeChain *pCC = pCtx->pCC; // Create a new list to store the result in ICCItem *pResult = pCC->CreateLinkedList(); if (pResult->IsError()) return pResult; CCLinkedList *pList = (CCLinkedList *)pResult; // Loop over all arguments and add to result list for (i = 0; i < pArgs->GetCount(); i++) { ICCItem *pItem = pArgs->GetElement(i); for (j = 0; j < pItem->GetCount(); j++) pList->Append(pCC, pItem->GetElement(j), NULL); } // Done return pResult; }
COverlayType *CDeviceClass::FireGetOverlayType (CItemCtx &ItemCtx) const // FireGetOverlayType // // Fire GetOverlayType event { SEventHandlerDesc Event; if (FindEventHandlerDeviceClass(evtGetOverlayType, &Event)) { // Setup arguments CCodeChainCtx Ctx; Ctx.SaveAndDefineSourceVar(ItemCtx.GetSource()); Ctx.SaveAndDefineItemVar(ItemCtx); ICCItem *pResult = Ctx.Run(Event); DWORD dwUNID = 0; if (pResult->IsError()) ItemCtx.GetSource()->ReportEventError(GET_OVERLAY_TYPE_EVENT, pResult); else if (!pResult->IsNil()) dwUNID = pResult->GetIntegerValue(); Ctx.Discard(pResult); // Done return COverlayType::AsType(g_pUniverse->FindDesignType(dwUNID)); } else return GetOverlayType(); }
ICCItem *fnEval (CEvalContext *pCtx, ICCItem *pArguments, DWORD dwData) // fnEval // // Evaluates an expression // // (eval exp) { CCodeChain *pCC = pCtx->pCC; ICCItem *pArgs; ICCItem *pResult; // Evaluate the arguments and validate them pArgs = pCC->EvaluateArgs(pCtx, pArguments, CONSTLIT("v")); if (pArgs->IsError()) return pArgs; pResult = pCC->Eval(pCtx, pArgs->GetElement(0)); // Done pArgs->Discard(pCC); return pResult; }
ICCItem *CMission::FireOnDeclined (void) // FireOnDeclined // // Fire <OnDeclined>. We return the result of the event, which might contain // instructions for the mission screen. // // Callers are responsible for discarding the result, if not NULL. { SEventHandlerDesc Event; if (FindEventHandler(EVENT_ON_DECLINED, &Event)) { CCodeChainCtx Ctx; Ctx.SaveAndDefineSourceVar(this); ICCItem *pResult = Ctx.Run(Event); if (pResult->IsError()) { ReportEventError(EVENT_ON_DECLINED, pResult); Ctx.Discard(pResult); return NULL; } return pResult; } return NULL; }