Example #1
0
        public async Task <GameObject> NewViewFromSchema(JsonSchema schema, JsonSchemaToView generator)
        {
            AssertV2.IsNotNull(schema, "schema");
            AssertV2.IsNotNull(generator, "generator");
            if (schema.properties == null)
            {
                AssertV2.IsFalse(generator.schemaGenerator.schemas.IsNullOrEmpty(), "generator.schema dict is emtpy!");
                if (generator.schemaGenerator.schemas.TryGetValue(schema.modelType, out JsonSchema vm))
                {
                    schema = vm;
                }
                else
                {
                    Log.e($"No Schema found for schema.modelType={schema.modelType}");
                }
            }
            AssertV2.IsNotNull(schema.properties, "schema.properties");
            GameObject rootContainerView = await generator.NewRootContainerView(rootPrefabName);

            rootContainerView.GetComponentInChildren <FieldView>().field = schema;
            var innerContainer = await generator.SelectInnerViewContainerFromObjectFieldView(rootContainerView);

            await generator.ObjectJsonSchemaToView(schema, innerContainer);

            return(rootContainerView);
        }
        private static void AddToSchemaDictionary(JsonSchemaToView self, ObjectFieldView objectFieldView)
        {
            if (objectFieldView == null)
            {
                Log.w("Passed fieldView was null, will skip AddToSchemaDictionary process");
                return;
            }
            RestorePropertiesFromChildrenGOs(objectFieldView);
            JsonSchema schema = objectFieldView.field;

            if (schema.modelType.IsNullOrEmpty())
            {
                Log.w("Missing schema.modelType in passsed ObjectFieldView.field", objectFieldView.gameObject);
                return;
            }
            if (!schema.properties.IsNullOrEmpty())
            {
                // After the fieldView properties are reconstructed correctly again fill the schemaGenerator fieldView map to have a central lookup location
                if (!self.schemaGenerator.schemas.ContainsKey(schema.modelType))
                {
                    self.schemaGenerator.schemas.Add(schema.modelType, schema);
                }
            }
            else
            {
                Log.d($"Will skip {schema.title} since it seems to be a partly unresolved type");
            }
        }
 /// <summary> fills the schema dictionary of the generator with the schemas found in the target view </summary>
 private static void SetupSchemaDictionary(this JsonSchemaToView self, GameObject targetView)
 {
     AddToSchemaDictionary(self, targetView.GetComponent <ObjectFieldView>());
     foreach (var fieldView in targetView.GetComponentsInChildren <ObjectFieldView>(includeInactive: true))
     {
         AddToSchemaDictionary(self, fieldView);
     }
 }
        private static async Task <FieldView> CreateChildEntryView(
            ListFieldView self, JObject root, JsonSchemaToView viewGenerator, JToken modelEntry, string fieldName)
        {
            JsonSchema newEntryVm = GetMatchingSchema(modelEntry, self.field.items);
            GameObject childView  = await AddChildEntryView(self, viewGenerator, fieldName, newEntryVm);

            await childView.LinkToJsonModel(root, viewGenerator);

            return(childView.GetComponentInChildren <FieldView>());
        }
 public static void ShowChildModelInNewScreen(this RecursiveFieldView self, JsonSchemaToView viewGenerator, GameObject currentScreen, JObject jObj)
 {
     self.openButton.SetOnClickAction(async delegate {
         var newScreen = await self.NewViewFromSchema(viewGenerator);
         var viewStack = currentScreen.GetViewStack();
         viewStack.ShowView(newScreen, currentScreen);
         var presenter        = new JsonSchemaPresenter(viewGenerator);
         presenter.targetView = newScreen;
         await presenter.LoadModelIntoView(jObj);
     }).LogOnError();
 }
        /// <summary> Can be used to generate a view directly from a model, if the json schema does not have to be customized, e.g.
        /// because the model uses Annotations this is the easiest way to generate a fully usable UI from any class </summary>
        /// true so that the used prefabs in the view are still linked correctly. </param>
        /// <param name="modelType"> The type of the model </param>
        /// <param name="keepReferenceToEditorPrefab"> If the view is generated during editor time this should be set to
        /// <returns> The generated view which can be used to load a model instance into it </returns>
        public static async Task <GameObject> GenerateViewFrom(this JsonSchemaToView self, Type modelType, bool keepReferenceToEditorPrefab = false)
        {
            var        timing = Log.MethodEnteredWith(modelType);
            JsonSchema schema = self.schemaGenerator.ToJsonSchema(modelType.Name, modelType);

            self.keepReferenceToEditorPrefab = keepReferenceToEditorPrefab;
            var view = await self.ToView(schema);

            view.name = schema.title;
            Log.MethodDone(timing);
            return(view);
        }
        private static async Task <GameObject> AddChildEntryView(
            ListFieldView self, JsonSchemaToView viewGenerator, string fieldName, JsonSchema entryVm)
        {
            var parentView = self.mainLink.gameObject;

            if (CanBeShownInListViewEntry(entryVm.GetJTokenType()))
            {
                GameObject childGo = await viewGenerator.AddChild(parentView, await viewGenerator.NewListViewEntry());

                await viewGenerator.InitChild(childGo, fieldName, entryVm);

                return(childGo);
            }
            else
            {
                return(await viewGenerator.AddViewForJsonSchemaField(parentView, entryVm, fieldName));
            }
        }
 private static void SetupButtons(ListFieldView listView, JObject root, JsonSchemaToView viewGenerator, JArray modelArray, Dictionary <FieldView, JToken> map)
 {
     listView.add.SetOnClickAction(async delegate {
         JToken entry = listView.field.items.First().NewDefaultJInstance();
         modelArray.Add(entry);
         var fieldName = "" + (modelArray.Count - 1);
         var fv        = await CreateChildEntryView(listView, root, viewGenerator, entry, fieldName);
         map.Add(fv, entry);
     });
     listView.up.SetOnClickAction(delegate {
         foreach (var v in GetSelectedViews(listView))
         {
             var selectedData = map[v];
             var index        = modelArray.IndexOf(selectedData);
             if (index > 0)
             {
                 modelArray.RemoveAt(index);
                 modelArray.Insert(index - 1, selectedData);
                 v.transform.SetSiblingIndex(v.transform.GetSiblingIndex() - 1);
             }
         }
     });
     listView.down.SetOnClickAction(delegate {
         foreach (var v in GetSelectedViews(listView).Reverse())
         {
             var selectedData = map[v];
             var index        = modelArray.IndexOf(selectedData);
             if (index < modelArray.Count - 1)
             {
                 modelArray.RemoveAt(index);
                 modelArray.Insert(index + 1, selectedData);
                 v.transform.SetSiblingIndex(v.transform.GetSiblingIndex() + 1);
             }
         }
     });
     listView.delete.SetOnClickAction(delegate {
         foreach (var v in GetSelectedViews(listView))
         {
             var selectedData = map[v];
             modelArray.Remove(selectedData);
             v.gameObject.Destroy();
         }
     });
 }
 /// <summary> Can be used to generate a view directly from a model, if the json schema does not have to be customized, e.g.
 /// because the model uses Annotations this is the easiest way to generate a fully usable UI from any class </summary>
 /// <typeparam name="T"> The type of the model </typeparam>
 /// <param name="keepReferenceToEditorPrefab"> If the view is generated during editor time this should be set to
 /// true so that the used prefabs in the view are still linked correctly. </param>
 /// <returns> The generated view which can be used to load a model instance into it </returns>
 public static async Task <GameObject> GenerateViewFrom <T>(this JsonSchemaToView self, bool keepReferenceToEditorPrefab = false)
 {
     return(await self.GenerateViewFrom(typeof(T), keepReferenceToEditorPrefab));
 }
