GithubHelp home page GithubHelp logo

cmag's People

Contributors

dziubanmaciej avatar

Stargazers

 avatar

Watchers

 avatar

cmag's Issues

Layout orpahned nodes in graph in a more smart way

Currently we set x to a magic value and only increment y. Ideally we would like to arrange them in some 2D grid. We don't want a giant vertical wall of nodes.

Should this grid depend on the number of layers? It would be nice if this grid would have the same height as the layers. But if we don't have layers or we have only two, then it would look too horizontal. Some clever heuristics will be needed. We should to the screen aspect ratio - worldSpaceAspectRatio.

Add helper for string composition

Sometimes ImGui expects only a const char* as input and we have to do the format ourselves. We usually concatenate strings or allocate a temporary char array with arbitrary size and call sprintf/snprintf.

Goal of this task is to provide a nice helper to do this. It can be a function with a static variable with char memory allocated and call snprintf() on it. I think snprintf can be also called to ask for required size, so we could do this to avoid buffer overruns.

Store more fields in CmagProject

A lot of fields in the browser are held in arbitrary places, mostly in TargetGraph class. This works, but they will not be restored after save/load. We should move them into CmagProject class, maybe in some Graphical sub-struct as in CmagTarget and make json parser/writer to be aware of it.

Initial list of fields to move (may be incomplete):

  • camera position and scale (struct Camera)
  • dependency types that are displayed in graph (dependencyTypeSelected)
  • active tab
  • selected target
  • autosave status

It would be best to do this after #32, so we can easily test if saving works.

Make selecting targets feel nicer

  1. Make targets in ListDirTab and TargetFolderTab selectable. This should be the same selection as in TargetGraphTab, so this state must be shared.
  2. Make right click open a context window to "Show in XXX tab" and suggest all other tabs.
  3. Move camera so the selected target is in center when moving to TargetGraphTab.

Add file associations for .cmag-project files

It would be nice if we could double-click on a .cmag-project file and it would launch cmag-browser. We will have to create a file association for the OS. It will require some kind of a script that runs during installation. Not sure when to remove it - we don't have a defined uninstallation routine.

On Windows we have to mess with the registry. Probably something like HKCU\SOFTWARE\Classes\.cmag-project\shell\Command = C:\Program Files\cmag\cmag_browser.exe. Admin privileges needed.

On Linux we have to create a .desktop file, also known as a desktop entry. They can be created in user-specific directories, so root access won't be needed.

Create cmdline documentation viewable on GitHub

It would be convenient to have documentation of command line options in a separate file, so we can link to it in README.

Currently it's hardcoded in argument parser classes. We could move it to a separate .txt file and generate a header file with header_pack. Then it could be included and used by argument parser classes when -h is passed.

Remove unneeded logs in dumper

We log creating various json files, but then we remove them and they are not there. Remove these logs - they are misleading.

We have an option to keep these files. We can then keep the logs as well.

Refactor cmag version and document it

Currently cmag version has 2 components. We should have 3:

  • major - bumped only with new mega-features. This should stay 1 for the most time
  • minor - bumped when project file structure changes.
  • patch - bumped with new user-visible features

Implement this and document in a separate .md file. Mention that it is not semantic versioning.

Remove cycles from graph during layout

This should always be the first step in Sugiyama layout approach. If we don't do this, we may omit some (or all) nodes during layer assignment.

This is not a very complicated algorithm (see here), but do we have to do this? Can we even have cycles? Isn't dependency graph always a DAG? It should be, but this suggests there might be an option to have cycles.

Add warning in TargetFolderTab about USE_FOLDERS

Do not show warning when FOLDER is not set to any target. If it is, check the generator:

  • VS or XCode - check if USE_FOLDERS is set. If not, give a warning that it may not work.
  • Other - give a warning, that it will not work in current generator.

Don't care about CMP0143. This is quite complex to reliably check and googling how it works takes 30 seconds. Let's not treat the user as a complete dumbo.

<rant>Besides, this policy seems sounds stupid... Couldn't they just change default value of USE_FOLDERS? Would be 100x simpler.</rant>

Scale down text in graph if it doesn't fit

Currently we apply ellipsis if the target name is too long to fit in the node on graph.

We can enhance that and try to scale the text down before doing it, because ellipses don't look too good. So implement something like:

  • calculate textWidth na maxTextWidth
  • if textWidth > maxTextWidth, then scale it down by max(maxTextWidth/textWidth, threshold)
  • do the existing logic with ellipsis if it still doesn't fit (it may not fit because of the threshold).

This is a continuation of #37

