Selaa lähdekoodia

Array jsonification (1D only) now fully automated!

Mark Sibly 7 vuotta sitten
vanhempi
commit
1cc514ec36

+ 49 - 61
modules/mojo3d/scene/jsonifier/jsonifier.monkey2

@@ -2,36 +2,38 @@ Namespace mojo3d.jsonifier
 
 Class Jsonifier
 
-	Method AddInstance( obj:Object,ctor:Invocation )
+	Method AddInstance( obj:Variant,ctor:Invocation )
 		
-		Assert( Not _instsByObj.Contains( obj ) )
+		Local tobj:=Cast<Object>( obj )
+		
+		Assert( Not _instsByObj.Contains( tobj ) )
 		
 		Local inst:=New Instance
 		inst.obj=obj
 		inst.id="@"+String(_insts.Length)
 		inst.ctor=ctor
-		inst.initialState=JsonifyState( obj )
+		inst.initialState=JsonifyState( tobj )
 		
-		_instsByObj[inst.obj]=inst
+		_instsByObj[tobj]=inst
 		_instsById[inst.id]=inst
 
 		_insts.Add( inst )
 	End
 
 	'ctor via ctor
-	Method AddInstance( obj:Object,args:Variant[] )
+	Method AddInstance( obj:Variant,args:Variant[] )
 		
 		AddInstance( obj,New Invocation( obj.DynamicType,"New",Null,args ) )
 	end
 
 	'ctor via method call
-	Method AddInstance( obj:Object,decl:String,inst:Variant,args:Variant[] )
+	Method AddInstance( obj:Variant,decl:String,inst:Variant,args:Variant[] )
 		
 		AddInstance( obj,New Invocation( decl,inst,args ) )
 	End
 
 	'ctor via function call
-	Method AddInstance( obj:Object,decl:String,args:Variant[] )
+	Method AddInstance( obj:Variant,decl:String,args:Variant[] )
 		
 		AddInstance( obj,New Invocation( decl,Null,args ) )
 	End
@@ -46,15 +48,18 @@ Class Jsonifier
 		
 		For Local i:=0 Until _insts.Length
 			
-			Local inst:=_insts[i]
 			Local jobj:=New JsonObject
 			
+			Local inst:=_insts[i]
+			Local tobj:=Cast<Object>( inst.obj )
+			
 			jobj["id"]=New JsonString( inst.id )
-			jobj["type"]=New JsonString( inst.obj.DynamicType.Name )
+			
+			jobj["type"]=New JsonString( tobj.DynamicType.Name )
 			
 			jobj["ctor"]=Jsonify( inst.ctor )
 			
-			Local state:=JsonifyState( inst.obj ),dstate:=New JsonObject
+			Local state:=JsonifyState( tobj ),dstate:=New JsonObject
 			
 			For Local it:=Eachin state.All()
 				
@@ -86,24 +91,23 @@ Class Jsonifier
 			
 			Local jobj:=jinsts.GetObject( i )
 			
-			Local obj:Object
+			Local obj:Variant
 						
 			If i<_insts.Length
 				
 				obj=_insts[i].obj
-				
 			Else
-				
 				Local ctor:=Cast<Invocation>( Dejsonify( jobj["ctor"],Typeof<Invocation> ) )
 			
-				obj=Cast<Object>( ctor.Execute() )
-				
+				obj=ctor.Execute()
 			Endif
-			
+
 			_dejsonified.Add( obj )
 			
+			Local tobj:=Cast<Object>( obj )
+			
 			'set value type state only on this pass.
-			If jobj.Contains( "state" ) DejsonifyState( obj,jobj.GetObject( "state" ),obj.DynamicType,False )
+			If jobj.Contains( "state" ) DejsonifyState( tobj,jobj.GetObject( "state" ),tobj.DynamicType,False )
 		Next
 
 		'set reference type state - do this on a second pass 'coz of forward refs. Probably wont always work?
@@ -113,7 +117,9 @@ Class Jsonifier
 			
 			Local obj:=_dejsonified[i]
 			