Example #10
0
        public static async Task LinkToJsonModel(this GameObject targetView, JObject root, JsonSchemaToView viewGenerator)
        {
            viewGenerator.SetupSchemaDictionary(targetView);

            foreach (var fieldView in targetView.GetFieldViewMap().Values)
            {
                var value = fieldView.GetFieldJModel(root);
                if (!fieldView.LinkToJsonModel(root, value))
                {
                    if (fieldView is RecursiveFieldView r)
                    {
                        r.ShowChildModelInNewScreen(viewGenerator, targetView, value as JObject);
                    }
                    else if (fieldView is ObjectFieldView)
                    {
                        // Do nothing (object fields are individually set up themselves)
                    }
                    else if (fieldView is ListFieldView l)
                    {
                        await l.LoadModelList(root, viewGenerator);
                    }
                    else
                    {
                        Log.e($"Did not link {fieldView.GetType()}: {fieldView.fullPath}");
                    }
                }
            }
        }
Example #11
0
        public static async Task LoadModelList(this ListFieldView self, JObject root, JsonSchemaToView viewGenerator)
        {
            JArray modelArray = self.GetFieldJModel(root) as JArray;

            AssertV2.IsNotNull(modelArray, "modelArray");
            var map = new Dictionary <FieldView, JToken>();

            for (int i = 0; i < modelArray.Count; i++)
            {
                var    fieldName = "" + i;
                JToken entry     = modelArray[i];
                var    fv        = await CreateChildEntryView(self, root, viewGenerator, entry, fieldName);

                map.Add(fv, entry);
            }
            SetupButtons(self, root, viewGenerator, modelArray, map);
        }
        public static async Task LogAnyDiffToNewGeneratedUi(this Dictionary <string, FieldView> self, Type modelType, JsonSchemaToView generator, bool forceAlwaysDelete)
        {
            GameObject generatedUi = await generator.GenerateViewFrom(modelType, keepReferenceToEditorPrefab : true);

            generatedUi.name = "Delete me";
            if (!LogAnyDiffToNewFieldViews(self, generatedUi.GetFieldViewMap()) || forceAlwaysDelete)
            {
                generatedUi.Destroy(); // If there are no additions in the new UI it can be destroyed right away again after logging is done
            }
        }
 public static async Task LogAnyDiffToNewGeneratedUi <T>(this Dictionary <string, FieldView> self, JsonSchemaToView generator, bool forceAlwaysDelete)
 {
     await LogAnyDiffToNewGeneratedUi(self, typeof(T), generator, forceAlwaysDelete);
 }
Example #14
0
 public async Task <GameObject> NewViewFromSchema(JsonSchemaToView generator)
 {
     return(await NewViewFromSchema(field, generator));
 }
Example #15
0
 public JsonSchemaPresenter(JsonSchemaToView viewGenerator)
 {
     this.viewGenerator = viewGenerator;
 }