Example #1
0
        /// <summary>
        /// Saves the surface to bytes. Performs also modified child surfaces saving before.
        /// </summary>
        /// <remarks>
        /// Assume this method does not throw exceptions but uses return value as a error code.
        /// </remarks>
        /// <returns>True if failed, otherwise false.</returns>
        public bool Save()
        {
            // Save all children modified before saving the current surface
            for (int i = 0; i < Children.Count; i++)
            {
                if (Children[i].IsModified && Children[i].Save())
                {
                    return(true);
                }
            }

            Saving?.Invoke(this);

            // Save surface meta
            _meta.AddEntry(10, Utils.StructureToByteArray(ref CachedSurfaceMeta));

            // Save all nodes meta
            VisjectSurface.Meta11 meta11;
            for (int i = 0; i < Nodes.Count; i++)
            {
                var node = Nodes[i];
                meta11.Position = node.Location;
                meta11.Selected = false; // don't save selection to prevent stupid binary diffs on asset
                // TODO: reuse byte[] array for all nodes to reduce dynamic memory allocations
                node.Meta.AddEntry(11, Utils.StructureToByteArray(ref meta11));
            }

            // Save graph
            try
            {
                // Save graph
                using (var stream = new MemoryStream())
                    using (var writer = new BinaryWriter(stream))
                    {
                        // Save graph to bytes
                        SaveGraph(writer);
                        var bytes = stream.ToArray();

                        // Send data to the container
                        Context.SurfaceData = bytes;

                        Saved?.Invoke(this);

                        // Clear modification flag
                        _isModified = false;
                    }
            }
            catch (Exception ex)
            {
                // Error
                Editor.LogWarning("Saving Visject Surface data failed.");
                Editor.LogWarning(ex);
                return(true);
            }

            return(false);
        }
Example #2
0
        internal static void WriteVariant(this BinaryWriter stream, object value)
        {
            if (value == null)
            {
                stream.Write((byte)0);
                stream.Write(0);
                return;
            }
            var type        = value.GetType();
            var variantType = ToVariantType(type);

            stream.Write((byte)variantType);
            switch (variantType)
            {
            case VariantType.Object:
                if (type != typeof(FlaxEngine.Object))
                {
                    stream.Write(int.MaxValue);
                    stream.WriteStrAnsi(type.FullName, 77);
                }
                else
                {
                    stream.Write(0);
                }
                break;

            case VariantType.Asset:
                if (type != typeof(Asset))
                {
                    stream.Write(int.MaxValue);
                    stream.WriteStrAnsi(type.FullName, 77);
                }
                else
                {
                    stream.Write(0);
                }
                break;

            case VariantType.Enum:
            case VariantType.Structure:
                stream.Write(int.MaxValue);
                stream.WriteStrAnsi(type.FullName, 77);
                break;

            default:
                stream.Write(0);
                break;
            }
            Guid id;

            switch (variantType)
            {
            case VariantType.Bool:
                stream.Write((byte)((bool)value ? 1 : 0));
                break;

            case VariantType.Int16:
                stream.Write((short)value);
                break;

            case VariantType.Uint16:
                stream.Write((ushort)value);
                break;

            case VariantType.Int:
                stream.Write((int)value);
                break;

            case VariantType.Uint:
                stream.Write((uint)value);
                break;

            case VariantType.Int64:
                stream.Write((long)value);
                break;

            case VariantType.Uint64:
                stream.Write((ulong)value);
                break;

            case VariantType.Float:
                stream.Write((float)value);
                break;

            case VariantType.Double:
                stream.Write((double)value);
                break;

            case VariantType.Pointer:
                stream.Write((ulong)(IntPtr)value);
                break;

            case VariantType.String:
                stream.WriteStr((string)value, -14);
                break;

            case VariantType.Object:
                id = ((FlaxEngine.Object)value).ID;
                stream.WriteGuid(ref id);
                break;

            case VariantType.Structure:
            {
                var data = Utils.StructureToByteArray(value, type);
                stream.Write(data.Length);
                stream.Write(data);
                break;
            }

            case VariantType.Asset:
                id = ((Asset)value).ID;
                stream.WriteGuid(ref id);
                break;

            case VariantType.Blob:
                stream.Write(((byte[])value).Length);
                stream.Write((byte[])value);
                break;

            case VariantType.Enum:
                stream.Write(Convert.ToUInt64(value));
                break;

            case VariantType.Vector2:
                stream.Write((Vector2)value);
                break;

            case VariantType.Vector3:
                stream.Write((Vector3)value);
                break;

            case VariantType.Vector4:
                stream.Write((Vector4)value);
                break;

            case VariantType.Int2:
                stream.Write((Int2)value);
                break;

            case VariantType.Int3:
                stream.Write((Int3)value);
                break;

            case VariantType.Int4:
                stream.Write((Int4)value);
                break;

            case VariantType.Color:
                stream.Write((Color)value);
                break;

            case VariantType.Guid:
                id = (Guid)value;
                stream.WriteGuid(ref id);
                break;

            case VariantType.BoundingBox:
                stream.Write((BoundingBox)value);
                break;

            case VariantType.BoundingSphere:
                stream.Write((BoundingSphere)value);
                break;

            case VariantType.Quaternion:
                stream.Write((Quaternion)value);
                break;

            case VariantType.Transform:
                stream.Write((Transform)value);
                break;

            case VariantType.Rectangle:
                stream.Write((Rectangle)value);
                break;

            case VariantType.Ray:
                stream.Write((Ray)value);
                break;

            case VariantType.Matrix:
                stream.Write((Matrix)value);
                break;

            case VariantType.Array:
                stream.Write(((object[])value).Length);
                foreach (var e in (object[])value)
                {
                    stream.WriteVariant(e);
                }
                break;

            case VariantType.Dictionary:
                stream.Write(((Dictionary <object, object>)value).Count);
                foreach (var e in (Dictionary <object, object>)value)
                {
                    stream.WriteVariant(e.Key);
                    stream.WriteVariant(e.Value);
                }
                break;

            case VariantType.Typename:
                if (value is Type)
                {
                    stream.WriteStrAnsi(((Type)value).FullName, -14);
                }
                else if (value is ScriptType)
                {
                    stream.WriteStrAnsi(((ScriptType)value).TypeName, -14);
                }
                break;
            }
        }