-			If jobj.Contains( "state" ) DejsonifyState( obj,jobj.GetObject( "state" ),obj.DynamicType,True )
+			Local tobj:=Cast<Object>( obj )
+			
+			If jobj.Contains( "state" ) DejsonifyState( tobj,jobj.GetObject( "state" ),tobj.DynamicType,True )
 		Next
 		
 		SetAssetsDir( assetsDir )
@@ -138,14 +144,6 @@ Class Jsonifier
 			Return New JsonNumber( Cast<Float>( value ) )
 		Case Typeof<String>
 			Return New JsonString( Cast<String>( value ) )
-		Case Typeof<Bool[]>
-			Return JsonifyArray( Cast<Bool[]>( value ) )
-		Case Typeof<Int[]>
-			Return JsonifyArray( Cast<Int[]>( value ) )
-		Case Typeof<Float[]>
-			Return JsonifyArray( Cast<Float[]>( value ) )
-		Case Typeof<String[]>
-			Return JsonifyArray( Cast<String[]>( value ) )
 		End
 		
 		'handle enums+references
@@ -168,12 +166,24 @@ Class Jsonifier
 		Select type.Kind
 		Case "Class"
 			Return JsonValue.NullValue
+		Case "Array"
+			Local n:=value.GetArrayLength()
+			Local jarray:=New JsonArray( n )
+			For Local i:=0 Until n
+				jarray[i]=Jsonify( value.GetArrayElement( i ) )
+			Next
+			Return jarray
 		End
 		
 		RuntimeError( "TODO: No jsonifier found for type '"+type+"'" )
 		Return Null
 	End
 	
+	Method Dejsonify<T>:T( jvalue:JsonValue )
+		
+		Return Cast<T>( Dejsonify( jvalue,Typeof<T> ) )
+	End
+	
 	Method Dejsonify:Variant( jvalue:JsonValue,type:TypeInfo )
 		
 		'handle primitive types
@@ -188,14 +198,6 @@ Class Jsonifier
 			Return Float( jvalue.ToNumber() )
 		Case Typeof<String>
 			Return jvalue.ToString()
-		Case Typeof<Bool[]>
-			Return DejsonifyArray<Bool>( jvalue )
-		Case Typeof<Int[]>
-			Return DejsonifyArray<Int>( jvalue )
-		Case Typeof<Float[]>
-			Return DejsonifyArray<Float>( jvalue )
-		Case Typeof<String[]>
-			Return DejsonifyArray<String>( jvalue )
 		End
 		
 		'handle references
@@ -206,8 +208,8 @@ Class Jsonifier
 			Elseif jvalue.IsString
 				Local id:=Int( jvalue.ToString().Slice( 1 ) )
 				Assert( id>=0 And id<_dejsonified.Length,"Dejsonify error" )
-				Local obj:=_dejsonified[id]
-				Return obj
+				Local inst:=_dejsonified[id]
+				Return inst
 			Endif
 		Case "Enum"
 			Return type.MakeEnum( jvalue.ToNumber() )
@@ -222,6 +224,15 @@ Class Jsonifier
 		Select type.Kind
 		Case "Class"
 			Return type.NullValue
+		Case "Array"
+			Local elemType:=type.ElementType
+			Local jarray:=Cast<JsonArray>( jvalue )
+			Local n:=jarray.Length,v:=elemType.NewArray( n )
+			For Local i:=0 Until n
+				Local elem:=Dejsonify( jarray[i],elemType )
+				v.SetArrayElement( i,elem )
+			Next
+			Return v
 		End
 		
 		RuntimeError( "No dejsonifier found for type '"+type+"'" )
@@ -229,33 +240,10 @@ Class Jsonifier
 		Return Null
 	End
 	
