Ситуация:
Есть два очень похожих компонента: превью статьи на главной странице, и сама статья, при переходе на "читать дальше". У компонента превью свой сервис, который тянет данные через http. В роутере, при переходе на полноую статью (другой компонент) указан компонент статьи, непосредственно. Вопрос:
Создавать копмоненту свой собственный сервис, который будет дублировать код сервиса превьюхи, либо же использовать один компонент, просто с отдельным шаблоном целой статьи (//не нашел, как юзать несколько шаблонов в одном компоненте), либо же ваш вариант. Интересует именно правильный подход с точки зрения angular way и TS.
Заранее благодарю.
Ответ
Для обоих компонентов можно сделать через один сервис
Есть главный поток(1) и из него вызывается побочный поток(2) Выглядит примерно так: Thread second_thread = new Thread(null, new Runnable() {
public void run() {
throws new Exception();
}
});
second_thread.start();
second_thread.join();
Как узнать из главного потока, что побочный поток завершился ошибкой?
Ответ
Классы Callable и Future как раз созданы чтобы решить эту проблему. Вопрос разрешен.
Здравствуйте. Дело в том, что я использую сокеты. И почти в одно и то же время, допустим, в 20 часов и 0 минут, у всех пользователей скрипт отправляет запрос на сокет сервер. Отправляя этот запрос, у меня есть цель: выполнить нужное мне событие (1.1) один раз, и вернуть всем результаты. Но у меня не совсем получается. Я делаю так: когда приходит запрос от пользователя я проверяю, был ли запрос раньше, и если не было, помечаю в базе, что запрос только что произошел. Дальше, если еще кто-то шлет запрос, то уже видно, что запрос уже произошел, и текущий клиент ждет выполнения нужного мне события (1.1). Проблема состоит в том, что иногда Node.JS не успевает выполнить запрос к базе, и за это время, пока идёт запрос, успевает "проскочить" несколько клиентов и нужно мне события (1.1) выполняется столько раз, сколько пользователей проскочило, плюс тот пользователь, что инициировал первый запрос. Как быть? Может есть какой-то алгоритм? Уже голову сломал.
Ответ
Как вариант, можно использовать именнованые локи MySQL SELECT GET_LOCK('lock_name', 60);
Документация
Есть шаблонная функция: template
auto exceptionWrapper (Object *obj, Function&& function, Args&& ...args)-> decltype((obj->*function)(std::forward(args)...))
{
try
{
QScopedPointer
Ответ
exceptionWrapper сам по себе не является функцией, но неким шаблоном функции, поэтому мы не можем никуда его передать — мы можем передавать лишь что-то конкретное, а не абстракцию, коей является шаблон. Таким образом, нам нужно конкретизировать (инстанциировать) exceptionWrapper прежде чем передавать его в QtConcurrent::run. Здесь встаёт другая проблема: с какими аргументами инстанциировать? Т.к. exceptionWrapper использует пробрасывающую ссылку (forwarding reference), идёт расчёт на то, что аргументы будут выводиться при вызове функции, но у нас ситуация иная — мы явно задаём аргументы шаблона. Конечно, мы всё равно получаем нужный результат таким вызовом: QtConcurrent::run(exceptionWrapper, obj, std::forward(query), std::forward(args)...);
Происходит это из-за того, что у нас в callAsync пробрасывающая ссылка, а в exceptionWrapper, в результате явной инстанциации, у нас rvalue-ссылка, и применяя правила C++ по свертке ссылок мы на выходе имеем то, что и ожидали: будет инстанциирована правильная, т.е. ожидаемая нами функция exceptionWrapper. К примеру, если мы рассмотрим минимальный пример, из Вашего дополненного вопроса, то при таком вызове: int var = 5;
callAsync(obj, &Object::sum, 7, var);
Будет сгенерирована функция exceptionWrapper с такой сигнатурой: int (Object *,int (Object::* )(int,int),int &&,int &) — как раз то, что и ожидалось. Но в этом кроется другая проблема. Мы работаем с конкурентной средой и пытаемся вызвать метод Qt, который потенциально выполнит наш метод в другом потоке. Но, чтобы выполнить метод в другом потоке, он вынужден скопировать (либо же переместить, если умеет) аргументы и сохранить их до того времени, когда можно будет вызвать нашу функцию. Сохраняя наши аргументы, Qt отбрасывает их изначальный тип и впоследствии, при передаче их в нашу функцию, все наши аргументы станут lvalue. Но в сигнатуре нашей функции есть int&&, который является rvalue-ссылкой и lvalue не может быть передано туда! Поэтому, нам придётся отказаться от пробрасывающих ссылок в exceptionWrapper — они там не нужны и только мешают, там нужен обычный const & В результате получим такое решение: template
auto fcn(Object *object, Function function, const Args& ...args)
{
return (object->*function)(args...);
} template
void callAsync(Object *object, Function&& function, Args&& ...args)
{
QtConcurrent::run(fcn, object, function,
std::forward(args)...);
}
Конечно, можно подумать и над альтернативными решениями, но этот ответ уже и так довольно длинный получился.
Изучаю С++ и пишу библиотеку ModBus. Прошу полезного совета у Гуру по изменению архитектуры в целом или ответить на конкретные вопросы в конце. Я хочу с помощью шаблонов классов автоматически помещать любые пользовательские данные в нужные таблицы данных ModBus с возвращением указателей на них. class AlarmData_b01
{
bool isAlarm;
bool isCountActivate;
}; class MeintenanceData_b01
{
bool isMeintenance;
bool isCountActivate;
}; class MeintenanceData_f32
{
unsigned short Id;
unsigned long Time;
float Rate;
}; AlarmData_b01 *AlarmData_b01_Alarm1_ptr = InputBits::Add();
AlarmData_b01 *AlarmData_b01_Alarm2_ptr = InputBits::Add(); MeintenanceData_b01 *AlarmData_b01_Meintenance1_ptr = InputBits::Add();
MeintenanceData_b01 *AlarmData_b01_Meintenance2_ptr = InputBits::Add(); MeintenanceData_f32 *AlarmData_f32_Meintenance1_ptr = InputRegs::Add();
MeintenanceData_f32 *AlarmData_f32_Meintenance2_ptr = InputRegs::Add();
Таким образом, для класса AlarmData создается свой класс, регистрирующий все объекты типа AlarmData. Тоже происходит и для класса MeintenanceData. Дискретные данные для аварий помещаются в таблицу дискретных данных, а данные 16 бит помещаются в таблицу регистров модбас. Так же с помощью статического метода шаблонного класса можно задать адрес для созданной области объектов в таблице ModBus. InputBits::AddresSet(100);
InputBits::AddresSet(110); InputRegs::AddresSet(100);
Таким образом будут формироваться таблицы данных, доступ к которым будет осуществляться из вне сторонним устройством по интерфейсу RS485 и протоколу ModBus с заданием адреса внутри посылки, указанного в моей программе с помощью AddresSet. В начале мной был создан базовый шаблон класса template
class ModBusTables
{
protected: static unsigned short Addres;
static unsigned short AreaSize;
T_DataType *AreaData_ptr; ModBusTables(); public: static void AddresSet(unsigned short ModBusAddres);
};
где static unsigned short Addres - Адрес области в таблице протокола Модбас
static unsigned short AreaSize - Размер объектов в области
T_DataType *AreaData_ptr - Тип для приведения указателя.
Так как в ModBus фактически существует только два типа данных: дискретные и ячейки по 16 бит, то в параметрах данного шаблона будет либо bool либо unsigned short. Таким образом AreaData_ptr - это указатель на тип данных конкретной таблицы ModBus, чтобы можно было путешествовать по любым данным пользователя с помощью единого указателя. Теперь приведу код шаблонного класса, который наследуется от одного из классов выше и расскажу в чем заключается вопрос. template class ModBusTable; template class TT_Table>
class ModBusTable > : public TT_Table
{
private: T_DataStruct AreaData; public: static T_DataStruct *Add()
{
ModBusTable *ModBusArea_ptr = new ModBusTable(); T_DataStruct *Instance_Ptr = &ModBusArea_ptr->AreaData; ModBusTable >::AreaSize = sizeof(ModBusArea_ptr->AreaData);
ModBusArea_ptr->AreaData_ptr = (T_DataType *)Instance_Ptr; return Instance_Ptr;
}
};
Главная задача данного шаблонного класса - создать свой объект в статическом методе, зарегистрировать его в классе и возвратить указатель на данные пользовательского типа, а так же преобразовать этот указатель в указатель AreaData_ptr объявленный в родительском классе, чтобы с любыми пользовательскими типами можно было работать через указатель на bool или unsigned short. Теперь сам вопрос. Для того, чтобы не вбивать много параметров в шаблон для регистрирования пользовательских данных в конкретной таблице ModBus, я применил наследование. template class InputBits: public ModBusTable > {};
template class InputRegs: public ModBusTable > {};
template class OutputBits: public ModBusTable > {};
template class OutputRegs: public ModBusTable > {};
Как логически объединить объекты классов InputBits и InputBits?
Объекты этих классов логически должны находится в одной таблице ModBus. Существует ли способ заменить наследование в данном случае на что-то похожее на alias template в С++11, чтобы создавать шаблон класса с новым именем InputBits по шаблону ModBusTable? Так, чтобы работало выражение InputBits::Add()
Приму любые советы по изменению архитектуры реализации данной задачи. Большое спасибо за прочтение, внимание и ответы!
Нужно нарисовать или любым иным способом провести линию от одного блока div к другому. Т.е. два элемента связать линией. Элементы генерируются динамически. Строится все это дело на основе уровней. Например, есть пользователь с уровнем 1. Он будет на самом верху. Дальше пользователи с уровнем 2, они ниже. Нужно их соединить любым способом, как на схеме.
Схематичный пример:
Как запретить ввод переменной меньше/больше заданного интервала?
Например:
Из динамического одмерного массива нужно удалить N элементов, начиная с номера K.
Ввод размера массива, n элементов и k вводится с клавиатуры.
Нужно чтобы n было не меньше и не больше size. Подскажите только, где об этом прочитать или кусочек кода, пожалуйста.
Ответ
Возможная последовательность действий такая:
Пользователь вводит число num
Проверяем число if (num ...
Если число удовлетворяет проверке идём дальше, если нет возвращаемся к шагу 1.
Код, обеспечивающий сам ввод, может быть совершенно разным и будет зависеть от того с какой системой вы работаете, в консоли или GUI, используете ли какие-то специфические библиотеки типа ncurses и т.д.