Giter Site home page Giter Site logo

Comments (23)

k-alexandrovsky avatar k-alexandrovsky commented on September 15, 2024

Нашел потенциальный ключ к разгадке тайны структуры модели. В классе NamesAreUniqueValidator (можешь просто в любом файле написать import org.eclipse.xtext.validation.NamesAreUniqueValidator и перейти туда через Ctrl) есть следующий код:

final IResourceServiceProvider resourceServiceProvider = resourceServiceProviderRegistry.getResourceServiceProvider(resource.getURI());
if (resourceServiceProvider==null)
    return;
IResourceDescription.Manager manager = resourceServiceProvider.getResourceDescriptionManager();
if (manager != null) {
    IResourceDescription description = manager.getResourceDescription(resource);
    if (description != null) {
        Iterable<IEObjectDescription> descriptions = description.getExportedObjects();

Так вот этот getExportedObjects тебе и нужен, я полагаю. Все @Inject'ы нужные там есть, про ExecutableExtensionFactory ты знаешь. У меня в MultipleResourceGenerator есть еще inject для получения самих Resource'ов. Проверка уникальности имен смешная, кстати, если вглядываться в код. Там по каждому чиху (@Check для EObject, это валидация после любого написанного в редакторе символа) прогоняются все объекты в ресурсе и сравниваются их имена. Я вообще надеялся, что там какое то кеширование и все сделано оптимально, а не каждый раз формирование списка и беготня по нему.

from raox.

k-alexandrovsky avatar k-alexandrovsky commented on September 15, 2024
val myWorkspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
val project = myWorkspaceRoot.getProject(model.eResource.URI.segments.get(model.eResource.URI.segmentCount - 2));

from raox.

bogachev-pa avatar bogachev-pa commented on September 15, 2024

Я тут подумал, ведь наверняка удобнее будет, чтобы TraceInfo обновлялось не по каждому чиху, а только при первом открытии и при каждом сохранении модели.

Представь себе, ты решил поменять местами два блока ресурсов. Вырезал один блок, TraceInfo пересчиталась, они исчезли, вставил, TraceInfo пересчиталась, все флажки трассировок для этого блока сбросились.

Так что надо будет делать это, наверное, при сохранении модели и при первом открытии окошка TraceInfo. А вот вопрос, как получить заветный allContents остается открытым. Завтра напишу, наверное, на xtext-овский форум, когда будет время.
Самое забавное, что outline при нажатии Ctrl+S не пересчитывается.

from raox.

k-alexandrovsky avatar k-alexandrovsky commented on September 15, 2024

Ну флажки то могут и не сброситься, если помнить все по именам. Проблема в том, что run должен сохранять модель (чего он сейчас не делает, потому что я не смог тут победить эклипс пока), и тогда изменения применятся, трейсинфо пересчитается, а пользователю запустится не то, что он хотел.

from raox.

bogachev-pa avatar bogachev-pa commented on September 15, 2024

Ну флажки то могут и не сброситься, если помнить все по именам.

Они сбросятся, когда пользователь вырежет ресурсы из модели. Или ты предлагаешь помнить вообще все имена, которые когда-то были, а не только последний шаг?

Проблема в том, что run должен сохранять модель (чего он сейчас не делает, потому что я не смог тут победить эклипс пока), и тогда изменения применятся, трейсинфо пересчитается, а пользователю запустится не то, что он хотел.

По-моему, это вообще не проблема. Если пользователь что-то поменял в модели и не сохранил, то он, очевидно, и не интересовался окошком TraceInfo, раз не заметил, что оно не изменилось в соответствии с его изменениями в модели.

from raox.

k-alexandrovsky avatar k-alexandrovsky commented on September 15, 2024

Или ты предлагаешь помнить вообще все имена, которые когда-то были, а не только последний шаг?

Ну да, пусть будет набор удаленных сущностей, они будут запоминаться на какое то время. Например, цикличный буфер на 5, скажем, объектов.

Если пользователь что-то поменял в модели и не сохранил, то он, очевидно, и не интересовался окошком TraceInfo, раз не заметил, что оно не изменилось в соответствии с его изменениями в модели.

Но если пользователь вообще не сохраняет модели, а просто нажимает на Run, ожидая, что запустится написанное, то ему TraceInfo и не воспользоваться никак, лишь прогонять модель дважды.

from raox.

bogachev-pa avatar bogachev-pa commented on September 15, 2024

Ну не знаю, по-моему Ctrl+S нажать лишний раз не проблема, а вот когда всё мелькает и меняется в окошке это может быть некруто.
А 5 объектов это, наверное, секунд десять активного редактирования модели, она же обновляется по каждому чиху. Ты же не ожидаешь, что тебе какой-нибудь интелисенс или эклипсовский статик аналайзер всё распарсит, пока ты код не сохранишь. В общем, не знаю, мне кажется, по сохранению удобнее.

from raox.

bogachev-pa avatar bogachev-pa commented on September 15, 2024

Задал вопрос на форуме.
https://www.eclipse.org/forums/index.php/t/872583/

from raox.

bogachev-pa avatar bogachev-pa commented on September 15, 2024

@k-alexandrovsky
Смотри, такая проблема.
Мне нужно добавить все данные из TraceConfig в sensitivityList базы данных перед тем, как туда будут занесены первые записи.
Но как это сделать, если traceConfig хранится в UI, а инициализация базы данных и добавление туда первых записей происходит в методе initSimulation(), откуда, как я понимаю, доступа к UI у нас нет.

Накостылить можно, передавая какой-нибудь временный список имен в фейковый класс либы перед инициализацией, и оттуда уже доставать их в методе initSimulation(). Но как сделать грамотно, я не могу придумать.

Edit: c таким костылем всё работает шикарно (:

Edit 2: с другой стороны, это возможно и правильно, чтобы конфигурация трассировки хранилась в либе, а не в уи. А из уи она только могла настраиваться перед началом прогона.

from raox.

k-alexandrovsky avatar k-alexandrovsky commented on September 15, 2024

@bogachev-pa
Я думал, что тут все супер-просто. ExecutionHandler (который UI, между прочим) через рефлексию дергает initSimulation() у Embedded.java, которая дергает это все у Simulator'a, в том числе подготавливает базу данных. После этого UI дергает у TraceConfig'a метод (пусть будет тоже init()), который лезет в Database и у нее дергает кучу раз метод addSensitivity(String name).

from raox.

k-alexandrovsky avatar k-alexandrovsky commented on September 15, 2024

Так, я посмотрел поподробнее, тут я не сильно прав, все немного запутаннее. Метод initSimulation() в Embedded придется либо разбить на initSimulation() и initModel(), что тоже глупо, сколько можно инитов, либо в конструкторе Tracer'а добавлять все зависимости. Из какого нибудь статического списка где-нибудь в либе (хоть в том же Tracer'е), а вести этот список будет UI.

from raox.

bogachev-pa avatar bogachev-pa commented on September 15, 2024

@k-alexandrovsky
Реализовал, примерно, как ты описал.

Отревьюй, пожалуйста, этот коммит, там много каких-то стремных мест, в основном помеченных комментарием //TODO, но у меня уже голова плавится, нужен свежий взгляд)
Я не уверен, что вообще правильно распределил роли с этими TraceConfig, TraceNode и TraceConfigurator.

from raox.

k-alexandrovsky avatar k-alexandrovsky commented on September 15, 2024

Черт, я ничего не понял в TraceConfig'е, кроме того, что есть какие то категории, а также иерархия. Единственное, я понял, что надо как то унифицировать механизм формирования имен. Потому что modelName + "." + objectName как то не очень здорово. Я предлагаю воспользоваться getFullyQualifiedName(EObject object).
И имя модели само оттуда вылезет. А в сам метод занести в свитч имена на релевантные ресурсы, активности, и все, что мы проверяем в sensitivityList. И это будет внутри лежать. А имя для отображения бери через getNameGeneric.
P.S. Возможно, я вообще не понял изначальную идею, потому что на гитхабе тяжко смотреть код, а дифф вообще равен всему классу целиком)

from raox.

bogachev-pa avatar bogachev-pa commented on September 15, 2024

Этого я и боялся, походу я нехило набыдлокодил с этим трэйс конфигом, раз ты ничего не понял)
Тогда давай в субботу обсудим, если ты будешь.

