Art-World

 view release on metacpan or  search on metacpan

lib/Art/World.pm  view on Meta::CPAN

  }

  role Active {
    method participate {
      say "That's interesting";
    }
  }

  role Buyer {

    requires money;

    multi method acquire ( Artwork $art ) {
      $self->pay( $art, $self );
      $art->change_owner( $self );
    }
  }

  # Dunno how but the fact of being collected should bump artist reputation
  role Collectionable {
    has owner (
      lazy    => true,
      is      => rw,
      clearer => true,
      writer  => 'set_owner',
      type    => ArrayRef[ Agent ]) = $self->creator;
    has value  ( is   => rw );
    has status (
      enum            => ['for_sale', 'sold'],
      # Create a delegated method for each value in the enumeration
      handles         => 1,
      default         => 'for_sale' );

    method $remove_from_seller_collection {
      my $meta = Art::World::Util->new_meta;
      # Removal of the to-be-sold Artwork in seller collection
      for my $owner ( $self->owner->@* ) {
        # Artists don't have a collection
        # Or maybe they can... So we should add a specific case
        if (  $meta->get_class( $owner ) !~ '^Art::World::Artist$' ) {
          while ( my ( $i, $art ) = each( $owner->collection->@* )) {
            # Removing if a matching artwork is found
            # Should be removed by id, but we don't manage that yet
            if ( $art->title =~ $self->title ) {
              # Wish I would use List::UtilsBy extract_by() for this
              splice $owner->collection->@*, $i, 1;
            }
          }
        }
      }
    }

    multi method change_owner ( Collector $buyer ) {

      # From seller collection
      $self->$remove_from_seller_collection;

      $self->clear_owner;
      $self->set_owner([ $buyer ]);
      push $buyer->collection->@*, $self;
      # TODO guess it should bump some people reputation and artwork aura now
    }

    multi method change_owner ( Coinvestor $buyers ) {

      # From Collector point of view
      $self->$remove_from_seller_collection;

      # From Artwork point of view
      $self->clear_owner;
      $self->set_owner( $buyers->members );
      push $buyers->collection->@*, $self;
      # TODO guess it should bump some people reputation and artwork aura now
    }
  }

  role Collective {

    has members! ( type => ArrayRef[ Agent ] );

    multi method acquire ( Artwork *art, Collective *collective ) {
      for my $member ( $arg->collective->members->@* ) {
        $member->pay( $arg->art, $arg->collective );
      }
      $arg->art->change_owner( $arg->collective );
    }
  }

  role Crud {
    has dbh! ( type => InstanceOf[ 'Art::World::Model' ], builder => true, lazy => true );
    has db!  ( type => HashRef[ Str ], builder => true, lazy => true );

    method insert ( Str $table, HashRef $attributes ) {
      # TODO IT MUST BE TESTED
      unless ( $self->does( 'Art::World::Unserializable' )) {
        try {
          my $row = $self->dbh->insert( ucfirst lc $table, $attributes);
        } catch {
          cluck 'You tried to insert to ' . $table . ' but this table doesn\'t exist';
        }
      }
    }

    method _build_dbh {
      use DBI;
      use Teng;
      use Teng::Schema::Loader;
      my $dbh = Teng::Schema::Loader->load(
        dbh       => DBI->connect(
          'dbi:' . $self->db->{ kind } .
          ':dbname=' . $self->db->{ name },
          '', '' ),
        namespace => __PACKAGE__ . '::Model'
       );
      return $dbh;
    }

    method _build_db {
      return {
        name => $self->config->{ DB }->{ NAME },
        kind => $self->config->{ DB }->{ KIND },
       };
    }
  }

  role Event {
    has place ( type => Place );
    has datetime ( type => InstanceOf['Time::Moment'] );
    # "guests"
    has participant ( type => ArrayRef[ Agent ] );
    has title ( type => Str, is => ro );
  }

lib/Art/World.pm  view on Meta::CPAN

  role Space {
    # Like a small space or a large space
    # Could limit the number of person coming during an event for example
    has space;
  }

  role Underground {
    method experiment {
      say "Underground";
    }
  }

  role Writing {
    method write ( Theory $concepts ) {}
  }

  class Art {

    has config (
      is => ro,
      lazy => true,
      default => sub { Config::Tiny->read( './art.conf' )}
    );

    # TODO an implemented project (Work, Exhibition) should inherit of this
    # TODO some stuff should extends this
    abstract class Concept {
      class Idea  with Abstraction {
        method express {
          say $self->discourse if $self->discourse;
        }
      }
      class Theory  with Abstraction { }
    }

    class Opening with Event, Fame {
      has treat ( type => ArrayRef[ Str ]);
      has smalltalk;

      # TODO must take as parameter what is served
      method serve {
        return $self->treat->@*;
      }
    }

    # TODO Guess this is more like an Agent method or role
    class Sex with Event;

    class Playground with Crud, Identity {

      class Magazine {

        has reader;
        has writer ( type => ArrayRef[ Agent ] );

        method publish {};
      }

      class Place with Fame, Invitation, Space {

        # Like, dunno, a city ? Could be in a Geo role I guess
        has location ( type => Str );

        class Institution with Market {
          class Gallery with Exhibit, Buyer {
            has artwork ( type => ArrayRef );
            has artist ( type => ArrayRef );
            has event ( type => ArrayRef );
            has owner;
          }

          class Museum with Exhibit, Buyer;

          class School {
            # TODO much underground
            has student  ( type => ArrayRef[ Agent ]);
            # TODO Should enforce a minimum reputation
            has teachers ( type => ArrayRef[ Agent ]);;
          }
        }

        class Squat with Underground;
        class Workshop;

      }

      class Website;

    }

    class Agent with Active, Crud, Fame, Identity {

      has relationship;
      has reputation ( is => rw, type => PositiveOrZeroNum ) = 0;
      # TODO it would improve a lot the networking

      # TODO Should be done during an event
      # TODO In case the networker is a Manager, the reputation bump
      # should be higher
      method networking( ArrayRef $people ) {

        $self->dbh;
        my $highest_reputation = max map { $_-> reputation } $people->@*;
        my $bump = $highest_reputation > 1 ?
          round( $highest_reputation * $self->config->{ FAME }->{ BUMP_COEFFICIENT } / 100) :
          $self->config->{ FAME }->{ DEFAULT_BUMP };
        for my $agent ( $people->@* ) {
          $agent->bump_fame( $bump );
        }

        if ( any { $_->does( 'Art::World::Manager' ) } $people->@* ) {
          my @managers = grep { $_->does( 'Art::World::Manager' )} $people->@*;
          my $highest_influence_manager    =  max map { $self } @managers;
          # Bump all the other persons with the Manager->influence thing
          # but not the Manager with the highest influence otherwise it would
          # increase it's own reputation
          my @all_the_other = grep { $_->id != $highest_influence_manager->id } $people->@*;
          for my $agent ( @all_the_other ) {
            # The influence() methode is only a way of bumping_fame() with a special bumper
            $agent->bump_fame( $highest_influence_manager->influence( $agent->reputation ));
          }



( run in 0.611 second using v1.01-cache-2.11-cpan-6fb7bf0f510 )