-
Notifications
You must be signed in to change notification settings - Fork 150
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Saving and Loading #9
Comments
Yes I wanted to know the same thing. That would be great. |
I have experimented with various ways to serialize the viewmodels, but this turn out to be much harder than it seems. The build-in serialization frameworks in .net do not play nice with unexpected types, circular dependencies, needs a seperate constructor or setup method, ... I also tried Json.net, but that doesn't work with ReactiveUI as the bindings break due to order of deserialization, double initialization of reactive properties, ... If you want more details I have a 3 page document with the approaches I tried and the problems I encountered. Overall, right now the easiest, most reliable way to do saving would be to either provide a custom serializer implementation for your types, or to convert your viewmodels into models and serialize those (this is what I do in my applications). I might make another attempt someday, but I can't make any promises there. |
@Wouterdek I am very new to WPF and I am using caliburn mirco with your tool could you make an example of this am trying to figure out things as I go but its a bit hard am trying to break down your lua demo I need the same thing for a XML structure and am tearing my hair out lol |
@Wouterdek Thanks |
I convert my viewmodels to models and back using seperate, dedicated classes. What that class does exactly depends on what your model looks like, but here is a short overview: // Add an instance of this class to your network viewmodel as a property
// Create similar converter class(es) for your node classes
class NetworkConverter {
NetworkConverter(NetworkViewModel vm){ ... }
Network BuildModel()
{
// Create node models
var nodeModels = new Dictionary<NodeViewModel, NodeModel>();
foreach(var node in vm.Nodes)
{
var nodeModel = node.Converter.BuildModel();
nodeModels[node] = nodeModel;
}
// Create connection models
var connectionModels = new List<Connection>();
foreach(var connection in vm.Connections)
{
// Take the connection input and output, take their corresponding parent node vms,
// look them up in the nodeModels dictionary,
// take the input/output models from the node model
// and create a connection model using those.
}
// Save pure UI data, such as node positions, collapse state, ...
string metadata = SerializeMetaData(vm);
return new Network(nodeModels.Values.ToList(), connections, metadata)
}
NetworkViewModel LoadModel(Network net)
{
// Create node viewmodels, doing the opposite of what is above.
// Create connection viewmodels, doing the opposite of what is above.
// Load pure UI metadata
LoadMetaData(vm, net.Metadata);
}
private string SerializeMetaData(NetworkViewModel vm)
{ }
private void LoadMetaData(NetworkViewModel vm, string metadata)
{ }
} A nice advantage to this strategy is that you can make your models immutable, which makes them easier/safer to use in a database context. As these models are snapshots of your viewmodels, you can also use them to implement the memento pattern, which is useful for stuff like undo/redo. |
You can find an overview of the things I've tried here |
@Wouterdek mm interesting I will give this a try and let you know also thanks for responding not many devs respond nowadays |
Hi! Any news about saving/loading? |
There have been no changes relating to saving/loading. I recommend writing your own system to transform your viewmodels to models which can be serialized. |
https://github.com/Traderain/Wolven-kit/blob/master/WolvenKit/MainController.cs#L220 Have you tried json.net like this? It keeps the references and such for me and works fairly well. |
Hi Wouterdek, I see this project (Winform) used BinaryReader/Writer to store, have you read it? https://github.com/komorra/NodeEditorWinforms |
hi, Wouterdek, i wrote a tool based on your repository and serialize/deserialize the nodes and connections by my self. |
BinaryWriter provides methods to write bytes/ints/bools/doubles/strings/... but not arbitrary complex datatypes. The implementation used in the library you linked seems to come down to just doing the serialization manually. I think its easier to abstract the persistent state into a model class (as you are supposed to in Model-View-ViewModel code), and serialize this class automatically. This also has other advantages that come with decoupling of viewmodel and view.
Try to run the loading code while profiling to see what runs slowly (Guide) |
I've implemented import/export for the scene in my project. Currently, I create custom lite model classes for every node and connections and place it in scene. After I've just serialized scene to binary. Import and export are working perfectly. You can even import scene several times on the canvas. |
Have you fixed slow nodes creation? |
How are you adding these? One possible cause may be that you are adding them one by one. If you create a list of all nodes you want to add and then add that list in one call to the network, that should give better performance. Same thing for the connections.
No, apart from the practical difficulties and development cost of the viewmodel serialization (detailed above) I think it makes more sense to serialize models, which are different in each application. |
I'm creating nodes in task, but adding in UI thread like this
So, creating of 80 nodes and 107 connection takes ~3 sec, but after adding them to networkViewModel it takes 1 minute 18 sec with unreasonable UI to render. My laptop: I7-6700HQ 2.6Ghz, RAM 16 Gb, SSD. Maybe It's because of graph validation? Could it be turned off? |
@danvervlad The repository contains a project called StressTest which has a button which creates and adds 100 nodes and 99 connections. On my laptop this completes in about 6 seconds. This uses pretty simple nodes though, and no verification. |
Yes, you are right. I've created separate issue for that #43 |
I submitted PR #74 yesterday, perhaps take a look hopefully it can solve your requirements for saving, its a Json string that is produced so should be able to be adapted to any other media for saving such as a database, initial save is done to a dictionary for fast switching and then committed to files upon exit of application, these files are then loaded into the application on start up. |
any news on this ? What is the current status ? |
Status is as described above. I still recommend the method described in #9 (comment) |
Moved |
@PlateMug |
Is there a way to save the nodes and load them? 请告诉我,大神 |
I followed this instruction and created the following code. But it does not seem to work. I am not sure what properties to save from a connection view model to recreate it later when the nodes are loaded. Could you point me in a right direction to see what I am doing wrong? Thanks.
Serialisation code.
Output:
|
Well, I have solved it. This serializes the nodes and the connections to JSON, and I am able to redraw the nodes from the JSON.
|
Can you add an example about saving and loading? |
I decided not to use this library after a couple of experiments and I don't have any code to refer now. I have a vague memory and it goes like this.
|
I can already save and load the Network, but when loading 100 Nodes will cause obvious stuttering, it takes about 10 seconds, is there any way to speed it up? |
I've got a good, robust loading and saving working, including position. I'm trying to figure out how to save/load the size of the nodes though. I know in the NodeViewModel there's a Size property, and I can take that, serialize it and deserialize it, however when I set the value of the Size property programmatically, it doesn't resize the view. I've tried resizing the view manually by setting its Width and Height, which works, but then the drag handles don't let me resize the node to be smaller than the value I resized it to. I can only resize it to be larger. Any thoughts would be appreciated. |
@glenwrhodes NodeNetwork/NodeNetwork/Views/NodeView.cs Line 163 in 9e453f7
|
Is there a way to save the nodes and load them?
The text was updated successfully, but these errors were encountered: