public static bool CanBeInList(this NamedObjectSave instance, NamedObjectSave listNos) { if (listNos.SourceClassGenericType == instance.SourceClassType || listNos.SourceClassGenericType == instance.InstanceType || listNos.SourceClassGenericType == instance.GetAssetTypeInfo()?.QualifiedRuntimeTypeName.QualifiedType) { return(true); } if (instance.SourceType == SourceType.Entity) { EntitySave instanceElement = instance.GetReferencedElement() as EntitySave; IElement listElementType = ObjectFinder.Self.GetIElement(listNos.SourceClassGenericType); if (instanceElement == null || listElementType == null) { return(false); } if (instanceElement.InheritsFrom(listNos.SourceClassGenericType)) { return(true); } } return(false); }
public static void UpdateShownVariables(DataUiGrid grid, NamedObjectSave instance, IElement container) { grid.Categories.Clear(); List<MemberCategory> categories = new List<MemberCategory>(); var defaultCategory = new MemberCategory("Variables"); defaultCategory.FontSize = 14; categories.Add(defaultCategory); AssetTypeInfo ati = instance.GetAssetTypeInfo(); // not sure if this is needed: if (instance.TypedMembers.Count == 0) { instance.UpdateCustomProperties(); } CreateCategoriesAndVariables(instance, container, categories, ati); if (ati != null) { SortCategoriesAndMembers(ref categories, ati); } if (defaultCategory.Members.Count == 0) { categories.Remove(defaultCategory); } else if (categories.Count != 1) { defaultCategory.Name = "Other Variables"; } if (categories.Count != 0) { // "Name" should be the very first property: var nameCategory = CreateNameInstanceMember(instance); categories.Insert(0, nameCategory); } SetAlternatingColors(grid, categories); foreach(var category in categories) { grid.Categories.Add(category); } grid.Refresh(); }
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); } } } } }
private static void AddCodeForIsOn(ICodeBlock codeBlock, NamedObjectSave nos) { string condition = null; AssetTypeInfo ati = nos.GetAssetTypeInfo(); if (ati != null && ati.HasCursorIsOn) { bool shouldConsiderVisible = ati.QualifiedRuntimeTypeName.QualifiedType == "FlatRedBall.Sprite" || ati.QualifiedRuntimeTypeName.QualifiedType == "FlatRedBall.ManagedSpriteGroups.SpriteFrame" || ati.QualifiedRuntimeTypeName.QualifiedType == "FlatRedBall.Graphics.Text"; bool shouldConsiderAlpha = ati.QualifiedRuntimeTypeName.QualifiedType == "FlatRedBall.Sprite" || ati.QualifiedRuntimeTypeName.QualifiedType == "FlatRedBall.ManagedSpriteGroups.SpriteFrame" || ati.QualifiedRuntimeTypeName.QualifiedType == "FlatRedBall.Graphics.Text"; string whatToFormat; if (shouldConsiderVisible) { whatToFormat = "{0}.AbsoluteVisible && cursor.IsOn3D({0}, LayerProvidedByContainer)"; } else if (ati.QualifiedRuntimeTypeName.QualifiedType == "FlatRedBall.Scene") { whatToFormat = "cursor.IsOn3D({0}, LayerProvidedByContainer, false)"; } else { whatToFormat = "cursor.IsOn3D({0}, LayerProvidedByContainer)"; } if (shouldConsiderAlpha) { whatToFormat = "{0}.Alpha != 0 && " + whatToFormat; } condition = string.Format(whatToFormat, nos.InstanceName); } else if (nos.SourceType == SourceType.Entity) { EntitySave entitySave = ObjectFinder.Self.GetEntitySave(nos.SourceClassType); if (entitySave != null) { // This happens if: // The user has an Entity which is IWindow // The user adds a new object // The user sets the object to Entity - this will cause a code regeneration and this will be null; if (entitySave.ImplementsIWindow || entitySave.ImplementsIClickable) { condition = string.Format("{0}.HasCursorOver(cursor)", nos.InstanceName); } } } if (condition != null) { codeBlock.If(condition) .Line("return true;"); } }
public static List<ExposableEvent> GetExposableEventsFor(NamedObjectSave namedObjectSave, IElement parent) { List<ExposableEvent> returnValues = new List<ExposableEvent>(); if (namedObjectSave != null) { switch (namedObjectSave.SourceType) { case SourceType.Entity: EntitySave entitySave = ObjectFinder.Self.GetEntitySave(namedObjectSave.SourceClassType); if (entitySave == null) { // do nothing //return returnValues; } else { returnValues = GetExposableEventsFor(entitySave, false); } break; case SourceType.FlatRedBallType: if (namedObjectSave.SourceClassType == "PositionedObjectList<T>") { returnValues.Add(new ExposableEvent("CollectionChanged")); } break; case SourceType.File: var ati = namedObjectSave.GetAssetTypeInfo(); if (ati != null && ati.ImplementsIWindow) { AddIWindowEvents(returnValues); } break; } #if GLUE PluginManager.AddEventsForObject(namedObjectSave, returnValues); #endif } if (parent != null) { for (int i = returnValues.Count - 1; i > -1; i--) { bool found = false; foreach (EventResponseSave ers in parent.Events) { if (ers.SourceObject == namedObjectSave.InstanceName && ers.SourceObjectEvent == returnValues[i].Name) { found = true; break; } } if (found) { returnValues.RemoveAt(i); } } } return returnValues; }
private static bool GenerateInstantiationOrAssignment(NamedObjectSave namedObject, IElement saveObject, ICodeBlock codeBlock, string overridingName, List<string[]> referencedFilesAlreadyUsingFullFile) { AssetTypeInfo nosAti = AvailableAssetTypes.Self.GetAssetTypeFromRuntimeType(namedObject.InstanceType); string objectName = namedObject.FieldName; bool succeeded = true; #region If SourceType is File if (namedObject.SourceType == SourceType.File) { if (string.IsNullOrEmpty(namedObject.SourceFile)) { succeeded = false; } else { EntitySave entitySave = null; ReferencedFileSave rfs = GetReferencedFileSaveReferencedByNamedObject(namedObject, saveObject, ref entitySave); #region //////////////////////EARLY OUT!!!! Exit out if the RFS is null or the name is bad if (rfs == null && string.IsNullOrEmpty(overridingName)) { if (!string.IsNullOrEmpty(namedObject.SourceFile)) { // July 11, 2011 // I used to think // that it was best // to "should loudly" // whenever encountering // a bug, however, breaking // the build for everyone is // not the way to do it. Intead // I'm going to make this not generate // any code if there is no SourceFile, and // we should have some way in Glue to search // for and find incomplete definitions. //string exceptionString = "This object references the file " + // namedObject.SourceFile + " which is not part of this object."; //stringBuilder.AppendLine("\t\t\tthrow new InvalidOperationException(\"" + exceptionString + "\");"); succeeded = false; } else { succeeded = false; } } if ((string.IsNullOrEmpty(namedObject.SourceName) || namedObject.SourceName == "<NONE>") && FileManager.GetExtension(namedObject.SourceFile) != "srgx") { succeeded = false; } #endregion if (succeeded) { string containerName = overridingName; if (rfs != null) { containerName = rfs.GetInstanceName();// FileManager.RemovePath(FileManager.RemoveExtension(namedObject.SourceFile)); } List<StateSave> statesUsingThisNamedObject = saveObject.GetAllStatesReferencingObject(objectName); if (statesUsingThisNamedObject.Count != 0) { InstantiateObjectInSwitchStatement(namedObject, codeBlock, referencedFilesAlreadyUsingFullFile, nosAti, objectName, rfs, statesUsingThisNamedObject, saveObject, containerName, null); } else { InstantiateObjectUsingFile(namedObject, codeBlock, referencedFilesAlreadyUsingFullFile, nosAti, objectName, rfs, saveObject, containerName, overridingName); } } } } #endregion else if (namedObject.SourceType == SourceType.FlatRedBallType) { // We treat Cameras in a special way: if (namedObject.ClassType == "Camera") { if (namedObject.IsNewCamera) { string contentManagerNameString = "ContentManagerName"; codeBlock.Line(objectName + " = new FlatRedBall.Camera(" + contentManagerNameString + ");"); codeBlock.Line("FlatRedBall.SpriteManager.Cameras.Add(" + objectName + ");"); } else { codeBlock.Line(objectName + " = FlatRedBall.SpriteManager.Camera;"); } } else if (namedObject.IsContainer) { codeBlock.Line(objectName + " = this;"); } else { string qualifiedName = namedObject.GetQualifiedClassType(); if (namedObject.GetAssetTypeInfo() != null) { qualifiedName = namedObject.GetAssetTypeInfo().QualifiedRuntimeTypeName.QualifiedType; } codeBlock.Line(string.Format("{0} = new {1}();", objectName, qualifiedName)); if (namedObject.IsLayer || namedObject.SourceType == SourceType.FlatRedBallType) { codeBlock.Line(string.Format("{0}.Name = \"{1}\";", objectName, objectName)); } } } #region else if SourceType is Entity else // SourceType == SourceType.Entity { codeBlock.Line(string.Format("{0} = new {1}(ContentManagerName, false);", objectName, GetQualifiedTypeName(namedObject))); codeBlock.Line(string.Format("{0}.Name = \"{1}\";", objectName, objectName)); // If it's an Entity List that references a List that can be created by Entities, then the Screen should register this list with the factory } #endregion return succeeded; }
private static void UpdateTypedMembers(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); } } } } }
private static Type FillWithExposableMembersForFlatRedBallType(NamedObjectSave namedObjectSave, List<MemberWithType> returnValue, Type type) { AssetTypeInfo assetTypeInfo = namedObjectSave.GetAssetTypeInfo(); if (assetTypeInfo != null && !string.IsNullOrEmpty(assetTypeInfo.Extension)) { returnValue.Add(new MemberWithType { Member = "SourceFile", Type = "string" }); } if (assetTypeInfo != null && !string.IsNullOrEmpty(assetTypeInfo.QualifiedRuntimeTypeName.QualifiedType)) { // if the type is null, that means this // may be a type that comes from plugins. // Therefore we won't show any variables (for // now). Maybe at some point in the future we'll // figure out a way to get the variables out - perhaps // by loading an assembly or by supporting CSV variable // definition. I think assembly-based may not be the way // to go because we'll have to start working with appdomains. // Update January 24, 2014 // We now do support variables // from CSVs. We should handle // adding variables here...or below // the if check. // Update October 28, 2015 // CSV is the way to go, or at least AssetTypeInfo. This allows // ultimate customization, including excluding variables. If we have // variables defined in the VariableDefinitions, then let's just use that // and not use any reflection: // Update October 28, 2015 // If we do this, we lose things like enumerations, Texture2D, and other types // that Glue does know how to work with automatically. So instead, we want to rely // on the variable definitions to give us our variables, and then qualify their types // if we can through reflection, and only if their type name agrees with the VariableDefinition type = TypeManager.GetTypeFromString(assetTypeInfo.QualifiedRuntimeTypeName.QualifiedType); // We'll fall back to reflection, but eventually I'd like to see this go away if (type != null) { FillListWithAvailableVariablesInType(type, returnValue); AddSpecialCasePropertiesFor(type, returnValue); } foreach (var variable in assetTypeInfo.VariableDefinitions) { bool isAlreadyHandled = returnValue.Any(item => item.Member == variable.Name); if(!isAlreadyHandled) { returnValue.Add(new MemberWithType { Member = variable.Name, Type = variable.Type }); } bool needsCustomType = isAlreadyHandled && !string.IsNullOrEmpty(variable.Type) && returnValue.Any(item => item.Member == variable.Name && AreTypesEquivalent(item.Type, variable.Type) == false); if(needsCustomType) { var existing = returnValue.FirstOrDefault(item => item.Member == variable.Name); existing.Type = variable.Type; } } } else if (namedObjectSave.IsList && !string.IsNullOrEmpty(namedObjectSave.SourceClassGenericType)) { // special case - if the list is of IVisibles, then // let's allow the user to set visibility on the whole // list. EntitySave entityTypeInList = ObjectFinder.Self.GetEntitySave(namedObjectSave.SourceClassGenericType); if (entityTypeInList != null && entityTypeInList.ImplementsIVisible) { returnValue.Add(new MemberWithType { Member = "Visible", Type = "bool" }); } } // June 23, 2013 // I don't think we // want to sort here // because the properties // will already be sorted in // a particular way from the function // FillListWithAvailableVariablesInType. // I'm going to comment this out to see if // it causes any problems. //returnValue.Sort(); return type; }
public static void WriteAddToManagersForNamedObject(IElement element, NamedObjectSave namedObject, ICodeBlock codeBlock, bool isInVariableSetterProperty = false, bool considerRemoveIfInvisible = true) { bool shouldEarlyOut = namedObject.IsFullyDefined == false || (namedObject.SetByDerived || namedObject.IsDisabled || !namedObject.Instantiate || namedObject.IsContainer) || (namedObject.SetByContainer && element is EntitySave) // Screens can't be contained, so we don't want to early out on Screens || (namedObject.SourceType == SourceType.File && (string.IsNullOrEmpty(namedObject.SourceName) || namedObject.SourceName == "<NONE>")) ; if (!shouldEarlyOut) { AddIfConditionalSymbolIfNecesssary(codeBlock, namedObject); bool isInsideVisibleProperty = considerRemoveIfInvisible == false; string objectName = namedObject.FieldName; AssetTypeInfo ati = namedObject.GetAssetTypeInfo(); if ((considerRemoveIfInvisible && namedObject.RemoveFromManagersWhenInvisible && IsInvisible(namedObject, element))) { if (namedObject.SourceType == SourceType.Entity) { // since we want to have all contained elements in namedObject also call AssignCustomVariables, we'll pass 'true' codeBlock.Line(objectName + ".AssignCustomVariables(true);"); } // else, we don't do anything here, but we do want the outer if statement to evaluate to true to prevent the addition from occurring below. } else { // If we're setting this // in a variable setter, that // means that this code is going // to be used to dynamically set the // source of an object. In that case, // the object will not have yet been added // to the managers. Also, files that are assigned // here are assumed to also not have been added to managers // because they should have their LoadedOnlyWhenReferenced property // set to true. bool isAddedToManagerByFile = !isInVariableSetterProperty && IsAddedToManagerByFile(element, namedObject); bool addedRegularly = namedObject.AddToManagers && !namedObject.InstantiatedByBase && !isAddedToManagerByFile; if (addedRegularly) { string layerName = "null"; if (!string.IsNullOrEmpty(namedObject.LayerOn)) { if (namedObject.LayerOn == AvailableLayersTypeConverter.UnderEverythingLayerName) { layerName = AvailableLayersTypeConverter.UnderEverythingLayerCode; } else { layerName = namedObject.LayerOn; } } else if (element is EntitySave) { layerName = "LayerProvidedByContainer"; } else if (element is ScreenSave) { layerName = "mLayer"; } #region There is an ATI - it's a type defined in the ContentTypes.csv file in Glue if (ati != null) { if ((BaseElementTreeNode.IsOnOwnLayer(element) || !string.IsNullOrEmpty(namedObject.LayerOn)) && ati.LayeredAddToManagersMethod.Count != 0 && !string.IsNullOrEmpty(ati.LayeredAddToManagersMethod[0])) { string layerAddToManagersMethod = DecideOnLineToAdd(namedObject, ati, true); // This used to be inside the if(element is EntitySave) but // I think we want it even if the ElementSave is a Screen. layerAddToManagersMethod = layerAddToManagersMethod.Replace("mLayer", layerName); codeBlock.Line(layerAddToManagersMethod.Replace("this", objectName) + ";"); } else { if (ati.AddToManagersMethod.Count != 0 && !string.IsNullOrEmpty(ati.AddToManagersMethod[0])) { string addLine = DecideOnLineToAdd(namedObject, ati, false); codeBlock.Line(addLine.Replace("this", objectName) + ";"); if (namedObject.IsLayer && element is EntitySave) { string layerToAddAbove = layerName; int indexOfThis = element.NamedObjects.IndexOf(namedObject); for (int i = 0; i < indexOfThis; i++) { if (element.NamedObjects[i].IsLayer && !element.NamedObjects[i].IsDisabled) { layerToAddAbove = element.NamedObjects[i].InstanceName; } } //If the EntitySave contains a Layer, the Layer should be inserted after whatever Layer the Entity is on. codeBlock.Line("FlatRedBall.SpriteManager.MoveLayerAboveLayer(" + objectName + ", " + layerToAddAbove + ");"); } } } AddLayerSpecificAddToManagersCode(namedObject, codeBlock, objectName); AddTextSpecificAddToManagersCode(namedObject, codeBlock, objectName, layerName); } #endregion #region No ATI - is it an Entity? else if (namedObject.SourceType == SourceType.Entity) { if (isInsideVisibleProperty) { codeBlock.Line(objectName + ".ReAddToManagers(" + layerName + ");"); } else { codeBlock.Line(objectName + ".AddToManagers(" + layerName + ");"); } } #endregion #region If this object is ignored in pausing, add it to the InstructionManager's ignored list PauseCodeGenerator.AddToPauseIgnoreIfNecessary(codeBlock, element, namedObject); #endregion } #region Special Case: Add any aliased ReferencedFileSaves that are on layers to the layer // Special Case: If a NamedObject is an EntireFile, // and the source ReferencedFileSave is not shared static, // then that means that the NamedObject is essentially just // used to access the ReferencedFileSave in Glue. The user may // be using the NamedObject to place the ReferencedfileSave on a // layer, so we should check for that // This bool construction // used to also say: // namedObject.SourceName.Contains("Entire ") // but I think we want this // added to a Layer even if it // an entire file. bool shouldAddToLayer = (!namedObject.AddToManagers || isAddedToManagerByFile) && !string.IsNullOrEmpty(namedObject.LayerOn) && namedObject.SourceType == SourceType.File && namedObject.SourceName != null && //namedObject.SourceName.Contains("Entire ") && ati != null && ati.LayeredAddToManagersMethod.Count != 0 && !string.IsNullOrEmpty(ati.LayeredAddToManagersMethod[0]); if (shouldAddToLayer) { string layerAddToManagersMethod = ati.LayeredAddToManagersMethod[0]; string layerName; if (namedObject.LayerOn == AvailableLayersTypeConverter.UnderEverythingLayerName) { layerName = AvailableLayersTypeConverter.UnderEverythingLayerCode; } else { layerName = namedObject.LayerOn; } layerAddToManagersMethod = layerAddToManagersMethod.Replace("mLayer", layerName); codeBlock.Line(layerAddToManagersMethod.Replace("this", objectName) + ";"); } #endregion } AddEndIfIfNecessary(codeBlock, namedObject); } }
public static void GenerateVariableAssignment(NamedObjectSave namedObject, ICodeBlock codeBlock) { IEnumerable<CustomVariableInNamedObject> enumerable = namedObject.InstructionSaves; var ati = namedObject.GetAssetTypeInfo(); string extraVariablePattern = null; if (ati != null) { extraVariablePattern = ati.ExtraVariablesPattern; } string[] extraVariables; if (extraVariablePattern != null) { extraVariables = extraVariablePattern.Split(';'); for (int i = 0; i < extraVariables.Length; i++) { extraVariables[i] = extraVariables[i].Trim().Substring(extraVariables[i].Trim().IndexOf(' ') + 1); } enumerable = enumerable.OrderBy(item => { if (extraVariables.Contains(item.Member)) { return namedObject.InstructionSaves.IndexOf(item) - namedObject.InstructionSaves.Count; } else { return namedObject.InstructionSaves.IndexOf(item); } }); } else { extraVariables = new string[0]; } foreach (var instructionSave in enumerable) { IElement element = null; if (namedObject.SourceType == SourceType.Entity) { element = ObjectFinder.Self.GetIElement(namedObject.SourceClassType); } if (ExposedVariableManager.IsExposedVariable(instructionSave.Member, namedObject) || (element != null && element.GetCustomVariableRecursively(instructionSave.Member) != null) || // Could be something set by container: (element != null && element.GetNamedObjectRecursively(instructionSave.Member) != null) ) { CustomVariableCodeGenerator.AppendAssignmentForCustomVariableInInstance(namedObject, codeBlock, instructionSave); } } }
public static string GetQualifiedTypeName(NamedObjectSave namedObjectSave) { if (namedObjectSave.SourceType == SaveClasses.SourceType.Entity && !string.IsNullOrEmpty(namedObjectSave.SourceClassType)) { return ProjectManager.ProjectNamespace + '.' + namedObjectSave.SourceClassType.Replace('\\', '.'); } else if (namedObjectSave.GetAssetTypeInfo() != null) { return namedObjectSave.GetAssetTypeInfo().QualifiedRuntimeTypeName.QualifiedType; } else { return namedObjectSave.GetQualifiedClassType(); } }
private static bool IsUncloneableEntireFile(NamedObjectSave namedObject) { if (namedObject.IsEntireFile) { AssetTypeInfo ati = namedObject.GetAssetTypeInfo(); if (ati != null && ati.CanBeCloned == false) { return true; } } return false; }
private static void FillWithExposableMembersForFlatRedBallType(NamedObjectSave namedObjectSave, List<MemberWithType> returnValue) { AssetTypeInfo assetTypeInfo = namedObjectSave.GetAssetTypeInfo(); if (assetTypeInfo != null && !string.IsNullOrEmpty(assetTypeInfo.Extension)) { returnValue.Add(new MemberWithType { Member = "SourceFile", Type = "string" }); } // slowly move away from reflection: // To do this, the CSV has to include // types for variables. Until it does, we // are going to continue to rely on reflection. if (assetTypeInfo != null && (assetTypeInfo.FriendlyName == "Sprite" || assetTypeInfo.FriendlyName == "AxisAlignedRectangle" || assetTypeInfo.FriendlyName == "Circle" || assetTypeInfo.FriendlyName == "Polygon" || assetTypeInfo.FriendlyName == "Layer" )) { if(assetTypeInfo.VariableDefinitions.Any(definition=> string.IsNullOrEmpty( definition.Type))) { throw new InvalidOperationException("The type " + assetTypeInfo.FriendlyName + " has variables without a type"); } var toAdd = assetTypeInfo.VariableDefinitions .Select(definition => new MemberWithType { Member = definition.Name, Type = definition.Type }); returnValue.AddRange(toAdd); } else if (assetTypeInfo != null && !string.IsNullOrEmpty(assetTypeInfo.QualifiedRuntimeTypeName.QualifiedType)) { var type = TypeManager.GetTypeFromString(assetTypeInfo.QualifiedRuntimeTypeName.QualifiedType); // We'll fall back to reflection, but eventually I'd like to see this go away if (type != null) { FillListWithAvailableVariablesInType(type, returnValue); AddSpecialCasePropertiesFor(type, returnValue); } FillFromVariableDefinitions(returnValue, assetTypeInfo); } else if (namedObjectSave.IsList && !string.IsNullOrEmpty(namedObjectSave.SourceClassGenericType)) { // special case - if the list is of IVisibles, then // let's allow the user to set visibility on the whole // list. EntitySave entityTypeInList = ObjectFinder.Self.GetEntitySave(namedObjectSave.SourceClassGenericType); if (entityTypeInList != null && entityTypeInList.ImplementsIVisible) { returnValue.Add(new MemberWithType { Member = "Visible", Type = "bool" }); } } // June 23, 2013 // I don't think we // want to sort here // because the properties // will already be sorted in // a particular way from the function // FillListWithAvailableVariablesInType. // I'm going to comment this out to see if // it causes any problems. //returnValue.Sort(); }
public static void UpdateShownVariables(DataUiGrid grid, NamedObjectSave instance, IElement container) { grid.Categories.Clear(); List<MemberCategory> categories = new List<MemberCategory>(); var defaultCategory = new MemberCategory("Variables"); defaultCategory.FontSize = 14; categories.Add(defaultCategory); AssetTypeInfo ati = instance.GetAssetTypeInfo(); // not sure if this is needed: if (instance.TypedMembers.Count == 0) { instance.UpdateCustomProperties(); } for (int i = 0; i < instance.TypedMembers.Count; i++) { TypedMemberBase typedMember = instance.TypedMembers[i]; InstanceMember instanceMember = CreateInstanceMember(instance, container, typedMember, ati); var categoryToAddTo = GetOrCreateCategoryToAddTo(categories, ati, typedMember); if (instanceMember != null) { categoryToAddTo.Members.Add(instanceMember); } } if (ati != null) { SortCategoriesAndMembers(ref categories, ati); } if (defaultCategory.Members.Count == 0) { categories.Remove(defaultCategory); } else if(categories.Count != 1) { defaultCategory.Name = "Other Variables"; } if (categories.Count != 0) { // "Name" shoul be the very first property: var nameCategory = CreateNameInstanceMember(instance); //categories.Add(nameCategory); categories.Insert(0, nameCategory); //categories.First().Members.Insert(0, nameInstanceMember); } // skip the first category in putting the alternating colors: for (int i = 0; i < categories.Count; i++) { var category = categories[i]; if (i != 0) { const byte brightness = 227; category.SetAlternatingColors(new SolidColorBrush(Color.FromRgb(brightness, brightness, brightness)), Brushes.Transparent); } grid.Categories.Add(category); } grid.Refresh(); }
public static string GetMemberTypeForNamedObject(NamedObjectSave namedObject, string variableName) { Type typeOfNamedObject = null; string foundType = null; var ati = namedObject.GetAssetTypeInfo(); switch (namedObject.SourceType) { case SourceType.Entity: EntitySave entitySave = ObjectFinder.Self.GetEntitySave(namedObject.SourceClassType); typeOfNamedObject = typeof(PositionedObject); if (entitySave != null) { CustomVariable customVariable = entitySave.GetCustomVariable(variableName); if (customVariable == null) { if (variableName.StartsWith("Current") && variableName.EndsWith("State")) { if (variableName == "CurrentState") { foundType = "VariableState"; } else { foundType = variableName.Substring("Current".Length, variableName.Length - ("Current".Length + "State".Length)); } } else if (variableName == "Visible" && // Should this check recursively? (entitySave.ImplementsIVisible || entitySave.InheritsFromFrbType())) { foundType = "bool"; } else if (variableName == "Enabled" && entitySave.ImplementsIWindow) { foundType = "bool"; } } else if (entitySave.ContainsCustomVariable(variableName)) { CustomVariable foundVariable = entitySave.GetCustomVariable(variableName); if (!string.IsNullOrEmpty(foundVariable.OverridingPropertyType)) { foundType = foundVariable.OverridingPropertyType; } else { foundType = foundVariable.Type; } } } break; case SourceType.File: { if (ati != null && ati.CachedExtraVariables.Any(item => item.Member == variableName)) { foundType = ati.CachedExtraVariables.First(item => item.Member == variableName).Type; } else { string typeAsString = namedObject.InstanceType; typeOfNamedObject = TypeManager.GetTypeFromString( typeAsString); } } break; case SourceType.FlatRedBallType: if (variableName == "SourceFile") { return namedObject.ClassType; } else if (ati != null && ati.CachedExtraVariables.Any(item => item.Member == variableName)) { foundType = ati.CachedExtraVariables.First(item => item.Member == variableName).Type; } else if (ati != null && !string.IsNullOrEmpty(ati.QualifiedRuntimeTypeName.QualifiedType)) { typeOfNamedObject = TypeManager.GetTypeFromString(ati.QualifiedRuntimeTypeName.QualifiedType); } else if (namedObject.IsList && variableName == "Visible") { foundType = "bool"; } break; } if (!string.IsNullOrEmpty(foundType)) { return foundType; } else { Type type = GetTypeForMemberInType(typeOfNamedObject, variableName); if(type == null) { type = typeof(string); } string toReturn = type.Name; if (type.IsGenericType) { var split = type.Name.Split('`'); string firstPart = split[0]; int numberOfParams = int.Parse(split[1]); if (numberOfParams > 1) { // need to add support //throw new Exception(); } else { var result = type.GetGenericArguments(); toReturn = firstPart + "<" + result[0].Name + ">"; } } return toReturn; } }
private static void WriteAttachTo(NamedObjectSave namedObject, ICodeBlock codeBlock, List<string[]> referencedFilesAlreadyUsingFullFile, ReferencedFileSave rfs) { string objectName = namedObject.FieldName; AssetTypeInfo ati = namedObject.GetAssetTypeInfo(); if ((namedObject.GetContainerType() == ContainerType.Entity && namedObject.AttachToContainer) || namedObject.AttachToCamera) { bool shouldAttach = true; if (ati != null) { shouldAttach = ati.ShouldAttach; } if (namedObject.IsList) { shouldAttach = false; } if (shouldAttach) { string whatToAttachTo = "this"; if (namedObject.AttachToCamera) { whatToAttachTo = "FlatRedBall.Camera.Main"; } // Files (like .scnx) can // contain objects which can // be attached to other objects // in the file. In some cases this // hierarchy is important. Therefore, // the generated code will string attachMethodCall = "AttachTo"; bool wrapInIf = true; if (ati != null && !string.IsNullOrEmpty(ati.AttachToNullOnlyMethod)) { attachMethodCall = ati.AttachToNullOnlyMethod; wrapInIf = false; } string tabs = "\t\t\t"; if (namedObject.ClassType == "SpriteRig") { codeBlock.Line(objectName + ".Root.AttachTo(" + whatToAttachTo + ", true);"); } else { var currentBlock = codeBlock; if (wrapInIf) { currentBlock = currentBlock .If(objectName + ".Parent == null"); } // March 26, 2012 // We used to attach // objects to their parents // by using absolute positions. // The problem is that this means // that if a script ran before the // attachment happened (when a variable // was set) then the script may run before // attachment happened and sometimes after. // That means users would have to handle both // relative and absoltue cases. We're going to // make attachments happen first so that attachment // happens right away - then the user can always write // scripts using relative values. WriteCopyToAbsoluteInInitializeCode(namedObject, currentBlock, referencedFilesAlreadyUsingFullFile, ati, objectName, rfs); // March 27, 2012 // We used to attach // by passing 'true' as // the 2nd argument meaning // that the relative values were // set from absolute. Now we use // the relative values so that the // script can simply set Relative values // always whether it's before or after attachment // and it'll just work. if (namedObject.AttachToCamera) { string adjustRelativeZLine = null; if (ati != null && !string.IsNullOrEmpty(ati.AdjustRelativeZ)) { adjustRelativeZLine = ati.AdjustRelativeZ; } else { adjustRelativeZLine = "this.RelativeZ += value"; } adjustRelativeZLine = adjustRelativeZLine.Replace("this", "{0}").Replace("value", "{1}"); currentBlock.Line(string.Format(adjustRelativeZLine, objectName, "-40") + ";"); } currentBlock.Line(objectName + "." + attachMethodCall + "(" + whatToAttachTo + ", false);"); } } } }
public static List<MemberWithType> GetExposableMembersFor(NamedObjectSave namedObjectSave) { List<MemberWithType> returnValue = new List<MemberWithType>(); Type type = null; if (namedObjectSave != null) { switch (namedObjectSave.SourceType) { case SourceType.Entity: EntitySave entitySave = ObjectFinder.Self.GetEntitySave(namedObjectSave.SourceClassType); if (entitySave == null) { return returnValue; } else { return GetTunnelableMembersFor(entitySave, false); } //break; case SourceType.File: string typeAsString = namedObjectSave.InstanceType; type = TypeManager.GetTypeFromString( typeAsString); if (type != null) { FillListWithAvailableVariablesInType(type, returnValue); } break; case SourceType.FlatRedBallType: type = FillWithExposableMembersForFlatRedBallType(namedObjectSave, returnValue, type); break; } } AssetTypeInfo ati = namedObjectSave.GetAssetTypeInfo(); if (ati != null) { // we convert from a string member to a typed member, only to go back to a string member. // That means we lose type info on any member that is of type not understood by Glue. // Not sure why the code does this, but we could just directly add the member from CachedExtraVariables //List<TypedMemberBase> typedMembers = null; //typedMembers = ati.GetTypedMembers(); foreach (var member in ati.CachedExtraVariables) { if (!returnValue.Any(item=>item.Member == member.Member)) { returnValue.Add(member); } } } return returnValue; }
public static void GetPostCustomActivityForNamedObjectSave(IElement container, NamedObjectSave namedObjectSave, ICodeBlock codeBlock) { if (!string.IsNullOrEmpty(namedObjectSave.ClassType)) { AssetTypeInfo ati = namedObjectSave.GetAssetTypeInfo();// AvailableAssetTypes.Self.GetAssetTypeFromRuntimeType(namedObjectSave.ClassType); if (ati != null && !string.IsNullOrEmpty(ati.AfterCustomActivityMethod)) { bool shouldGenerate = true; if (namedObjectSave.SourceType == SourceType.File && !string.IsNullOrEmpty(namedObjectSave.SourceFile)) { ReferencedFileSave rfs = container.GetReferencedFileSaveRecursively(namedObjectSave.SourceFile); if (rfs != null && !rfs.IsSharedStatic) { shouldGenerate = false; } } if (shouldGenerate) { bool wrappInNullCheck = namedObjectSave.Instantiate == false; if (wrappInNullCheck) { codeBlock = codeBlock.If(namedObjectSave.InstanceName + " != null"); } codeBlock.Line(ati.AfterCustomActivityMethod.Replace("this", namedObjectSave.InstanceName) + ";"); if (wrappInNullCheck) { codeBlock = codeBlock.End(); } } } } }
public static CodeBuilder.ICodeBlock AddToPauseIgnoreIfNecessary(CodeBuilder.ICodeBlock codeBlock, IElement element, NamedObjectSave nos) { if (nos.IgnoresPausing) { if (nos.SourceType == SourceType.Entity && !string.IsNullOrEmpty(nos.SourceClassType)) { // it's an Entity codeBlock.Line(nos.InstanceName + ".SetToIgnorePausing();"); } else if (nos.GetAssetTypeInfo() != null && nos.GetAssetTypeInfo().CanIgnorePausing) { codeBlock.Line("FlatRedBall.Instructions.InstructionManager.IgnorePausingFor(" + nos.InstanceName + ");"); } } return codeBlock; }
public static ICodeBlock AppendAssignmentForCustomVariableInInstance(NamedObjectSave namedObject, ICodeBlock codeBlock, InstructionSave instructionSave) { // We don't support assigning lists yet, and lists are generic, so we're going to test for generic assignments // Eventually I may need to make this a little more accurate. if (instructionSave.Value != null && instructionSave.Value.GetType().IsGenericType == false) { bool usesStandardCodeGen = true; var ati = namedObject.GetAssetTypeInfo(); if(ati != null) { var foundVariableDefinition = ati.VariableDefinitions.FirstOrDefault(item => item.Name == instructionSave.Member); if(foundVariableDefinition != null && foundVariableDefinition.UsesCustomCodeGeneration) { usesStandardCodeGen = false; } } if (usesStandardCodeGen) { AppendCustomVariableInInstanceStandard(namedObject, codeBlock, instructionSave, ati); } else { PluginManager.WriteInstanceVariableAssignment(namedObject, codeBlock, instructionSave); } } return codeBlock; }