private static bool CheckForMissingTunnelReferences(IElement asIElement) { bool errorFound = false; foreach (CustomVariable variable in asIElement.CustomVariables) { if (!string.IsNullOrEmpty(variable.SourceObject)) { NamedObjectSave nos = asIElement.GetNamedObjectRecursively(variable.SourceObject); if (nos == null) { errorFound = true; MessageBox.Show("The variable " + variable.Name + " references " + variable.SourceObject + " but " + "this object doesn't exist."); } else { List <string> availableMembers = ExposedVariableManager.GetExposableMembersFor(nos).Select(item => item.Member).ToList(); if (!availableMembers.Contains(variable.SourceObjectProperty)) { errorFound = true; MessageBox.Show("The variable " + variable.Name + " references the property " + variable.SourceObjectProperty + "in " + asIElement.ToString() + " which does not exist."); } } } } return(errorFound); }
public void Test() { string memberType = ExposedVariableManager.GetMemberTypeForEntity("Current" + mEntitySave.StateCategoryList[0].Name + "State", mEntitySave); if (memberType != mEntitySave.StateCategoryList[0].Name) { throw new Exception("ExposedVariableManager.GetMemberTypeForEntity didn't return the proper type"); } // The base should be able to expose Visible because it's IVisible List <string> variables = variables = ExposedVariableManager.GetExposableMembersFor(mEntitySave, false).Select(item => item.Member).ToList(); if (!variables.Contains("Visible")) { throw new Exception("The base Entity that is IVisible does not have the Visible property as an exposable variable and it should"); } // The derived should be able to expose Visible because its base is IVislble variables = ExposedVariableManager.GetExposableMembersFor(mDerivedEntitySave, false).Select(item => item.Member).ToList(); if (!variables.Contains("Visible")) { throw new Exception("Derived Entities are not showing Visible as an exposable variable when the base implements IVislble"); } }
public void TestExposingStates() { List <string> variables = ExposedVariableManager.GetExposableMembersFor(mEntitySave, false).Select(m => m.Member).ToList(); if (!variables.Contains("CurrentState")) { throw new Exception("ExposedVariableManager is not properly returning the CurrentState as an exposable variable"); } if (!variables.Contains("CurrentStateCategoryState")) { throw new Exception("ExposedVariableManager is not properly returning categorized states as exposable variables"); } // Let's remove uncategorized state to make sure the categorized state is still recognized: StateSave stateSave = mEntitySave.States[0]; mEntitySave.States.RemoveAt(0); variables = ExposedVariableManager.GetExposableMembersFor(mEntitySave, false).Select(m => m.Member).ToList(); if (!variables.Contains("CurrentStateCategoryState")) { throw new Exception("ExposedVariableManager is not properly returning categorized states when there are no uncategorized states."); } // Add it back in case it's needed for other tests. mEntitySave.States.Add(stateSave); variables = ExposedVariableManager.GetExposableMembersFor(mEntityWithCategorizedThatShareVariables, false).Select(m => m.Member).ToList(); if (!variables.Contains("CurrentState")) { throw new Exception("Entities that only have states in categories, but those categories share variables with other categories, are not exposing CurrentState and they should!"); } List <string> listOfStates = new List <string>(); AvailableStates availableStates = new AvailableStates(null, mContainerDerivedEntity, mContainerDerivedEntity.CustomVariables[0], null); availableStates.GetListOfStates(listOfStates, "TunneledStateVariable"); if (listOfStates.Count == 0 || !listOfStates.Contains("StateInCategory1")) { throw new Exception("SetByDerived variables that tunnel in to categorized states do not properly return their list through GetListOfStates"); } ScreenSave screenSave = new ScreenSave(); StateSaveCategory category = new StateSaveCategory(); category.Name = "Whatever"; screenSave.StateCategoryList.Add(category); StateSave stateInScreen = new StateSave(); stateInScreen.Name = "First"; category.States.Add(stateInScreen); variables = ExposedVariableManager.GetExposableMembersFor(screenSave, false).Select(item => item.Member).ToList(); if (variables.Contains("CurrentState") == false) { throw new NotImplementedException("Screens with states that are in categories that share variables are not properly returning the CurrentState as a possible variable"); } }
private void PopulateTunnelingVariables(string nameOfNamedObject, NamedObjectSave nos) { List <string> availableVariables = null; if (nos != null) { availableVariables = ExposedVariableManager.GetExposableMembersFor(nos).Select(item => item.Member).ToList(); // We should remove any variables that are already tunneled into foreach (CustomVariable customVariable in EditorLogic.CurrentElement.CustomVariables) { if (customVariable.SourceObject == nameOfNamedObject) { // Reverse loop since we're removing things for (int i = availableVariables.Count - 1; i > -1; i--) { if (availableVariables[i] == customVariable.SourceObjectProperty) { availableVariables.RemoveAt(i); break; } } } } } if (availableVariables != null) { availableVariables.Sort(); this.TunnelingVariableComboBox.Items.Clear(); if (availableVariables != null) { // We don't want to expose things like velocity an acceleration in Glue List <string> velocityAndAccelerationVariables = ExposedVariableManager.GetPositionedObjectRateVariables(); // We also don't want to expose relative values - the user just simply sets the value and the state/variable handles // whether it sets relative or absolute depending on whether the Entity is attached or not. // This behavior used to not exist, but users never knew when to use relative or absolute, and // that level of control is not really needed...if it is, custom code can probably handle it. List <string> relativeVariables = ExposedVariableManager.GetPositionedObjectRelativeValues(); foreach (string availableVariable in availableVariables) { if (!velocityAndAccelerationVariables.Contains(availableVariable) && !relativeVariables.Contains(availableVariable)) { this.TunnelingVariableComboBox.Items.Add(availableVariable); } } } } }
private static bool IsUserTryingToCreateNewWithExposableName(string resultName, bool isExposeTabSelected) { List <string> exposables = ExposedVariableManager.GetExposableMembersFor(EditorLogic.CurrentElement, false).Select(item => item.Member).ToList(); if (exposables.Contains(resultName)) { return(isExposeTabSelected == false); } else { return(false); } }
private static void AddAutoCompleteForElement(List <string> toReturn, IElement element) { foreach (NamedObjectSave nos in element.NamedObjects) { foreach (NamedObjectSave innerNos in nos.ContainedObjects) { toReturn.Add(innerNos.InstanceName); } toReturn.Add(nos.InstanceName); } foreach (CustomVariable customVariable in element.CustomVariables) { toReturn.Add(customVariable.Name); } if (element is ScreenSave) { toReturn.Add("PauseThisScreen()"); toReturn.Add("UnpauseThisScreen()"); toReturn.Add("IsPaused"); toReturn.Add("MoveToScreen(typeof("); } else if (element is EntitySave) { toReturn.Add("Destroy()"); } toReturn.AddRange( ExposedVariableManager.GetExposableMembersFor(element, false).Select(item => item.Member)); if (element.AllStates.GetCount() > 0) { toReturn.Add("CurrentState"); foreach (StateSaveCategory category in element.StateCategoryList) { if (!category.SharesVariablesWithOtherCategories) { toReturn.Add("Current" + category.Name + "State"); } } toReturn.Add("InterpolateToState("); } }
GetStandardValues(ITypeDescriptorContext context) { stringToReturn.Clear(); stringToReturn.Add("<NONE>"); string nameOfNamedObject = mCustomVariable.SourceObject; NamedObjectSave nos = mElement.GetNamedObjectRecursively(nameOfNamedObject); if (nos != null) { stringToReturn.AddRange(ExposedVariableManager.GetExposableMembersFor(nos).Select(item => item.Member)); } StandardValuesCollection svc = new StandardValuesCollection(stringToReturn); return(svc); }
private static void AddAutoCompleteFor(List <string> toFill, NamedObjectSave nos) { if (nos.SourceType == SourceType.Entity) { EntitySave entitySave = ObjectFinder.Self.GetEntitySave(nos.SourceClassType); if (entitySave != null) { AddAutoCompleteForElement(toFill, entitySave); } } else if (nos.SourceType == SourceType.FlatRedBallType) { toFill.AddRange(ExposedVariableManager.GetExposableMembersFor(nos).Select(item => item.Member)); if (nos.IsList) { toFill.Add("Count"); } } }
private void FillExposableVariables() { List <string> availableVariables = null; if (EditorLogic.CurrentEntitySave != null) { availableVariables = ExposedVariableManager.GetExposableMembersFor(EditorLogic.CurrentEntitySave, true).Select(item => item.Member).ToList(); } else if (EditorLogic.CurrentScreenSave != null) { availableVariables = ExposedVariableManager.GetExposableMembersFor(EditorLogic.CurrentScreenSave, true).Select(item => item.Member).ToList(); } if (availableVariables != null) { // We don't want to expose things like velocity an acceleration in Glue List <string> velocityAndAccelerationVariables = ExposedVariableManager.GetPositionedObjectRateVariables(); // We also don't want to expose relative values - the user just simply sets the value and the state/variable handles // whether it sets relative or absolute depending on whether the Entity is attached or not. // This behavior used to not exist, but users never knew when to use relative or absolute, and // that level of control is not really needed...if it is, custom code can probably handle it. List <string> relativeVariables = ExposedVariableManager.GetPositionedObjectRelativeValues(); foreach (string variableName in availableVariables) { if (!velocityAndAccelerationVariables.Contains(variableName) && !relativeVariables.Contains(variableName)) { AvailableVariablesComboBox.Items.Add(variableName); } } if (AvailableVariablesComboBox.Items.Count > 0) { AvailableVariablesComboBox.SelectedIndex = 0; } } }
private static void GenerateInterpolateForIndividualStateNoSource(ref ICodeBlock codeBlock, IElement element, ref ICodeBlock otherBlock, InstructionSave instruction, CustomVariable customVariable, string valueAsString, string timeCastString) { string velocityMember = FlatRedBall.Instructions.InstructionManager.GetVelocityForState(instruction.Member); // If the velocityMember exists, we need to make sure it's actually exposable if (!ExposedVariableManager.GetExposableMembersFor(element, false).Any(item => item.Member == velocityMember)) { velocityMember = null; } if (velocityMember == null && customVariable.HasAccompanyingVelocityProperty) { velocityMember = customVariable.Name + "Velocity"; } if (!string.IsNullOrEmpty(velocityMember)) { string relativeVelocity = InstructionManager.GetRelativeForAbsolute(velocityMember); string leftHandPlusEquals = null; if (!string.IsNullOrEmpty(relativeVelocity)) { codeBlock = codeBlock .If("this.Parent != null"); otherBlock = otherBlock .If("this.Parent != null"); string instructionMemberRelative = InstructionManager.GetRelativeForAbsolute(instruction.Member); leftHandPlusEquals = relativeVelocity + " = "; codeBlock.Line(leftHandPlusEquals + "(" + valueAsString + " - " + instructionMemberRelative + ") / " + timeCastString + "secondsToTake;"); otherBlock.Line(leftHandPlusEquals + " 0;"); codeBlock = codeBlock .End() .Else(); otherBlock = otherBlock .End() .Else(); } leftHandPlusEquals = velocityMember + " = "; codeBlock.Line(leftHandPlusEquals + "(" + valueAsString + " - " + instruction.Member + ") / " + timeCastString + "secondsToTake;"); otherBlock.Line(leftHandPlusEquals + " 0;"); if (!string.IsNullOrEmpty(relativeVelocity)) { codeBlock = codeBlock.End(); otherBlock = otherBlock.End(); } } }
private static void UpdateTypedMembers(this NamedObjectSave instance) { if (instance.SourceType == SourceType.Entity) { if (string.IsNullOrEmpty(instance.SourceClassType) || instance.SourceClassType == "<NONE>") { instance.TypedMembers.Clear(); } else { EntitySave entitySave = ObjectFinder.Self.GetEntitySave( instance.SourceClassType); if (entitySave != null) { instance.TypedMembers.Clear(); // This is null if a property that calls // UpdateProperties is called before the project // is loaded - as is the case when the GLUX is // deserialized. instance.TypedMembers.AddRange(entitySave.GetTypedMembers()); } } } else if (string.IsNullOrEmpty(instance.ClassType) || instance.ClassType.Contains("PositionedObjectList<")) { instance.TypedMembers.Clear(); } else if (instance.IsList) { // do nothing. } else { instance.TypedMembers.Clear(); // We used to only include members in the // ATI. Now we want to include every possible // variable so that they all show up in the PropertyGrid. //AssetTypeInfo ati = instance.GetAssetTypeInfo(); //if (ati == null) //{ // throw new NullReferenceException("Could not find an AssetType for the type " + // instance.SourceClassType + ". This either means that your ContenTypes CSV is corrupt, out of date, missing, or that you have not loaded a content types CSV if you are using teh GluxViewManager in a custom app."); // instance.TypedMembers.Clear(); //} //else //{ // instance.TypedMembers.Clear(); // instance.TypedMembers.AddRange(ati.GetTypedMembers()); //} List <MemberWithType> variables = ExposedVariableManager.GetExposableMembersFor(instance); foreach (var member in variables) { int errorCode = 0; try { errorCode = 0; string memberType = member.Type; errorCode = 1; memberType = TypeManager.ConvertToCommonType(memberType); errorCode = 2; Type type = TypeManager.GetTypeFromString(memberType); errorCode = 3; // Glue can't do anything with generic properties (yet) // Update: I'm adding support for it now //if (type != null && type.IsGenericType == false) TypedMemberBase typedMember = null; if (type != null) { typedMember = TypedMemberBase.GetTypedMemberUnequatable(member.Member, type); } else { typedMember = TypedMemberBase.GetTypedMemberUnequatable(member.Member, typeof(object)); typedMember.CustomTypeName = memberType; } instance.TypedMembers.Add(typedMember); } catch (Exception e) { throw new Exception("Error trying to fix member " + member + " in object " + instance + ". Error code: " + errorCode + "Additional info:\n\n\n" + e.ToString(), e); } } var ati = instance.GetAssetTypeInfo(); if (ati != null) { foreach (var member in ati.VariableDefinitions) { // Only consider this if it's not already handled: bool isAlreadyHandled = instance.TypedMembers.Any(item => item.MemberName == member.Name); if (!isAlreadyHandled) { string memberType = member.Type; memberType = TypeManager.ConvertToCommonType(memberType); Type type = TypeManager.GetTypeFromString(memberType); // Glue can't do anything with generic properties (yet) // Update: I'm adding support for it now //if (type != null && type.IsGenericType == false) TypedMemberBase typedMember = null; if (type != null) { typedMember = TypedMemberBase.GetTypedMemberUnequatable(member.Name, type); } else { typedMember = TypedMemberBase.GetTypedMemberUnequatable(member.Name, typeof(object)); typedMember.CustomTypeName = memberType; } instance.TypedMembers.Add(typedMember); } } } } }
public static bool IsNamedObjectNameValid(string name, NamedObjectSave namedObject, out string whyItIsntValid) { bool isDefinedInBaseButNotSetByDerived = false; int wasRemovedFromIndex; NamedObjectSave containerNos; IElement element; RemoveNosFromElementIfNecessary(namedObject, out wasRemovedFromIndex, out element, out containerNos); MembershipInfo membershipInfo = NamedObjectSaveExtensionMethodsGlue.GetMemberMembershipInfo(name); if (wasRemovedFromIndex != -1) { if (containerNos == null) { element.NamedObjects.Insert(wasRemovedFromIndex, namedObject); } else { containerNos.ContainedObjects.Insert(wasRemovedFromIndex, namedObject); } } if (membershipInfo == MembershipInfo.ContainedInBase) { // make sure this thing is set to be SetByDerived NamedObjectSave nos = EditorLogic.CurrentElement.GetNamedObjectRecursively(name); if (!nos.SetByDerived) { isDefinedInBaseButNotSetByDerived = true; } } whyItIsntValid = null; CheckForCommonImproperNames(name, ref whyItIsntValid); if (string.IsNullOrEmpty(whyItIsntValid)) { if (isDefinedInBaseButNotSetByDerived) { whyItIsntValid = "There is an object named " + name + " in the base Element but it is not Set By Derived."; } else if (membershipInfo == MembershipInfo.ContainedInThis) { whyItIsntValid = "The name " + name + " is already being used"; } else if (EditorLogic.CurrentElement != null && FileManager.RemovePath(EditorLogic.CurrentElement.Name) == name) { if (EditorLogic.CurrentElement is EntitySave) { whyItIsntValid = "You can't name your Object the same name as the Entity it is contained in."; } else { whyItIsntValid = "You can't name your Object the same name as the Screen it is contained in."; } } else if (string.IsNullOrEmpty(name)) { whyItIsntValid = "The name cannot be blank."; } else if (char.IsDigit(name[0])) { whyItIsntValid = "Object names can't start with numbers"; } else if (name.Contains(' ')) { whyItIsntValid = "Object names can't have spaces"; } else if (EditorLogic.CurrentElement != null && ExposedVariableManager.GetExposableMembersFor(EditorLogic.CurrentElement, false).Any(item => item.Member == name)) { whyItIsntValid = "The name " + name + " is an existing or exposable variable name in " + EditorLogic.CurrentElement.ToString() + " so it is not a valid object name"; } else if (mOtherReservedNames.Contains(name)) { whyItIsntValid = "The name \"" + name + "\" is not an allowed name for objects. "; } else if (IsPositionedObjectMember(name)) { whyItIsntValid = "The name \"" + name + "\" is a reserved name by the PositionedObject Type."; } } return(string.IsNullOrEmpty(whyItIsntValid)); }
public static InterpolationCharacteristic GetInterpolationCharacteristic(CustomVariable customVariable, IElement container) { string variableType = null; if (customVariable != null) { if (!string.IsNullOrEmpty(customVariable.OverridingPropertyType)) { variableType = customVariable.OverridingPropertyType; } else { variableType = customVariable.Type; } } if (customVariable != null && customVariable.GetIsVariableState(container)) { return(InterpolationCharacteristic.CanInterpolate); } if (customVariable == null || variableType == null || variableType == "string" || variableType == "bool" || variableType == "Color" || customVariable.GetIsFile() || customVariable.GetIsCsv() || (customVariable.GetRuntimeType() != null && customVariable.GetRuntimeType().IsEnum) ) { return(InterpolationCharacteristic.CantInterpolate); } string velocityMember = null; if (!string.IsNullOrEmpty(customVariable.SourceObject)) { velocityMember = FlatRedBall.Instructions.InstructionManager.GetVelocityForState(customVariable.SourceObjectProperty); } else { velocityMember = FlatRedBall.Instructions.InstructionManager.GetVelocityForState(customVariable.Name); } if (!string.IsNullOrEmpty(velocityMember)) { // There's a velocity variable for this, but we need to make sure // it's actually available var exposableMembers = ExposedVariableManager.GetExposableMembersFor(container, false); if (exposableMembers.Any(item => item.Member == velocityMember)) { return(InterpolationCharacteristic.CanInterpolate); } } // December 26, 2013 // This used to not pass // a value for maxDepth which // means a maxDepth of 0. Not // sure why, but we do want to look // at tunneling at any depth. int maxDepth = int.MaxValue; if (customVariable.HasAccompanyingVelocityConsideringTunneling(container, maxDepth)) { return(InterpolationCharacteristic.CanInterpolate); } else { return(InterpolationCharacteristic.NeedsVelocityVariable); } }