-	Method JsonifyArray<C>:JsonArray( values:C[] )
-		
-		Local jvalues:=New JsonArray( values.Length )
-		
-		For Local i:=0 Until jvalues.Length
-			jvalues[i]=Jsonify( values[i] )
-		Next
-		
-		Return jvalues
-	End
-	
-	Method DejsonifyArray<C>:C[]( jvalue:JsonValue )
-		
-		Local jvalues:=jvalue.ToArray()
-		Local values:=New C[jvalues.Length]
-		
-		For Local i:=0 Until values.Length
-			values[i]=Cast<C>( Dejsonify( jvalues[i],Typeof<C> ) )
-		Next
-		
-		Return values
-	End
-	
 	Private
 	
 	Class Instance
-		Field obj:Object
+		Field obj:Variant
 		Field id:String
 		Field ctor:Invocation
 		Field initialState:JsonObject
@@ -266,7 +254,7 @@ Class Jsonifier
 	Field _instsByObj:=New Map<Object,Instance>
 	Field _instsById:=New StringMap<Instance>
 	
-	Field _dejsonified:=New Stack<Object>
+	Field _dejsonified:=New Stack<Variant>
 	
 	Method JsonifyState:JsonObject( obj:Object )
 		

+ 17 - 44
modules/mojo3d/scene/jsonifier/jsonifierexts.monkey2

@@ -9,28 +9,28 @@ Class StdJsonifierExt Extends JsonifierExt
 		Select value.Type
 		Case Typeof<Vec2i>
 			Local v:=Cast<Vec2i>( value )
-			Return jsonifier.JsonifyArray( New Int[]( v.x,v.y ) )
+			Return jsonifier.Jsonify( New Int[]( v.x,v.y ) )
 		Case Typeof<Vec2f>
 			Local v:=Cast<Vec2f>( value )
-			Return jsonifier.JsonifyArray( New Float[]( v.x,v.y ) )
+			Return jsonifier.Jsonify( New Float[]( v.x,v.y ) )
 		Case Typeof<Recti>
 			Local v:=Cast<Recti>( value )
-			Return jsonifier.JsonifyArray( new Int[]( v.min.x,v.min.y,v.max.x,v.max.y ) )
+			Return jsonifier.Jsonify( new Int[]( v.min.x,v.min.y,v.max.x,v.max.y ) )
 		Case Typeof<Rectf>
 			Local v:=Cast<Rectf>( value )
-			Return jsonifier.JsonifyArray( New Float[]( v.min.x,v.min.y,v.max.x,v.max.y ) )
+			Return jsonifier.Jsonify( New Float[]( v.min.x,v.min.y,v.max.x,v.max.y ) )
 		Case Typeof<Vec3f>
 			Local v:=Cast<Vec3f>( value )
-			Return jsonifier.JsonifyArray( New Float[]( v.x,v.y,v.z ) )
+			Return jsonifier.Jsonify( New Float[]( v.x,v.y,v.z ) )
 		Case Typeof<Boxf>
 			Local v:=Cast<Boxf>( value )
-			Return jsonifier.JsonifyArray( New Float[]( v.min.x,v.min.y,v.min.z,v.max.x,v.max.y,v.max.z ) )
+			Return jsonifier.Jsonify( New Float[]( v.min.x,v.min.y,v.min.z,v.max.x,v.max.y,v.max.z ) )
 		Case Typeof<AffineMat4f>
 			Local v:=Cast<AffineMat4f>( value )
-			Return jsonifier.JsonifyArray( New Float[]( v.m.i.x,v.m.i.y,v.m.i.z, v.m.j.x,v.m.j.y,v.m.j.z, v.m.k.x,v.m.k.y,v.m.k.z, v.t.x,v.t.y,v.t.z ) )
+			Return jsonifier.Jsonify( New Float[]( v.m.i.x,v.m.i.y,v.m.i.z, v.m.j.x,v.m.j.y,v.m.j.z, v.m.k.x,v.m.k.y,v.m.k.z, v.t.x,v.t.y,v.t.z ) )
 		Case Typeof<Color>
 			Local v:=Cast<Color>( value )
-			Return jsonifier.JsonifyArray( New Float[]( v.r,v.g,v.b,v.a ) )
+			Return jsonifier.Jsonify( New Float[]( v.r,v.g,v.b,v.a ) )
 		Case typeof<Axis>
 			Return New JsonNumber( Int( Cast<Axis>( value ) ) )
 		End