Make interface look more complete

Some interface elements look very unpolished. I should rethink them and make them more ergonomic to use. Maybe consult some other people and see what they think?

image
image
image
image

Implement project merging

For single config generators, such as Unix Makefiles we should be able to merge outputs of two cmag analyses into a one project to be able to compare different configs.

We would have to verify all fields that are not per-config and make sure if they are the same. Some could be different, .e.g needsLayout, in which case we would set it to true.

Use cmake project name as cmag project name by default

Currently all the projects are named "project". There is an option to change it, but nobody will use it and all projects will just be called "project" forever... Use CMake project's name instead by default. This may be tricky, because we use project name in filenames, but it certainly can be done.

Make the browser DPI aware

Not sure how the browser will behave when DPI scaling is not 100%.
Not sure what will happen when DPI changes.

I think this must be handled manually. ImGui might have some helpers. Research the topic and see what should be done.

Do this after: #69

Check cmag version in project file

Currently we will fail in weird ways if project file structure changes and we cannot parse the project file. A cool way would be to make the parser compatible with old formats, but that'll be too much hassle with no real benefits, at least on current stage of the project.

We need to compare version stored in project file and current cmag version. If it's different - return an error.

Resolve target aliases

Currently, if a target depends on another target, but uses its alias, then we can't figure out which target it is pointing to in the preamble. CMake has ALIASED_TARGET property, but would need a reverse property - list of all aliases of a target. This is not available.

We could think of some heuristics to work out that "this target is probably an alias of that target". It could work in some cases, but sounds dangerous.

We could also create a second CMake pass. We would have to gather all targets that are listed as dependencies in LINK_LIBRARIES or MANUALLY_ADDED_DEPENDENCIES. Then feed the list to CMake (with a different postamble) and dump ALIASED_TARGET property of all of them.

Allow copying data to clipboard

First, see how to copy to the clipboard in general. Would could do this with OS-specific APIs. We'd need to implement separately for Windows, X11 and Wayland (or not :)). Or we could use ImGui infrastructure for it. There's a function called ImGui::SetClipboardText(). It looks like it works and should be sufficient.

In order to copy, we should have a right-click menu and an option to "Copy to clipboard". It would be good to finally create some generic helper for popups while we're at it. Maybe see BeginPopupContextItem() instead doing popups manually?

List of data that should be copyable:

  • target name (from graph, from list file tab, from target folder tab)
  • target property name
  • target property value
  • folder name, folder full path (from list files tab)
  • textual globals (from summary tab)

Fix wrapping texture in graph

There is a bug with graph rendering. The graph wraps for 1 pixel on the bottom.

image

I don't know why this happens, but my guess is that our texture is too small by 1 pixel for some reason and ImGui samples it with GL_REPEAT.

Enable big projects

I've seen some projects fail to dump when reading super-big json files. I think it's because of how ::readFile() function is implemented. It may truncate the output. Find the size at which this can fail, make a test for it and fix it.

Dump more info about imported targets

Imported targets are scoped to their cmake list file only and we cannot take information about them in the postamble. This causes us to not have full information about them.

Technically we could shim additional postambles in all list files in a second cmag pass, but that would be super complex.

We could enable CMAKE_FIND_PACKAGE_TARGETS_GLOBAL. This option could be dangerous to some projects - there could be duplicate names. Also, it is added in CMake 3.24 and we support 3.12. It would not work for all versions.

Make cmag buildable by CMake 3.15

We support CMake 3.12 for cmag dumper. This is the lowest version that will work with our current postamble. It would be nice if the cmag project itself would build with CMake 3.12.

I haven't even checked if it works. But if it's possible, we could add some CI verification to make sure we can build cmag and execute tests with CMake 3.12. I wouldn't add it to per-change testing, but we could have some way to run extra GH action on demand and verify this. For example before release.

Validate with selected projects

Gather a list of popular CMake projects, clone them, run cmag on them and expect them to be parsed successfully. This will take a considerable amount of time, so it should probably be a thing to execute manually before new release or dangerous commit. It can be implemented as a GitHub action with workflow_dispatch event.

Current list:

Improve edge rendering for different dependency types

Render MANUALLY_ADDED_DEPENDENCIES differently. Different stipple? Different color?

Make checkboxes for every dependency type instead of a combo box. User should be able to select any combination of dependency types to render.

Fix tooltip rendering in tables

Currently, we calculate area to check for hover based on size of the text. But this text could be shorter or longer than the table cell, so it will be wrong. Looks like it isn't that simple. Maybe we could use sizes from previous frame?

