internal IDef LoadResource(string relativePath, Type type, bool asProto) { IDef resource; if (!asProto) { if (LoadedDefs.GetExisting(DefIDFull.Parse(relativePath), type, out resource)) { return(resource); } } resource = LoadFromDisk(relativePath); return(!type.IsInstanceOfType(resource) ? null : resource); }
internal void Unregister(DefIDFull id) { lock (this) { HotLoadWasUsed = true; IDef res; if (!_pathsToObjects.TryGetValue(id, out res)) { return; } _pathsToObjects.Remove(id); _objectsToPaths.Remove(res); return; } }
internal void RegisterObject(DefIDFull id, BaseDef resource) { lock (this) { if (_pathsToObjects.ContainsKey(id)) { Logger.Error().Message("Double registration for id {0}", id).Write(); return; } if (_objectsToPaths.ContainsKey(resource)) { Logger.Error().Message("Double registration for id {0}", id).Write(); return; } _pathsToObjects[id] = resource; _objectsToPaths[resource] = id; } }
private IDef LoadResource(DefIDFull id, Type type) { lock (_loadLock) { IDef resource; if (LoadedDefs.GetExisting(id, type, out resource)) { return(resource); } var relativePath = id.Root; if (!relativePath.StartsWith("/")) { throw new ArgumentException($"Path does not start with forward slash / {relativePath}", nameof(relativePath)); } try { //ProfileSampleBegin("LoadRes", id.Root); LoadFromDisk(relativePath); //ProfileSampleEnd(); } catch (Exception e) { Context = new LoadingContext(); Logger.LogError?.Invoke(e.ToString()); throw; } finally { } if (LoadedDefs.GetExisting(id, type, out resource)) { return(resource); } Logger.LogError?.Invoke($"Resource {id} not found"); return(null); } }
public bool GetExisting(DefIDFull id, Type type, out IDef res) { lock (this) { if (!_pathsToObjects.TryGetValue(id, out res)) { return(false); } if (res == null) { return(true); } if (!type.IsInstanceOfType(res)) { res = null; } return(true); } }
public T LoadResource <T>(DefIDFull id) where T : IDef { return(Deserializer.LoadResource <T>(id)); }
internal T LoadResource <T>(DefIDFull id) where T : IDef { return((T)LoadResource(id, typeof(T))); }
internal T LoadResource <T>(string relativePath) where T : IDef { return((T)LoadResource(DefIDFull.Parse(relativePath), typeof(T))); }
public void PushProto(bool isProtoLoading, DefIDFull id = default(DefIDFull)) { ProtoStack.Push(new ProtoFrame(isProtoLoading, id)); }
public ProtoFrame(bool isProtoLoading, DefIDFull id) { Id = id; IsProtoLoading = isProtoLoading; }
//$type //$id //$vars //$overrideVars //$proto public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { ClearComments(reader); var context = (LoadingContext)serializer.Context.Context; var Context = context; var lineInfo = ((JsonTextReader)reader); if (reader.TokenType != JsonToken.StartObject) { throw new Exception($"Expecting StarObject token at {Context.RootAddress}:{lineInfo.LineNumber}:{lineInfo.LinePosition}, possibly ResourceRef<> wrap is forgotten"); } bool hasId = false; bool hasProto = false; bool hasOverrideVars = false; bool hasVars = false; var startPath = (string)reader.Path; int startDepth = reader.Depth; ClearComments(reader); //skip "$type" propertyname reader.Read(); ClearComments(reader); if ((string)reader.Value != "$type") { throw new Exception($"$type is not first at {lineInfo.LineNumber} {lineInfo.LinePosition} {Context.RootAddress} - val is {reader.Value} {reader.TokenType}"); } reader.Read(); var specificTypeName = (string)reader.Value; reader.Read(); ClearComments(reader); Type specificType = null; try { specificType = serializer.SerializationBinder.BindToType("", specificTypeName); } catch (Exception e) { throw new JsonException($"Error reading type {specificTypeName} at {lineInfo.LineNumber} {lineInfo.LinePosition} {Context.RootAddress}", e); } string id = null; if (reader.TokenType == JsonToken.PropertyName && (string)reader.Value == "$id") { reader.Read(); id = (string)reader.Value; reader.Read(); if (id != null) { hasId = true; } } ClearComments(reader); IDef defInstance = null; bool isProto = false; if (reader.TokenType == JsonToken.PropertyName) { if ((string)reader.Value == "$vars") { bool can = false; if (Context.ProtoStack.Count > 0) { can = Context.ProtoStack.Peek().CanRegisterDefInstance; Context.ProtoStack.Peek().CanRegisterDefInstance = false; } hasVars = true; ClearComments(reader); //skip propName reader.Read(); //skip startobject reader.Read(); while (reader.TokenType != JsonToken.EndObject) { ClearComments(reader); var varName = (string)reader.Value; //skip to content reader.Read(); context.PushSubObject(); var temVarObj = serializer.Deserialize(reader, typeof(TemplateVariable)); //here I'm at the last token of prev object reader.Read(); Context.PopSubObject(); var temVar = (TemplateVariable)temVarObj; temVar.VariableId = new DefIDFull(Context.RootAddress, lineInfo.LineNumber, lineInfo.LinePosition); if (temVar == null) { throw new JsonException($"Error reading template var {varName} at {lineInfo.LineNumber} {lineInfo.LinePosition} {Context.RootAddress}"); } Context.SetVar(varName, temVar); } //skip $vars endObj reader.Read(); if (Context.ProtoStack.Count > 0) { Context.ProtoStack.Peek().CanRegisterDefInstance = can; } } ClearComments(reader); if ((string)reader.Value == "$overrideVars" || (string)reader.Value == "$proto") { bool can = false; if (Context.ProtoStack.Count > 0) { can = Context.ProtoStack.Peek().CanRegisterDefInstance; Context.ProtoStack.Peek().CanRegisterDefInstance = false; } isProto = true; //here I read "$proto" and "$overrideVars" //load from current context (say if a var points to previously set var) Dictionary <string, KeyValuePair <TemplateVariable, IJsonLineInfo> > vars = new Dictionary <string, KeyValuePair <TemplateVariable, IJsonLineInfo> >(); if ((string)reader.Value == "$overrideVars") { hasOverrideVars = true; reader.Read(); //skip propName var startOverrideDepthRead = reader.Depth; reader.Read(); //skip start object while (reader.TokenType != JsonToken.EndObject) { ClearComments(reader); var varLineInfo = (JsonTextReader)reader; object value = null; Type varTypeIfHasOne = null; Context.PushSubObject(); if (reader.TokenType != JsonToken.PropertyName) { throw new Exception("Override var does not start with a property name"); } var varNameValue = (string)reader.Value; reader.Read(); // value token (start obj, string or whatever) if (reader.TokenType == JsonToken.String) { var refValue = ((string)reader.Value); if (refValue.StartsWith("@")) { value = Context.GetVar(refValue.Substring(1), out varTypeIfHasOne); } else if (refValue.StartsWith("/") || refValue.StartsWith("./") || refValue.StartsWith("$")) { value = serializer.Deserialize(reader, typeof(DefRef <BaseDef>)); } else { value = serializer.Deserialize(reader); } } else { value = serializer.Deserialize(reader); } //here I'm at the last token of override var reader.Read(); Context.PopSubObject(); vars.Add(varNameValue, new KeyValuePair <TemplateVariable, IJsonLineInfo>(new TemplateVariable() { Type = varTypeIfHasOne, Value = value }, new LineInfo() { Row = varLineInfo.LineNumber, Col = varLineInfo.LinePosition })); ClearComments(reader); } var endOverrideDepthRead = reader.Depth; if (startOverrideDepthRead != endOverrideDepthRead) { throw new Exception($"Depth in override is wrong {startDepth} {endOverrideDepthRead}"); } //Skipping end object reader.Read(); Context.PushProto(true, new DefIDFull(Context.RootAddress)); foreach (var variable in vars) { var value = variable.Value.Key; var setVar = value.Value; var type = value.Value?.GetType(); if (type == null) { type = value.Type; } if (type != null) { if (typeof(IDef).IsAssignableFrom(type)) { setVar = DefReferenceConverter.CreateRef(type, (IDef)value.Value); if (setVar != null) { type = setVar.GetType(); } } } Context.SetVar(variable.Key, new TemplateVariable() { Value = setVar, Type = type, VariableId = new DefIDFull(Context.RootAddress, variable.Value.Value.LineNumber, variable.Value.Value.LinePosition) }); } } else { Context.PushProto(true, new DefIDFull(Context.RootAddress));//Here I could've missed something } while (reader.TokenType == JsonToken.Comment) { reader.Read(); } while (reader.TokenType != JsonToken.PropertyName) { reader.Read(); } //Skipping $proto if ((string)reader.Value != "$proto") { throw new Exception($"No $proto at {lineInfo.LineNumber} {lineInfo.LinePosition} {Context.RootAddress} - is {reader.Value} {reader.TokenType}"); } hasProto = true; reader.Read(); Context.PushSubObject(); bool setProtoStart = false; if (setProtoStart = !Context.LoadingFrames.Peek().ProtoStart.HasValue) { Context.LoadingFrames.Peek().ProtoStart = new DefIDFull(Context.RootAddress, lineInfo.LineNumber, lineInfo.LinePosition); } var serObj = serializer.Deserialize(reader, (typeof(DefRef <>).MakeGenericType(specificType))); if (reader.TokenType == JsonToken.String || reader.TokenType == JsonToken.EndObject) { reader.Read(); } if (reader.TokenType == JsonToken.PropertyName && (string)reader.Value == "$overrideVars") { throw new Exception($"$proto and $overrideVars are in a wrong order. Should be $overrideVars and then $proto at {lineInfo.LineNumber} {lineInfo.LinePosition} {Context.RootAddress}"); } var rRef = (IRefBase)serObj; defInstance = rRef.DefBase; if (setProtoStart) { Context.LoadingFrames.Peek().ProtoStart = null; } Context.PopSubObject(); Context.PopProto(); if (defInstance.GetType() != specificType) { throw new JsonException($"Prototype and child resources mismatch {defInstance.GetType().Name} {specificTypeName} at {lineInfo.LineNumber} {lineInfo.LinePosition} {Context.RootAddress}"); } if (Context.ProtoStack.Count > 0) { Context.ProtoStack.Peek().CanRegisterDefInstance = can; } } } if (!isProto) { defInstance = (IDef)Activator.CreateInstance(specificType); if (Context.IsProto && Context.ProtoStack.Peek().ProtoObject == null && Context.ProtoStack.Peek().CanRegisterDefInstance) { Context.ProtoStack.Peek().ProtoObject = defInstance; } } if (id != null) { Context.SetInternalRes(id, defInstance); } var addr = Context.IsRootObject ? new DefIDFull(Context.RootAddress) : new DefIDFull(Context.RootAddress, lineInfo.LineNumber, lineInfo.LinePosition); if (!Context.IsProto) { ((IDef)defInstance).Address = addr; loadedResources.RegisterObject(addr, (BaseDef)defInstance); } else if (Context.ProtoStack.Peek().ProtoObject != defInstance) { var addrId = new DefIDFull(Context.ProtoRootAdress, lineInfo.LineNumber, lineInfo.LinePosition, Context.ProtoIndex = Context.ProtoIndex + 1); ((IDef)defInstance).Address = addrId; loadedResources.RegisterObject(addrId, (BaseDef)defInstance); } Context.PushSubObject(); var props = ((JsonObjectContract)serializer.ContractResolver.ResolveContract(defInstance.GetType())).Properties; //here I'm at a property, which is the first actual property of an object ClearComments(reader); while (reader.TokenType != JsonToken.EndObject) { ClearComments(reader); if (((string)reader.Value) == null) { Logger.Error($"Not Correct Field ({reader.Value.ToString()}) in Jdb file ({reader.Path}). Please fix it!"); } if (props.Contains((string)reader.Value)) { var prop = props[(string)reader.Value]; reader.Read(); //here we are reading value //bool isObj = reader.TokenType == JsonToken.StartObject; var obj = serializer.Deserialize(reader, prop.PropertyType); prop.ValueProvider.SetValue(defInstance, obj); //here we should be at the last token of previous deserializer reader.Read(); ClearComments(reader); } else { if ((string)reader.Value == "$id") { throw new Exception($"Id is in wrong place {startPath} {Context.RootAddress}"); } reader.Skip(); reader.Read(); } } int endDepth = reader.Depth; if (startDepth != endDepth) { throw new Exception($"Depth is different {specificTypeName} {startPath} {startDepth} {endDepth} hasId {hasId} hasProto {hasProto} hasOverride {hasOverrideVars} hasVars {hasVars}"); } Context.PopSubObject(); return(defInstance); }