en un clic
scopy-architecture-knowledge
// Core Scopy architecture knowledge including plugin lifecycle, library dependencies, build system, and key design patterns. Loaded by clarify-task and design-task commands.
// Core Scopy architecture knowledge including plugin lifecycle, library dependencies, build system, and key design patterns. Loaded by clarify-task and design-task commands.
| name | scopy-architecture-knowledge |
| description | Core Scopy architecture knowledge including plugin lifecycle, library dependencies, build system, and key design patterns. Loaded by clarify-task and design-task commands. |
Plugins inherit from PluginBase (which implements Plugin interface). Required overrides:
bool compatible(QString param, QString category) override; // Device detection (MUST NOT alter state)
bool onConnect() override; // Setup when device connects
bool onDisconnect() override; // Cleanup when device disconnects
Full lifecycle sequence:
DeviceFactory::build(param, category) creates DeviceImplcompatible(param, category) on each plugin factory instanceclone() → preload() (NOT on UI thread)loadIcon() → loadPage() → loadConfigPage() → loadToolList() → loadPreferencesPage() → loadExtraButtons() → postload()onConnect() — enable tools, create instruments, register APIsonDisconnect() — cleanup, delete APIsPlugin class skeleton:
class MyPlugin : public QObject, PluginBase {
SCOPY_PLUGIN
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.adi.Scopy.PluginBase")
Q_INTERFACES(scopy::PluginBase)
public:
bool compatible(QString m_param, QString category) override;
void loadToolList() override;
bool loadIcon() override;
bool loadPage() override;
bool onConnect() override;
bool onDisconnect() override;
void initMetadata() override;
};
Build order and what each library provides:
| Library | Provides | Key Dependencies |
|---|---|---|
scopy-common | Shared utilities, base classes | Qt Core/Widgets |
scopyiioutil | IIO communication, PingTask, CyclicalTask | libiio, libserialport |
scopy-gui | Qt widgets, UI components, Style system | scopy-common, QWT, Boost |
scopy-gr-util | GNU Radio integration | scopy-iioutil, scopy-gui, Gnuradio libs, Genalyzer |
scopy-pluginbase | Plugin framework, MessageBroker, Preferences, ScopyJS | scopy-common, scopyiioutil |
scopy-iio-widgets | IIOWidgetBuilder, IIOWidget, IIOWidgetGroup | libiio, scopy-gui, scopyiioutil |
scopy-pkg-manager | Runtime package installation | — |
scopy-core | ScopyMainWindow, DeviceManager, PluginManager, DeviceFactory | all above, Python3, libsigrokdecode |
Each package lives under packages/<name>/ and contains:
packages/<name>/
├── manifest.json.cmakein # Package metadata (id, title, version, category)
├── CMakeLists.txt # Build config
├── plugins/ # One or more plugins
│ └── <plugin>/
│ ├── include/<plugin>/<plugin>plugin.h
│ ├── src/<plugin>plugin.cpp
│ ├── CMakeLists.txt
│ ├── resources/
│ ├── test/
│ └── doc/
└── emu-xml/ # Device emulation files
Build flags: ENABLE_PACKAGE_<NAME> (uppercase, dashes preserved). ENABLE_ALL_PACKAGES=ON enables all.
Tools are registered in loadToolList() using the macro:
#define SCOPY_NEW_TOOLMENUENTRY(id, name, icon)
// Creates: new ToolMenuEntry(id, name, icon, this->m_name, this->m_param, this)
Key properties: id, name, icon, visible, enabled, running, attached, detachable, runEnabled, runBtnVisible.
In onConnect(), each tool is enabled and given its widget:
toolList[i]->setEnabled(true);
toolList[i]->setTool(instrumentWidget);
// Subscribe
MessageBroker::GetInstance()->subscribe(this, "topic_name");
// Publish
MessageBroker::GetInstance()->publish("topic_name", "message_data");
// Receive in plugin
void messageCallback(QString topic, QString message) override;
All plugins auto-subscribe to "broadcast" topic. The broker stores QMap<QObject*, QSet<QString>> for subscriptions.
// Initialize with default
Preferences::init("plugin.setting_key", defaultValue);
// Read/Write
QVariant val = Preferences::get("plugin.setting_key");
Preferences::set("plugin.setting_key", newValue);
// React to changes
connect(Preferences::GetInstance(), &Preferences::preferenceChanged,
[](QString key, QVariant val) { /* handle */ });
File-backed via QSettings. Call save()/load() for persistence.
IIOWidgetBuilder builder(parentWidget);
auto widget = builder
.device(iio_device)
.channel(iio_channel)
.attribute("voltage")
.uiStrategy(IIOWidgetBuilder::RangeUi)
.compactMode(true)
.group(widgetGroup)
.buildSingle();
UI Strategies: EditableUi, ComboUi, SwitchUi, RangeUi, CheckBoxUi, TemperatureUi
Data Strategies: AttrData, TriggerData, DeviceAttrData, ContextAttrData
Priority: Channel > Device > Context (most specific wins).
CyclicalTask — periodic thread execution:
CyclicalTask *ct = new CyclicalTask(myThread, this);
ct->start(5000); // Execute every 5 seconds
ct->stop();
PingTask — device connectivity check (subclass and implement ping()):
class MyPingTask : public PingTask {
bool ping() override { /* return true if device alive */ }
};
// Signals: pingSuccess(), pingFailed(), connectionLost(), forceDisconnect()
// Single static method — creates DeviceImpl with all compatible plugins
DeviceImpl *device = DeviceFactory::build(param, category, parent);
class MyPluginApi : public ApiObject {
Q_OBJECT
friend class MyPlugin;
public:
Q_INVOKABLE QString getValue();
Q_INVOKABLE void setValue(const QString &val);
private:
MyPlugin *m_plugin = nullptr;
};
Register in onConnect(): ScopyJS::GetInstance()->registerApi(m_api)
Delete at start of onDisconnect(): delete m_api; m_api = nullptr;
Guidelines for using Context7, web search, and other research tools to find solutions outside the Scopy codebase. Loaded when the task involves unfamiliar technology or external libraries.
How Scopy libraries depend on each other, plugin commonalities, MessageBroker topics, shared widgets, style system flow, and build system relationships. Loaded when determining component interactions or change impact.
Decision trees for common Scopy architectural choices - plugin vs core, tool vs section, widget type selection, sync vs async, GNU Radio vs direct, package organization, and API exposure. Loaded when making design decisions.
Catalog of all Scopy development tools including package generator, testing tools, CI scripts, format/license scripts, and dev plugin commands. Loaded when analyzing what tools exist for a task.
Code patterns and examples for Scopy IIOWidget unit tests. Covers standard helpers, data-driven testing, and complex multi-step scenarios. Auto-loads when creating or reviewing `*_Unit_test.js` files.
Unit test validation rules for Scopy plugin IIOWidget tests. Auto-loads when reviewing or writing `*_Unit_test.js` files.