from raox.

k-alexandrovsky avatar k-alexandrovsky commented on September 15, 2024

В общем, я вроде как решил проблему с обновлением модели и получением ecore-дерева.
Вот кусок кода, в котором почти все хорошо:

IPartService service = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getPartService();

service.addPartListener(new IPartListener2()
{

    ...

    @Override
    public void partActivated(IWorkbenchPartReference partRef)
    {
        System.out.println("ACTIVATED:" + partRef.getId() + " : " + partRef.getPartName());
        if(partRef.getId().equals("ru.bmstu.rk9.rdo.RDO"))
        {
            IResource resource = ResourceUtil.getResource(((XtextEditor)partRef.getPart(true)).getEditorInput());
            IEditorPart editor = partRef.getPage().getActiveEditor();
            ((XtextEditor)editor).getDocument().addModelListener(new IXtextModelListener()
            {           
                @Override
                public void modelChanged(XtextResource resource)
                {
                    System.out.println(resource.getContents().get(0));
                }
            });
        }
    }

    ...

Единственное, тут этот add быдлокодерский, он без устали плодит одинаковые listener'ы. Поэтому в в part listener'е мы будем вести индекс объектов (IXtextDocument'ов, которые мы получаем через ((XtextEditor)editor).getDocument()), к которым мы уже прописались, и добавлять listener'а лишь единожды. А в самом listener'e мы будем проверять хеш-код объекта (модели) на равенство прошлому состоянию, потому что он спамит сигналами об изменениях даже когда ты просто бегаешь по редактору и нажимаешь там всякие кнопки мыши, не прикасаясь к клавиатуре. И объект один и тот же.

Суть:

System.out.println(resource.getContents().get(0).hashCode());

from raox.

bogachev-pa avatar bogachev-pa commented on September 15, 2024

Круто, сегодня попробую.
Отпиши на форум xtext'a, чтобы еще 7.5 тысяч интересующихся тоже узнали решение (:

from raox.

bogachev-pa avatar bogachev-pa commented on September 15, 2024

А в самом listener'e мы будем проверять хеш-код объекта (модели) на равенство прошлому состоянию, потому что он спамит сигналами об изменениях даже когда ты просто бегаешь по редактору и нажимаешь там всякие кнопки мыши, не прикасаясь к клавиатуре. И объект один и тот же.

Проверять по хэшу видимо неправильно, Хэш у модели меняется вообще по странным законам, далеко не при каждом изменении в редакторе. Он не так уж и страшно спамит, я бы оставил без проверок обновление, если не будет наблюдаться лагов при использовании этого гуи.

А так всё работает круто, кроме одного момента. Чтобы хоть что-то появилось, надо хоть какое-то сделать изменение в окне редактора.

from raox.

k-alexandrovsky avatar k-alexandrovsky commented on September 15, 2024

Хэш у модели меняется вообще по странным законам

Так изменение и не есть плохо, нам нужно отсечь варианты, когда изменения гарантированно не было. И когда мы увидим тот же хэш, просто // do nothing, как говорится. Хотя это уже к вопросу о преждевременных оптимизациях. Так что и правда пока не надо париться.

Чтобы хоть что-то появилось, надо хоть какое-то сделать изменение в окне редактора.

Тут да, единственное, когда нас ждут неприятности, это самый-самый запуск эклипса. Окно уже открыто, а мы только-только загрузились. Тут я предлагаю при старте делать единожды проверку

IEditorPart startingEditor = workbenchWindow.getActivePage().getActiveEditor();
if(startingEditor != null)
{
    System.out.println("Started with " + startingEditor + " opened!");
    if(startingEditor instanceof XtextEditor)
        System.out.println("\tXtext editor for " + ((XtextEditor)startingEditor).getLanguageName() + " language");
}
Started with org.eclipse.xtext.ui.editor.XtextEditor@216906a0 opened!
    Xtext editor for ru.bmstu.rk9.rdo.RDO language

from raox.

bogachev-pa avatar bogachev-pa commented on September 15, 2024

Так изменение и не есть плохо, нам нужно отсечь варианты, когда изменения гарантированно не было. И когда мы увидим тот же хэш, просто // do nothing, как говорится. Хотя это уже к вопросу о преждевременных оптимизациях. Так что и правда пока не надо париться.

Такая проверка будет выдавать false positives, т.е. хэш может не поменяться, даже когда модель поменялась.

Тут да, единственное, когда нас ждут неприятности, это самый-самый запуск эклипса. Окно уже открыто, а мы только-только загрузились. Тут я предлагаю при старте делать единожды проверку

Проблема в том, чтобы ресурс в этот момент получить.
Вот этот код:

IResource resource = ResourceUtil.getResource(((XtextEditor)partRef.getPart(true)).getEditorInput());

Возвращает ведь совсем не тот ресурс, что нам нужен. По крайней мере я не понял, как из него RDOModel вытащить.

from raox.

k-alexandrovsky avatar k-alexandrovsky commented on September 15, 2024

Такая проверка будет выдавать false positives

Ну шанс коллизий для объектов с непереопределенным hashCode() крайне мал, и если нас будут сильно спамить, и производительность будет страдать, то лучше уж 10^-50 шанс на необновленное дерево, все таки не космический корабль строим. Плюс, есть еще одно средство, хранить модель как объект, и сравнивать объекты. Тут минус в том, что у нас будет порой удвоенное потребление памяти за счет того, что мы храним объект, которому пока уже умирать. А может и не будет, все зависит от строгости GC.

По крайней мере я не понял, как из него RDOModel вытащить.

Тут же вроде как все просто. Потому что мы умеем делать XtextEditor => Resource

if(editor instanceof XtextEditor)
{
    IResource resource = ResourceUtil.getResource((XtextEditor)editor).getEditorInput());
    //   ^^^ уже то, что нам надо, остается только
    RDOModel hoorayItIsDefinitelyRDOModel = (RDOModel)resource.getContents().get(0);
}

from raox.

bogachev-pa avatar bogachev-pa commented on September 15, 2024

У меня возникли некоторые сомнения по системе sensitivityList.
Сейчас, насколько я понимаю, разные модули добавляют имена объектов, которые они хотят видеть сериализованными.
Теперь допустим модуль 1 добавил туда все ресурсы, а модуль 2 все результаты. Теперь в sensitivityList имеем и то, и другое.
Но теперь каждому модулю нужно понять, что его интересуют не все записи базы данных, а только те, что он сам добавил в sensitivityList, т.е. ему нужно продублировать эту информацию где-то у себя. В итоге получится, что все имена сериализуемых объектов хранятся дважды - в базе данных и в самом модуле.

Мне кажется это очень неудобно. Сейчас у нас есть только трассировка, так что это незаметно. Мало того, трассировщик сейчас вообще не хранит никаких данных о том, кого надо трассировать, у берет всё, что засериализовала база данных.
Вообще пока не очень понимаю, как трассировщику проверять, что это именно он хотел, а не кто-то другой.

С другой стороны, а кто еще, кроме TraceConfig сможешь настраивать sensitivity? Я так с лету не могу придумать.

Edit: немного путанно написал, но думаю, причины сомнений ясны.
Основной вопрос - нужно ли вообще кому-то кроме TraceConfig настраивать sensitivity?

from raox.

k-alexandrovsky avatar k-alexandrovsky commented on September 15, 2024

Мне кажется, что Database не должна знать ничего про своих клиентов. Ей в список кидают интересующие объекты, она их добавляет, и все это валится в sensitivityList, он быстрый и простой, будучи хэшсетом. А после завершения моделирования пусть клиенты копаются в базе данных сами. Частично эту задачу облегчают индексы.
С другой стороны, можно сделать много разных sensitivity листов, а каждому листу завести свой индекс. И потом по запросу эти индексы отдавать. Возможно, этот вариант лучше. Но непонятно что делать с графиками. Мы же хотим каждому ресурсу свой индекс, а что делать с временными, с другой стороны. Кого им во владельца листа писать.

from raox.

bogachev-pa avatar bogachev-pa commented on September 15, 2024

В целом задача решена. Для каких-то новых вопросов, я думаю, надо создавать отдельные ишью.

from raox.

Related Issues (20)

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.