@@ -42,28 +42,28 @@ Class StdJsonifierExt Extends JsonifierExt
 		
 		Select type
 		Case Typeof<Vec2i>
-			Local v:=jsonifier.DejsonifyArray<Int>( jvalue )
+			Local v:=jsonifier.Dejsonify<Int[]>( jvalue )
 			Return New Vec2i( v[0],v[1] )
 		Case Typeof<Vec2f>
-			Local v:=jsonifier.DejsonifyArray<Float>( jvalue )
+			Local v:=jsonifier.Dejsonify<Float[]>( jvalue )
 			Return New Vec2f( v[0],v[1] )
 		Case Typeof<Recti>
-			Local v:=jsonifier.DejsonifyArray<Float>( jvalue )
+			Local v:=jsonifier.Dejsonify<Int[]>( jvalue )
 			Return New Recti( v[0],v[1],v[2],v[3] )
 		Case Typeof<Rectf>
-			Local v:=jsonifier.DejsonifyArray<Float>( jvalue )
+			Local v:=jsonifier.Dejsonify<Float[]>( jvalue )
 			Return New Rectf( v[0],v[1],v[2],v[3] )
 		Case Typeof<Vec3f>
-			Local v:=jsonifier.DejsonifyArray<Float>( jvalue )
+			Local v:=jsonifier.Dejsonify<Float[]>( jvalue )
 			Return New Vec3f( v[0],v[1],v[2] )
 		Case Typeof<Boxf>
-			Local v:=jsonifier.DejsonifyArray<Float>( jvalue )
+			Local v:=jsonifier.Dejsonify<Float[]>( jvalue )
 			Return New Boxf( v[0],v[1],v[2],v[3],v[4],v[5] )
 		Case Typeof<AffineMat4f>
-			Local v:=jsonifier.DejsonifyArray<Float>( jvalue )
+			Local v:=jsonifier.Dejsonify<Float[]>( jvalue )
 			Return New AffineMat4f( v[0],v[1],v[2], v[3],v[4],v[5], v[6],v[7],v[8], v[9],v[10],v[11] )
 		Case Typeof<Color>
-			Local v:=jsonifier.DejsonifyArray<Float>( jvalue )
+			Local v:=jsonifier.Dejsonify<Float[]>( jvalue )
 			Return New Color( v[0],v[1],v[2],v[3] )
 		Case Typeof<Axis>
 			Return Cast<Axis>( Int( jvalue.ToNumber() ) )
@@ -97,7 +97,7 @@ Class InvocationJsonifierExt Extends JsonifierExt
 			jobj.SetString( "decl",decl )
 			jobj.SetString( "type",v.Decl.Type )
 			If v.Inst jobj.SetValue( "inst",jsonifier.Jsonify( v.Inst ) )
-			jobj.SetValue( "args",jsonifier.JsonifyArray( v.Args ) )
+			jobj.SetValue( "args",jsonifier.Jsonify( v.Args ) )
 			
 			Return jobj
 		End
@@ -161,30 +161,3 @@ Class InvocationJsonifierExt Extends JsonifierExt
 	End
 	
 End
-
-'need to fix array handling!
-Class Mojo3dJsonifierExt Extends JsonifierExt
-	
-	Const instance:=New Mojo3dJsonifierExt
-	
-	Method Jsonify:JsonValue( value:Variant,jsonifier:Jsonifier ) Override
-		
-		Select value.Type
-		Case Typeof<Material[]>
-			Return jsonifier.JsonifyArray( Cast<Material[]>( value ) )
-		End
-		
-		Return Null
-	End
-	
-	Method Dejsonify:Variant( jvalue:JsonValue,type:TypeInfo,jsonifier:Jsonifier ) Override
-		
-		Select type
-		Case Typeof<Material[]>
-			Return jsonifier.DejsonifyArray<Material>( jvalue )
-		End
-
-		Return Null
-	End
-
-End