I have a unity project with an error in six different files all with the same error:
the type or namespace name 'IAotStubbable' could not be found.
I, for the life of me, cannot find the issue.
Here are the different files:
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace Unity.VisualScripting
{
[AddComponentMenu("Visual Scripting/Variables")]
[DisableAnnotation]
[IncludeInSettings(false)]
public class Variables : LudiqBehaviour, IAotStubbable
{
[Serialize, Inspectable]
public VariableDeclarations declarations { get; internal set; } =
new VariableDeclarations() { Kind = VariableKind.Object };
public static VariableDeclarations Graph(GraphPointer pointer)
{
Ensure.That(nameof(pointer)).IsNotNull(pointer);
if (pointer.hasData)
{
return GraphInstance(pointer);
}
else
{
return GraphDefinition(pointer);
}
}
public static VariableDeclarations GraphInstance(GraphPointer pointer)
{
return pointer.GetGraphData<IGraphDataWithVariables>().variables;
}
public static VariableDeclarations GraphDefinition(GraphPointer pointer)
{
return GraphDefinition((IGraphWithVariables)pointer.graph);
}
public static VariableDeclarations GraphDefinition(IGraphWithVariables graph)
{
return graph.variables;
}
public static VariableDeclarations Object(GameObject go) => go.GetOrAddComponent<Variables>().declarations;
public static VariableDeclarations Object(Component component) => Object(component.gameObject);
public static VariableDeclarations Scene(Scene? scene) => SceneVariables.For(scene);
public static VariableDeclarations Scene(GameObject go) => Scene(go.scene);
public static VariableDeclarations Scene(Component component) => Scene(component.gameObject);
public static VariableDeclarations ActiveScene => Scene(SceneManager.GetActiveScene());
public static VariableDeclarations Application => ApplicationVariables.current;
public static VariableDeclarations Saved => SavedVariables.current;
public static bool ExistOnObject(GameObject go) => go.GetComponent<Variables>() != null;
public static bool ExistOnObject(Component component) => ExistOnObject(component.gameObject);
public static bool ExistInScene(Scene? scene) => scene != null && SceneVariables.InstantiatedIn(scene.Value);
public static bool ExistInActiveScene => ExistInScene(SceneManager.GetActiveScene());
[ContextMenu("Show Data...")]
protected override void ShowData()
{
base.ShowData();
}
public IEnumerable<object> GetAotStubs(HashSet<object> visited)
{
// Include the constructors for AOT serialization
// https://support.ludiq.io/communities/5/topics/3952-x
foreach (var declaration in declarations)
{
var defaultConstructor = declaration.value?.GetType().GetPublicDefaultConstructor();
if (defaultConstructor != null)
{
yield return defaultConstructor;
}
}
}
}
}
using System;
namespace Unity.VisualScripting
{
public interface IGraphNest : IAotStubbable
{
IGraphNester nester { get; set; }
GraphSource source { get; set; }
IGraph embed { get; set; }
IMacro macro { get; set; }
IGraph graph { get; }
Type graphType { get; }
Type macroType { get; }
bool hasBackgroundEmbed { get; }
}
}
namespace Unity.VisualScripting
{
public interface IMacro : IGraphRoot, ISerializationDependency, IAotStubbable
{
IGraph graph { get; set; }
}
}
using System;
using System.Collections.Generic;
namespace Unity.VisualScripting
{
public interface IGraphElement : IGraphItem, INotifiedCollectionItem, IDisposable, IPrewarmable, IAotStubbable, IIdentifiable, IAnalyticsIdentifiable
{
new IGraph graph { get; set; }
bool HandleDependencies();
int dependencyOrder { get; }
new Guid guid { get; set; }
void Instantiate(GraphReference instance);
void Uninstantiate(GraphReference instance);
IEnumerable<ISerializationDependency> deserializationDependencies { get; }
}
}
using System;
using UnityEngine;
namespace Unity.VisualScripting
{
public interface IGraph : IDisposable, IPrewarmable, IAotStubbable, ISerializationDepender
{
Vector2 pan { get; set; }
float zoom { get; set; }
MergedGraphElementCollection elements { get; }
string title { get; }
string summary { get; }
IGraphData CreateData();
IGraphDebugData CreateDebugData();
void Instantiate(GraphReference instance);
void Uninstantiate(GraphReference instance);
}
}
using UnityEngine;
namespace Unity.VisualScripting
{
public interface IMachine : IGraphRoot, IGraphNester, IAotStubbable
{
IGraphData graphData { get; set; }
GameObject threadSafeGameObject { get; }
}
}
What can I do to fix this? I've surfed forums for help for a while but havent found anything yet. This is for a massive school project and I would really love to have it finished. Thank you for any and all responses.
Related
During a runtime mapping operation (like when you use ResolveUsing or a custom TypeConverter) is it possible to get the container classes (or types at least) of the source and destination members?
I know that when you map one object to another, that the objects don't have to be members of some "parent" or "container" object, but I'm talking about the situation when AutoMapper is recursively copying a complex object.
Here's an example:
Here I'm copying (or setting it up at least) Cars & Boats of "kind A" to "kind B".
public class VehicleCopyProfile : AutoMapper.Profile
{
public VehicleCopyProfile()
{
this.CreateMap<CarA, CarB>();
this.CreateMap<BoatA, BoatB>();
this.CreateMap<WindshieldA, WindshieldB>(
.ConvertUsing((s, d, resContext) =>
{
// *** How can I tell if s is coming from a Car or a Boat? ***
});
}
}
// Cars & Boats each have a Windshield
public class CarA
{
public WindshieldA Windshield {get;set;}
}
public class BoatA
{
public WindshieldA Windshield {get;set;}
}
public class WindshieldA
{
public string Name {get;set;}
}
public class CarB
{
public WindshieldB Windshield {get;set;}
}
public class BoatB
{
public WindshieldB Windshield {get;set;}
}
public class WindshieldB
{
public string Name {get;set;}
}
Here is a solution using AutoMapper ResolutionContext Items as proposed by #Lucian Bargaoanu in comment. The idea is to use Before and After Map to store information in the Resolution Context. I use a Stack to keep track of the whole chain of relationship.
namespace SO51101306
{
public static class IMappingExpressionExtensions
{
public static IMappingExpression<A, B> RegisterChainOfTypes<A, B>(this IMappingExpression<A, B> mapping)
{
mapping.BeforeMap((a, b, ctx) => {
ctx.PushTypeInChainOfTypes(typeof(A));
});
mapping.AfterMap((a, b, ctx) => {
ctx.PopLastTypeInChainOfTypes();
});
return mapping;
}
}
public static class ResolutionContextExtensions
{
const string chainOfTypesKey = "ChainOfTypes";
private static Stack<Type> GetOrCreateChainOfTypesStack(ResolutionContext ctx)
{
var hasKey = ctx.Items.ContainsKey(chainOfTypesKey);
return hasKey ? (Stack<Type>)ctx.Items[chainOfTypesKey] : new Stack<Type>();
}
public static void PushTypeInChainOfTypes(this ResolutionContext ctx, Type type)
{
var stack = GetOrCreateChainOfTypesStack(ctx);
stack.Push(type);
ctx.Items[chainOfTypesKey] = stack;
}
public static Type PopLastTypeInChainOfTypes(this ResolutionContext ctx)
{
var stack = (Stack<Type>)ctx.Items[chainOfTypesKey];
return stack.Pop();
}
public static bool HasParentType(this ResolutionContext ctx, Type parentType)
{
var stack = GetOrCreateChainOfTypesStack(ctx);
return stack.Contains(parentType);
}
}
public class CarCopyProfile : Profile
{
public CarCopyProfile()
{
CreateMap<CarA, CarB>().RegisterChainOfTypes();
CreateMap<BoatA, BoatB>().RegisterChainOfTypes();
CreateMap<WindshieldA, WindshieldB>()
.ConvertUsing((wa,wb,ctx)=> {
if(ctx.HasParentType(typeof(CarA)))
{
Console.WriteLine("I'm coming from CarA");
//Do specific stuff here
}
else if (ctx.HasParentType(typeof(BoatA)))
{
Console.WriteLine("I'm coming from boatA");
//Do specific stuff here
}
return wb;
});
}
}
public class CarA
{
public WindshieldA Windshield { get; set; }
}
public class BoatA
{
public WindshieldA Windshield { get; set; }
}
public class CarB
{
public WindshieldB Windshield { get; set; }
}
public class BoatB
{
public WindshieldB Windshield { get; set; }
}
public class WindshieldA
{
public string Name { get; set; }
}
public class WindshieldB
{
public string Name { get; set; }
}
class Program
{
static void Main(string[] args)
{
Mapper.Initialize(c => c.AddProfile<CarCopyProfile>());
var carA = new CarA{Windshield = new WindshieldA()};
var boatA = new BoatA{Windshield = new WindshieldA()};
var carB = Mapper.Map<CarB>(carA);
var boatB = Mapper.Map<BoatB>(boatA);
}
}
}
This will output:
I'm coming from CarA
I'm coming from boatA
Another way is to use custom value resolver:
class CustomResolver<T1, T2>:IValueResolver ... { ... }
this.CreateMap<CarA, CarB>()
.ForMember(x => x.Windshield , opt => opt.ResolveUsing(new CustomResolver<CarA, CarB>()));
Then in you CustomResolver implementation:
var windshieldB = Mapper.Map<WindshieldB>(windshieldA, x => {x.Items["type1"] = typeof(T1); x.Items["type2"] = typeof(T2);});
And then:
this.CreateMap<WindshieldA, WindshieldB>(
.ConvertUsing((s, d, resContext) =>
{
// resContext.Options.Items["type1"]
});
See http://docs.automapper.org/en/stable/Custom-value-resolvers.html
I do not know if I understood something wrong. But Visual Studio says that adding an item does not allow the conversion from ExporterTaskWorker<ExporterTypeMusic> to ExporterTaskWorker<IExporterType>. But ExporterTypeMusic implements the IExporterType interface.
What am I doing wrong?
public interface IExporterType
{
bool BrandChannelAssigning();
}
public class ExporterTypeMusic : IExporterType
{
public bool BrandChannelAssigning()
{
throw new System.NotImplementedException();
}
}
public class ExporterTaskWorker<T> : INotifyPropertyChanged where T : IExporterType
{
public Config TheConfig { get; set; }
public object SomeProperty { get; set; }
...
...
public ExporterTaskWorker(Config _config) {
}
}
public class SomeClass
{
public ObservableCollection<ExporterTaskWorker<IExporterType>> ExporterInstanceCollection { get; set; } = new ObservableCollection<ExporterTaskWorker<IExporterType>>();
public void SomeMethod()
{
Config theConfig = new Config();
ExporterTaskWorker<ExporterTypeMusic> exporterTaskWorker = new ExporterTaskWorker<ExporterTypeMusic>(theConfig);
ExporterInstanceCollection.Add(exporterTaskWorker);
}
}
Getting the CS1501 error "No overload for method 'Load' takes '1' arguments" and it is driving me insane because I have looked for a solution all over internet but cannot find any. So I ask here now, and hopefully recieve a solution that works.
PPSerialization:
using UnityEngine;
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
public class PPSerialization {
public static BinaryFormatter binaryFormatter = new BinaryFormatter();
public static void Save(string saveTag, object obj) {
MemoryStream memoryStream = new MemoryStream();
binaryFormatter.Serialize(memoryStream, obj);
string temp = System.Convert.ToBase64String(memoryStream.ToArray());
PlayerPrefs.SetString(saveTag, temp);
}
public static object Load(string saveTag, object obj) {
string temp = PlayerPrefs.GetString(saveTag);
if (temp == string.Empty) {
return null;
}
MemoryStream memoryStream = new MemoryStream(System.Convert.FromBase64String(temp));
return binaryFormatter.Deserialize(memoryStream);
}
}
GameInformation:
using UnityEngine;
using System.Collections;
public class GameInformation : MonoBehaviour {
void Awake() {
DontDestroyOnLoad(transform.gameObject);
}
public static BaseEquipment EquipmentOne { get; set; }
public static string PlayerName { get; set; }
public static BaseCharacterClass PlayerClass { get; set; }
public static int PlayerLevel { get; set; }
public static int Health { get; set; }
public static int Stamina { get; set; }
public static int Strength { get; set; }
public static int Intelligence { get; set; }
}
Save_Info:
using UnityEngine;
using System.Collections;
public class Save_Info
{
public static void SaveAllInfo() {
PlayerPrefs.SetString("PLAYERNAME", GameInformation.PlayerName);
PlayerPrefs.SetInt("PLAYERLEVEL", GameInformation.PlayerLevel);
PlayerPrefs.SetInt("HEALTH", GameInformation.Health);
PlayerPrefs.SetInt("STAMINA", GameInformation.Stamina);
PlayerPrefs.SetInt("STRENGTH", GameInformation.Strength);
PlayerPrefs.SetInt("INTELLIGENCE", GameInformation.Intelligence);
if (GameInformation.EquipmentOne != null)
{
PPSerialization.Save("EQUIPMENTITEM1", GameInformation.EquipmentOne);
}
Debug.Log("SAVED");
}
}
Load_Info:
using UnityEngine;
using System.Collections;
public class Load_Info
{
public static void LoadAllInfo()
{
GameInformation.PlayerName = PlayerPrefs.GetString("PLAYERNAME");
GameInformation.PlayerLevel = PlayerPrefs.GetInt("PLAYERLEVEL");
GameInformation.Health = PlayerPrefs.GetInt("HEALTH");
GameInformation.Stamina = PlayerPrefs.GetInt("STAMINA");
GameInformation.Strength = PlayerPrefs.GetInt("STRENGTH");
GameInformation.Intelligence = PlayerPrefs.GetInt("INTELLIGENCE");
if (PlayerPrefs.GetString("EQUIPMENTITEM1") != null)
{
GameInformation.EquipmentOne = (BaseEquipment)PPSerialization.Load("EQUIPMENTITEM1");
}
}
}
You have method Load with 2 parameters
public static object Load(string saveTag, object obj) {
string temp = PlayerPrefs.GetString(saveTag);
if (temp == string.Empty) {
return null;
}
But you try to call it only with 1 paramert
GameInformation.EquipmentOne = (BaseEquipment)PPSerialization.Load("EQUIPMENTITEM1");
Change your Load method like this :
public static object Load(string saveTag) {
string temp = PlayerPrefs.GetString(saveTag);
if (temp == string.Empty) {
return null;
}
MemoryStream memoryStream = new MemoryStream(System.Convert.FromBase64String(temp));
return binaryFormatter.Deserialize(memoryStream);
}
Entity and Component has one-to-many relationship. Entity stored in db correctly, with all components. But when I trying load it back this Entity in Child method Components not loads. If i try use lazy loading, code failing on entity.GetComponent because of Entity.Components isn't initialized. After exception Components are initialized and has zero elements. If I disable lazy loading, Components are initialized and has zero elements. I wrote example for building one-to-many relationship and using lazy initialization, and it works fine.
public static void Main(string[] args)
{
Parent();
Child();
}
private static void Child()
{
using (var db = new EntitiesContext())
{
var entities = from entity in db.Entities
select entity;
foreach (Entity entity in entities)
{
Position pos = entity.GetComponent<Position>();
Core core = entity.GetComponent<Core>();
}
}
}
private static void Parent()
{
Entity entity = new Entity();
entity.AddComponent(new Position(10, 10));
entity.AddComponent(new ObjectName("Entity" + 1));
entity.AddComponent(new Core(100));
using (var db = new EntitiesContext())
{
db.Entities.Add(entity);
db.SaveChanges();
}
}
public class EntitiesContext : DbContext
{
public DbSet<TypeMaskPair> MappedTypes { get; set; }
public DbSet<Entity> Entities { get; set; }
public EntitiesContext()
: base("EntitiesDb")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Entity>()
.HasMany(entity => entity.Components)
.WithRequired(component => component.EntityObj)
.HasForeignKey(component => component.EntityId)
.WillCascadeOnDelete();
//this.Configuration.LazyLoadingEnabled = false;
}
}
public abstract class Component
{
[Key]
public int Id { get; set; }
[Required]
public int EntityId { get; set; }
[Required]
public virtual Entity EntityObj { get; set; }
private static DbMasksMapper componentsMap;
static Component()
{
componentsMap = new DbMasksMapper(typeof(Component));
}
public TypeMask GetMask()
{
return componentsMap.GetMask(this.GetType());
}
public static TypeMask GetMask<T>() where T : Component
{
return componentsMap.GetMask(typeof(T));
}
}
public class Entity
{
[Key]
public int Id { get; set; }
public virtual List<Component> Components { get; set; }
[NotMapped]
public TypeMask Mask { get; private set; }
public string TypeMaskString
{
get{ return Mask.ToString(); }
set{ Mask = new TypeMask(value); }
}
public Entity()
{
Components = new List<Component>();
Mask = new TypeMask();
}
public void AddComponent(Component component)
{
Components.Add(component);
component.EntityObj = this;
Mask |= component.GetMask();
}
public void DeleteComponent(TypeMask componentMask)
{
if (ContainsComponent(componentMask))
{
int removeIndex = Components.FindIndex(c => c.GetMask() == componentMask);
Components.RemoveAt(removeIndex);
Mask &= ~componentMask;
}
}
public Component GetComponent(TypeMask componentMask)
{
return Components.Find(c => c.GetMask() == componentMask);
}
public T GetComponent<T>() where T : Component
{
return (T) GetComponent(Component.GetMask<T>());
}
public bool ContainsComponent<T>() where T : Component
{
return ContainsComponent(Component.GetMask<T>());
}
public bool ContainsComponent(TypeMask componentMask)
{
return (Mask & componentMask) == componentMask;
}
}
class Position : Component
{
public Position(int x = 0, int y = 0)
{
X = x;
Y = y;
}
public int X { get; set; }
public int Y { get; set; }
}
class Cargo : Component
{
public Cargo(int capacity = 0)
{
Capacity = capacity;
}
public int Capacity { get; set; }
}
class Core : Component
{
public Core(int power = 0)
{
Power = power;
}
public int Power { get; set; }
}
class ObjectName : Component
{
public ObjectName(string name = "")
{
Name = name;
}
public string Name { get; set; }
}
I saw similar questions, but didn't found any answer.
Where is a mistake?
Solution
All works after I wrote default constructor for inherited components. But, I don't understand why constructor with default arguments doesn't suitable. Without any argument it should work like default constructor. Can anyone explain it? Seems I doing it wrong
Imagine a class as follows.. It's a class provided to me to work with.. I cannot change its source..
public class MyClass
{
object _Object { get; set; }
public void FuncA1() { _Object = new object(); }
public void FuncA2() { _Object = new List<object>(); }
public int FuncB1() { _Object = 0; return 0; }
public int FuncB2() { _Object = 123; return 123; }
public string FuncC1() { _Object = null; return null; }
public string FuncC2() { _Object = "Hello"; return "Hello"; }
}
Im trying to create a wrapper for this class, such that I can group its many functions into categories..
MyWrapper.Voids.FuncA1();
MyWrapper.Voids.FuncA2();
MyWrapper.Integers.FuncB1();
MyWrapper.Integers.FuncB2();
MyWrapper.Strings.FuncC1();
MyWrapper.Strings.FuncC2();
The only solution I can think of for this scenario is to design the wrapper like this:
public class MyWrapper
{
MyClass _Instance { get; set; }
public _Void Voids { get; private set; }
public _Integer Integers { get; private set; }
public _String Strings { get; private set; }
public class _Void
{
MyWrapper _Parent { get; set; }
public void FuncA1() { _Parent._Instance.FuncA1(); }
public int FuncA2() { return _Parent._Instance.FuncA2(); }
}
public class _Integer
{
...
}
public class _String
{
...
}
public MyWrapper()
{
_Instance = new MyClass();
Voids = new _Voids(this);
Integers = new _Integer(this);
Strings = new _String(this);
}
}
This solution works, but has a number of problems:
- The inner classes are forced to be public, which allows them to be instantiated by the user..
- I am forced to maintain a reference of the parent object in the child classes..
Is there a better way of doing this?
EDIT: The code posted initially was a bit confusing, in the sense that it was diverting attention away from the core issue and more into the issues of whether a function would cause exceptions or not if they all work on the same object..
NOTE: This is not actual code.. I hacked together this example to show what I'm trying to do.. CREATE A WRAPPER AROUND AN OBJECT (I cannot change the original object's code) AND GROUP FUNCTIONS INTO CATEGORIES..
FINAL EDIT: following suggestion by Juharr.. here's what ive done to accomplish what i wanted.. for the betterment of others..
public interface IVoid
{
void FuncA1();
void FuncA2();
}
public interface IInteger
{
int FuncB1();
int FuncB2();
}
public class MyWrapper
{
public MyClass Instance { get; private set; }
public IVoid Voids { get; private set; }
public IInteger Integers { get; private set; }
private abstract class MyBase
{
protected MyWrapper Parent { get; set; }
protected MyClass Instance { get { return Parent.Instance; } }
public MyBase(MyWrapper oParent) { Parent = oParent; }
}
private class MyVoid : MyBase, IVoid
{
public MyVoids (MyWrapper oParent) : base(oParent) { }
public void FuncA1() { Instance.FuncA1(); }
public void FuncA2() { Instance.FuncA2(); }
}
private class MyInteger : MyBase, IInteger
{
public MyInteger (MyWrapper oParent) : base(oParent) { }
public int FuncB1() { return Instance.FuncB1(); }
public int FuncB2() { return Instance.FuncB2(); }
}
public MyWrapper()
{
Instance = new MyClass();
Voids = new MyVoid(this);
Integers = new MyInteger(this);
}
}
You could write public interfaces instead. Then your inner classes don't have to be public. So something like this.
public interface IIntger
{
void Set(int iValue);
int Get();
}
public class MyWrapper
{
MyClass _Instance { get; set; }
public IInteger Integer { get; private set; }
private class _Integer : IInteger
{
MyWrapper _Parent { get; set; }
public void Set(int iValue) { _Parent._Instance.IntegerSet(iValue); }
public int Get() { return _Parent._Instance.IntegerGet(); }
}
public MyWrapper()
{
_Instance = new MyClass();
Integer = new _Integer(this);
}
}
EDIT:
To answer the second part of your question you will either need the reference to the parent class or a reference to the class you are wrapping. So you could have this instead.
public class MyWrapper
{
public IInteger Integer { get; private set; }
private class _Integer : IInteger
{
MyClass _Instance { get; set; }
public _Integer(MyClass myClass) { _Instance = myClass; }
public void Set(int iValue) { _Instance.IntegerSet(iValue); }
public int Get() { return _Instance.IntegerGet(); }
}
public MyWrapper(MyClass instance)
{
Integer = new _Integer(instance);
}
}