Move all magic values in browser to CmagBrowserTheme

All hardcoded widths, ratios etc. used to layout the interface should be inside the theme object. We can also add a method to it to recalculate some values based on current window size. It would be called each frame or in some resize callback, if ImGui provides it.

Create scripts for automatic deployment to public repositories

Cmag should be easy to install on all popular supported systems. We should have:

  1. Windows and Linux - Simple binary .zip releases
  2. Windows - Chocolatey
  3. Linux - AUR
  4. Linux - Ubuntu repository

Ideally all of this should be automated, so I can release cmag on all systems at once. How to do it?

  • compiling localy on native systems. Easy, but annoying - I'll have to boot both OSes.
  • GitHub actions - completely new territory to explore. This vendor-locks me deeper into GitHub, but I don't care. Hard to do it securely - I'd have to store keys for all the remote repositories on GitHub, which I don't like.
  • Docker containers - I hate Docker, but maybe it's time to grow up? I'd have to re-learn this stuff, but it may be the best option.
  • Compiling on Windows + WSL for Linux. This just sucks, but it's an idea.
  • External deployment services? Probably not worth it.

Handle genexes evaluated based on target

There are some generator expressions, which are evaluated differently based on the target they are bound to.

  1. $<LINK_LANGUAGES:languages> (required for #40)
  2. $<LINK_LANGUAGE>
  3. $<LINK_LANG_AND_ID:language,compiler_ids>
  4. $<COMPILE_LANGUAGE:languages>
  5. $<COMPILE_LANGUAGE>
  6. $<COMPILE_LANG_AND_ID:language,compiler_ids>

First problem: they cannot be be evaluated with $<TARGET_GENEX_EVAL>. Not sure why, because it technically has all the context required, but it just doesn't work. We cannot know in advance that a property will contain one of these genexes and remove it in the postamble.

Second problem: these properties will evaluate to different values when used in INTERFACE_LINK_LIBRARIES. Resulting value will depend on the language of target using this interface. We'll probably have to walk through all dependencies to resolve that properly.

Third problem (extension of the second): can it be transitive?

Layout graph based on selected dependency type

The function createGraph() uses allDependencies field when converting from std::vector<CmagTarget *> to Graph structure. We could use only the dependencies that are enabled with checkbox in the GUI to make a better graph.

Do this after #20

Implement saving project in browser

Saving project to json is already implemented, but not used in the browser.

Not sure how to exactly implement saving. Possible options:

  1. The good old Save and Save as. Ctrl+S shortcut to save. Would we have to implement menu bar (see BeginMenuBar() in ImGui)? Maybe it could be somewhere else. Also, it would be good to check for changes and display the usual "Do you want to leave without saving?" dialog.
  2. Autosave after every change.
  3. Autosave every 10 seconds.

To make it familiar to people, option 1. would be the best. Option 3. would be the most convenient. Maybe let's implement both and make 3. optional?

Figure out custom target dependencies

Targets can hold dependencies on custom targets using files. If a custom target has some file in OUTPUT and some other target has it in SOURCES than CMake will create a dependency.

Can we even check this? It may be impossible.

Handle target names which do not fit into node in graph

We have a fixed size of nodes and target names can be of arbitrary length, so there can be a situation in which they do not fit.

One solution would be to make the node width to be resizable. This would be quite complicated for rendering, graph layout algorithm and could also look weird. CMake with Graphviz does that and it doesn't look good for long names.

Another solution would be to scale down the text so it fits into the node. Not sure if this can be done. Not sure if this will look good. Fonts can be distorted.

Another solution would be to shorten the string and add ellipsis. So instead of nlohmann::json::nlohmann::json we could see nlohmann::json:nloh.... Full name would be displayed in a popup (on-hover).

Maybe implement 2 and 3 approaches? Scale down the text to some extent and add ellipsis if it still doesn't fit?

Add an edge popup

Define some rectangle around the edge as hover space. Display dependency types and an example invocation to show why this type is here, e.g.

Build dependency, created by
target_link_libraries(TargetA PRIVATE TargetB)

or

Manual dependency, created by
add_dependencies(TargetA TargetB)

Order vertices during graph layout

Currently we just output them in whatever way we've ordered the targets. This works, but smarter ordering within each layer would allow us to minimize crossings.

This is a standard step for sugiyama approach, so it shouldn't be hard to find information about it. Unfortunately, it usually involves creating "virtual nodes" to eliminate edges hopping multiple layers. Cmag renders all edges as straight lines, so we'd have to think of something else.

I can't find any resources on "sugiyama layout with straight edges".

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.