// SPDX-License-Identifier: MIT
#include "Circle.hh"
#include "Ellipse.hh"
#include "Shape.hh"
#include <dso/DSOLoader.hh>
#include <plugin/Plugin.hh>
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
using namespace std;
using namespace plugin;
using namespace plugin::example;
using namespace fedem::dso;
vector< unique_ptr< Shape > > objectList;
int main( )
{
DSOLoader::prefix( "lib"s );
// ----- Config-based creation demo -----
cout << "=== Config-based creation demo ===\n\n";
// Load plugins
try
{
DSOLoader::load( "./libCircle.so"s );
}
catch( exception& )
{
}
try
{
DSOLoader::load( "./libEllipse.so"s );
}
catch( exception& )
{
}
try
{
DSOLoader::load( "./libSquare.so"s );
}
catch( exception& )
{
}
// Circle with config
{
auto circle = Shape::create( "Circle", Circle::Config { 42 } );
if( circle )
{
cout << "Circle (config r=42): ";
circle->printOn( cout );
objectList.push_back( move( circle ) );
}
}
// Ellipse with config
{
auto ellipse = Shape::create( "Ellipse", Ellipse::Config { 10, 20 } );
if( ellipse )
{
cout << "Ellipse (config a=10 b=20): ";
ellipse->printOn( cout );
objectList.push_back( move( ellipse ) );
}
}
// Default construction (backward compatible)
{
auto circle = Shape::create( "Circle" );
if( circle )
{
circle->setSize( 7 );
cout << "Circle (default + setSize 7): ";
circle->printOn( cout );
objectList.push_back( move( circle ) );
}
}
// Square — registered with REGISTER (no config support)
{
auto square = Shape::create( "Square" );
if( square )
{
square->setSize( 15 );
cout << "Square (default + setSize 15): ";
square->printOn( cout );
objectList.push_back( move( square ) );
}
}
cout << "\n=== Interactive mode ===\n\n";
// ----- Interactive mode -----
do
{
cout << "Available addons:";
auto addons = Plugin< Shape >::catalog( ).names( true );
if( addons.empty( ) )
{
cout << " (none)\n";
}
else
{
for( auto const& name : addons )
cout << ' ' << name;
cout << '\n';
}
cout << "shape/command : ";
string cmd;
cin >> cmd;
if( ! cin || cmd == "exit" || cmd == "quit" || cmd == "q" )
break;
if( cmd == "list" )
{
for( auto const& shape : objectList )
{
shape->printOn( cout );
}
cout << '\n';
continue;
}
if( find( addons.cbegin( ), addons.cend( ), cmd ) == addons.cend( ) )
{
auto const dsoFilename = DSOLoader::prefix( ) + cmd + ".so"s;
bool loaded = false;
try
{
DSOLoader::load( "./"s + dsoFilename );
loaded = true;
}
catch( exception& )
{
}
if( ! loaded )
{
try
{
DSOLoader::load( dsoFilename );
loaded = true;
}
catch( exception& )
{
cerr << "Could not load DSO for '" << cmd << "'\n";
continue;
}
}
}
auto shape = Shape::create( cmd );
if( ! shape )
{
cout << '`' << cmd << "` could not be created!\n";
}
else
{
cout << "size : ";
unsigned int size;
cin >> size;
if( ! cin )
{
constexpr auto max_size = std::numeric_limits< std::streamsize >::max( );
cin.clear( ); // unset failbit
cin.ignore( max_size, '\n' ); // skip bad input
cout << "abort: unknow size!\n";
continue;
}
shape->setSize( size );
cout << "Size of shape is " << shape->getSize( ) << endl;
cout << *shape << '\n';
objectList.push_back( move( shape ) );
}
} while( true );
return EXIT_SUCCESS;
}