private UserFunction GetUserFunction(string userFuncIdentifier, ParseNode declaredWith) { if (userFuncs.ContainsKey(userFuncIdentifier)) { return(userFuncs[userFuncIdentifier]); } if (declaredWith != null) { var userFuncObject = new UserFunction(userFuncIdentifier, declaredWith); userFuncs.Add(userFuncIdentifier, userFuncObject); newUserFuncs.Add(userFuncObject); return(userFuncObject); } return(null); // shouldn't happen - must call with declaredWith = something. }
private UserFunction GetUserFunction(string userFuncIdentifier, ParseNode declaredWith) { if (userFuncs.ContainsKey(userFuncIdentifier)) { return userFuncs[userFuncIdentifier]; } if (declaredWith != null) { var userFuncObject = new UserFunction(userFuncIdentifier, declaredWith); userFuncs.Add(userFuncIdentifier, userFuncObject); newUserFuncs.Add(userFuncObject); return userFuncObject; } return null; // shouldn't happen - must call with declaredWith = something. }
/// <summary> /// Returns true if the given user function is one of the ones that was just /// declared during the current compile and not one that was leftover from /// a previous compile. /// <br/> /// Returns false if either the function exists and is old, or the function /// doesn't even exist in the collection at all. /// </summary> /// <param name="func"></param> /// <returns></returns> public bool IsNew(UserFunction func) { // Possible opportuinity for an optimization refactor here: // ------------------------------------------- // newUserFuncs is purely a flat sequential list with // no sort order or hash mapping. Therefore seeing if a // function is new or not requires a sequential walk of all // the functions built during the current compile. // If people start writing library scripts containing upwards // of 20 or more functions in one file, that could become // inefficient. It may be possible to refactor newUserFuncs // into some sort of hashmap or at least sorted list. That way // Contains() would be a faster search. return(newUserFuncs.Contains(func)); }
/// <summary> /// Returns true if the given user function is one of the ones that was just /// declared during the current compile and not one that was leftover from /// a previous compile. /// <br/> /// Returns false if either the function exists and is old, or the function /// doesn't even exist in the collection at all. /// </summary> /// <param name="func"></param> /// <returns></returns> public bool IsNew(UserFunction func) { // Possible opportuinity for an optimization refactor here: // ------------------------------------------- // newUserFuncs is purely a flat sequential list with // no sort order or hash mapping. Therefore seeing if a // function is new or not requires a sequential walk of all // the functions built during the current compile. // If people start writing library scripts containing upwards // of 20 or more functions in one file, that could become // inefficient. It may be possible to refactor newUserFuncs // into some sort of hashmap or at least sorted list. That way // Contains() would be a faster search. return newUserFuncs.Contains(func); }
/// <summary> /// Build the system trigger to go with a user function (lock) /// such as LOCK STEERING or LOCK THROTTLE /// </summary> /// <param name="func">Represents the lock object, which might not be fully populated yet.</param> private void BuildSystemTrigger(UserFunction func) { string triggerIdentifier = "lock-" + func.ScopelessIdentifier; Trigger triggerObject = context.Triggers.GetTrigger(triggerIdentifier); if (triggerObject.IsInitialized()) return; short rememberLastLine = lastLine; lastLine = -1; // special flag telling the error handler that these opcodes came from the system itself, when reporting the error List<Opcode> rememberCurrentCodeSection = currentCodeSection; currentCodeSection = triggerObject.Code; AddOpcode(new OpcodePush("$" + func.ScopelessIdentifier)); AddOpcode(new OpcodePush(new KOSArgMarkerType())); // need these for all locks now. AddOpcode(new OpcodeCall(func.ScopelessPointerIdentifier)); AddOpcode(new OpcodeStoreGlobal()); AddOpcode(new OpcodeEOF()); lastLine = rememberLastLine; currentCodeSection = rememberCurrentCodeSection; }
private void UnlockIdentifier(UserFunction lockObject) { if (lockObject.IsSystemLock()) { // disable this FlyByWire parameter AddOpcode(new OpcodePush(new KOSArgMarkerType())); AddOpcode(new OpcodePush(lockObject.ScopelessIdentifier)); AddOpcode(new OpcodePush(false)); AddOpcode(new OpcodeCall("toggleflybywire()")); // add a pop to clear out the dummy return value from toggleflybywire() AddOpcode(new OpcodePop()); // remove update trigger string triggerIdentifier = "lock-" + lockObject.ScopelessIdentifier; if (context.Triggers.Contains(triggerIdentifier)) { Trigger triggerObject = context.Triggers.GetTrigger(triggerIdentifier); AddOpcode(new OpcodePushRelocateLater(null), triggerObject.GetFunctionLabel()); AddOpcode(new OpcodeRemoveTrigger()); } } // unlock variable // Really, we should unlock a variable by unsetting it's pointer var so it's an error to use it: AddOpcode(new OpcodePush(lockObject.ScopelessPointerIdentifier)); AddOpcode(new OpcodePushRelocateLater(null), lockObject.DefaultLabel); if (allowLazyGlobal) AddOpcode(new OpcodeStore()); else AddOpcode(new OpcodeStoreExist()); }