Задать вопрос
  • Как передавать много сообщений через Socket?

    maaGames
    @maaGames Автор вопроса
    Евгений Шатунов, > Или блокировать сокет на период записи пакета от прочих попыток записи.

    Если я правильно разобрался с библиотекой, там по умолчанию создаются блокируемые сокеты, а не блокируемые нужно созавать отдельным методом или вызывать функцию, чтобы сделать сокеты не блокируемыми. Т.е., пока не закончится запись в сокет, другой поток в этот сокет писать не сможет (плюс у меня функция записи обёрнута в мьютекс, чтобы уж наверняка - если это лишнее, потом удалю).
    Но, если я правильно понял, отправиться может как бльше, так и меньше байт, чем я пытаюсь передать. И я не понял, от чего это зависит и что мне с этим делать.
  • Как передавать много сообщений через Socket?

    maaGames
    @maaGames Автор вопроса
    tsarevfs Про логирование - спасибо. А можете что-то посоветовать для сравнения двух файлов по тайм кодам? Просто глазами два файла с тысячами строк смотреть и сихронизировать их по времени - немного неприятно.
  • Как передавать много сообщений через Socket?

    maaGames
    @maaGames Автор вопроса
    Код показать не могу, к сожалению :(

    Мне нужно как-то узнавать, что пришло новое сообщение (или событие, не знаю, какая терминология правильная), получать его идентификатор и, в зависимости от этого, считывать различный объём байт.
    Условно, отправляю три сообщения (идентификатор + данные):
    версия+номер ,
    название+текст ,
    тип_объекта+массив_байт_этого_объекта

    И на сервере я слушаю порт методом poll(), когда что-то прилетает, я считываю 4 байта идентификатора и в зависимости от него считываю различный объём байт. Размер считываемых байт в начале каждого блока данных записан, т.е. я знаю, сколько байт нужн осчитать.
    Вернее, после срабатывания poll я создаю SocketInputStream передавая тот же сокет, который ждал poll и уже из этого объекта считываю идентификатор и данные. И в итоге у меня получается, что объект SocketInputStream начинает считывать данные "со смещением", если можно так выразиться, в начале должно быть магическое число, но по факту там находятся данные предыдущего или следующего сообщения (сложно понять, тех или тех, но точно не случайный мусор).

    По идее, мутекс анлочится после fush. Но у меня нет уверенности, что сокет будет пересылать данные сразу при этом, а не будет ждать заполнения буфера до 1024 байт (по умолчанию там такой буфер указан) и/или закрытия сокета.
    {
        ScopeMutex mutex( mutex_object );
        SocketOutputStream sos(...);
        sos.write(...);
    }
  • Как передавать много сообщений через Socket?

    maaGames
    @maaGames Автор вопроса
    Race condition быть не может, потому что мьютекс не даёт. Т.е. до создания объекта SocketOutputStream ждётся анлок мьютекса. Анлок происходит после удаления SocketOutputStream. Но если где-то после этого уже возникает гонка (уже после вызовов write и удаления объекта поока), то я даже не представляю, как с этим бороться тогда...

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

    Обмен данными происходит на одном ПК, либо между компьютерами в локальной сети. Такой же объём данных без проблем передавался через очередь сообщений Windows (но большие данные передавались через файл), так что проблем с DoS быть не должно.

    Часто и много передаются только маленькие сообщения, их может быть несколько тысяч за несколько секунд, размером порядка десятков байт, но это включая "магические числа" для проверки правильности данных. Потом можно будет заняться оптимизацией размера, если потребность будет. Сейчас вопрос производительности и загрузки сети не сильно волнует.
  • Постфиксная запись на stack?

    maaGames
    @maaGames
    Данил, Кстати, да. Сайдэффектов лучше избегать. и оптипизирующий компилятор может сильно наоптимизирвоать не очевидных вещей (особенно когда перегрузка операторов испоьзуется, тогда вообще поведение становится не очевидным).
  • Можно ли в Google Play не показывать полный, реальный адрес, если продаешь приложение?

    maaGames
    @maaGames
    Kraken115, Кошелёк не при регистрации, это я немного ошибся. Если будешь AdSense подключать, то вот там нужно будет подтвердить личность при помощи пин-кода в бумажном письме. Я выводил деньги только с рекламы, с внутриировых покупок не выводил, так что не знаю, будут ли там какие-то дополнительные подтверждения. По идее, должны быть, т.к. Гугл за тебя выплачивает налоги (если я правильно помню условия пользовательского соглашения).
  • Почему работает разыменование пустого объекта?

    maaGames
    @maaGames
    Pashka23, Тем более! Само по себе название переменной намекает. В таких ситуациях говоришь: "в первую очередь инициализируем указатель нулём, а теперь давайте смотреть дальше..."
  • Может ли быть два базовых случая в рекурсии?

    maaGames
    @maaGames
    Ventus, В рекурсии есть условие выхода из рекурсии, видимо его подразумевали под "базовым случаем". Но это именно условие завершения рекурсии и этих условий может быть хоть сколько, но как минимум одно условие есть всегда, иначе получится "вечная" рекурсия, которая съест весь стэк и приложение упадёт :)
  • Какой спрайт лучше подобрать под временное закрытие прохода?

    maaGames
    @maaGames
    Одиночка Айс, Как я понял, автору не нужна бесшовная загрузка и он делает аналог "зашёл в комнату, закрылась дверь, прогрузился следующий уровень, открылась дверь в новую локацию", как это делалось в почти всех играх до недавнего времени. Так что в любом случае есть "точки склейки" локаций. Деалешь локации разделёнными чем-нибудь, чтобы были конкретные места соединения и пихаешь туда разводные мосты, открывающиеся проходы в скалах, пролетающее облачко, по которому можно перебраться на другую сторону, и т.д т.п.
    Бесшовную склейку тоже можно сделать "малой кровью", если между большими локациями содавать небольшие "склеивающие локации". Тогда в памяти нужно держать локацию, в которой находится игрок и все смежные с ней (или не все, а только те, к которым игрок ближе; локация не обязана быть четырёхугольной, смежных может быть хоть 20 штук). Переходишь в минилокацию - подгружаешь смежную мини-локацию. Переходишь в смежную мини-локацию, выгружаешь старую большую и загружаешь новую большую. Переходишь в новую большую и удаляешь старую мини-локацию. Но это я говорю о локациях типа 1000*1000 ячеек. Для 25*25 можно обойтись без мини-смежных и просто грузить соседние.
  • Как сделать, чтобы пользователь должен был удерживать палец на экране и перемещать вверх, вниз?

    maaGames
    @maaGames
    Отмечу, что это не троллинг, а именно так и реализуется - смотреть примеры аналогового управления через сенсорный экран.
  • Наследование. Каким образом вызывается operator=() через оператор разрешения контекста?

    maaGames
    @maaGames
    Egorithm, Внутри методов класса this-> всегда есть неявно, но можно указывать и явно, для более лучшего документирования кода. Или если имя аргумента метода совпадает с именем члена класса (но это уже проблемы именования).
    Суть такого написания в том, чтобы не копировать реализацию из базового класса в дочерний. Так что может визуально выглядит не очень красиво и понятно, но это лучше, чем дублирование кода. Это относится не только к оператору присваивние, а к абсолютно всем виртуальным функцям. По возможности нужно избегать дублирование кода (упрощает отладку и дальнейшую поддержку кода), а вот такой "странный" вызов сильно упрощает эту задачу.
  • Наследование. Каким образом вызывается operator=() через оператор разрешения контекста?

    maaGames
    @maaGames
    Egorithm, > С другой стороны, там написано, что это необходимо делать только если и базовый, и производный класс используют динамическое выделение памяти. Но я догадываюсь, что такое нужно делать просто при явном определении operator=().

    Подозреваю, что там речь идёт о необходимости самостоятельно писать operator=(), если ВНУТРИ объекта происходит динамическое выделение памяти, потом учто компилятор сам не может знать, как сравнивать объекты с указателями. Т.е. речь не о способе создания самого объекта, а о способе создания его членов.
    В любом случае, если создаёшь конструктор копирования - создаёшь оператор присваивания. Если создаёшь оператор присваивания - создавай и конструктор копирования.
  • Наследование. Каким образом вызывается operator=() через оператор разрешения контекста?

    maaGames
    @maaGames
    Egorithm, Это никак не связано с динамическим выделением памяти.
    class A
    {
        A(int);
    };
    
    class B
    {
       B( int b )
       :   A(b)
      {}
    };

    Например, вот. В конструкторе указывается конструктор базового класса. Примерно то же самое делается для методов. Условно выражаясь, происходит вызов метода через "this-родительского-класса" с отключенным полиморфизмом, т.е. вызовется именно метод базового класса, а не перегруженный метод.
    Есть и ещё более запутанные приёмы. Например:
    class A
    {
      virtual void func();
    };
    
    class B : public A
    {
      virtual void func();
    };
    
    class C : public B
    {
      virtual void func()
      {
         ... // какой-т код
    
        A::func();
    
        ... /// ещё какой-то код
      }
    };

    В методе func класса С вызывается реализация метода func из класса А, при этом реализация из класса B не вызывается.
  • Есть ли способ динамической загрузки библиотеки?

    maaGames
    @maaGames
    Евгений Иванович, Ну так используй кросплатформенный код работы с файловой системой. Скачать бибилотеку на диск - не проблема. Загрузить динамически библиотеку с диска - не проблема. Получить адрес функции в загруженнйо библиотеке - не проблема.
    Учитыая, что для работы с сетью всегда приходится использовать либо API конкретной системы, либо используя кросплатформенную обёртку (типа буста), то не понимаю, откуда взялась проблема работы с диском.
  • Эффективный алгоритм для двустороннего поиска?

    maaGames
    @maaGames
    laniminel, B-tree только на скорость поиска влияют, не на использование памяти (если не ошибаюсь, конечно). Раз в первую очередь акцент на эффективность, то нужно сбалансированное дерево строить, чтобы время поиска было log(N). В сортированном массиве тоже сложность поиска log(N) и 500 мегабайт это небольшой размер для современных компьютеров. Так что я бы протестировал и вариант с массивами. Там и служебной информации гораздо меньше. Получается, сейчас ~200 байт на узел дерева, а ведь в нём хранятся как минимум два указателя на дочерние узлы, может ещё указатель на родительский узел. Т.е. 3*8=24 байта служебный. Это 10% от занятой памяти. Так что с массивами вместо 450 будет 400. Хотя, между 400 и 450 никакой разницы в 2019 году.
  • Эффективный алгоритм для двустороннего поиска?

    maaGames
    @maaGames
    res2001, Вообще, пока не назван используемый язык, я что-то передумал говорить о производительности :) Мало ли, как там контейнеры в испльзуемом языке реализованы.
    По идее, индексированный доступ (вернее, прямой доступ по указателю) будет всегда быстрее косвенного доступа из дерева. Опять же, в зависимости от реализации, хранятся ли данные прям в узле дерева или в узле указатель на данные...
    В любом случае, я бы предпочёл два бинарных дерева.
  • Нужно ли учить графическую часть в winapi?

    maaGames
    @maaGames
    Ну ка, запили "Hello World!" на UWP для Windows 7 :)
  • Можно ли как-то ускорить публикацию в Play Market?

    maaGames
    @maaGames
    4DKZ, Сложна. Такое лучше спросить у тех.поддержки ГуглПлея.
  • Можно ли Встроить QT dialog в MFC CDialog?

    maaGames
    @maaGames Автор вопроса
    Adamos, Короче, короткий ответ: Нет, простым способом так встроить QT нельзя. :)
  • Можно ли Встроить QT dialog в MFC CDialog?

    maaGames
    @maaGames Автор вопроса
    Adamos, С тем же успехом я могу написать свою Виндоус, потому что мне не нравится MFC...
    Если я правильно догадываюсь, мне нужно будет из CDialog обрабатывать только функции изменения размера, перемещения, видимости и удаления. Если говорить очень грубо, то приложение не будет обращаться к диалогу, но из диалога будут меняться данные в документе.