<commit_before>#[derive(Deserialize, Debug, Clone, PartialEq)]
pub struct Error<T>
{
	error_summary: String,
	error: T,
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
pub enum AlphaGetMetadataError
{
	#[serde(rename="path")]
	Path(LookupError),
	#[serde(rename="properties_error")]
	PropertiesError(LookUpPropertiesError),
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
pub enum RelocationError
{
	#[serde(rename="from_lookup")]
	FromLookup(LookupError),
	#[serde(rename="from_write")]
	FromWrite(WriteError),
	#[serde(rename="to")]
	To(WriteError),
	#[serde(rename="cant_copy_shared_folder")]
	CantCopySharedFolder,
	#[serde(rename="cant_nest_shared_folder")]
	CantNestSharedFolder,
	#[serde(rename="cant_move_folder_into_itself")]
	CantMoveFolderInfoItself,
	#[serde(rename="too_many_files")]
	TooManyFiles,
	#[serde(rename="duplicated_or_nested_paths")]
	DuplicatedOrNestedPaths,
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
pub enum WriteError
{
	#[serde(rename="malformed_path")]
	MalformedPath(Option<String>),
	#[serde(rename="conflict")]
	Conflict(WriteConflictError),
	#[serde(rename="no_write_permission")]
	NoWritePermission,
	#[serde(rename="insufficient_space")]
	InsufficientSpace,
	#[serde(rename="disallowed_name")]
	DisallowedName,
	#[serde(rename="team_folder")]
	TeamFolder,
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
pub enum WriteConflictError
{
	#[serde(rename="file")]
	File,
	#[serde(rename="folder")]
	Folder,
	#[serde(rename="file_ancestor")]
	FileAncestor,
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
pub enum RelocationBatchError
{
	#[serde(rename="from_lookup")]
	FromLookup(LookupError),
	#[serde(rename="from_write")]
	FromWrite(WriteError),
	#[serde(rename="to")]
	To(WriteError),
	#[serde(rename="cant_copy_shared_folder")]
	CantCopySharedFolder,
	#[serde(rename="cant_nest_shared_folder")]
	CantNestSharedFolder,
	#[serde(rename="too_many_files")]
	TooManyFiles,
	#[serde(rename="duplicated_or_nested_paths")]
	DuplicatedOrNestedPaths,
	#[serde(rename="too_many_write_operations")]
	TooManyWriteOperations,
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
pub enum PollError
{
	#[serde(rename="invalid_async_job_id")]
	InvalidAsyncJobId,
	#[serde(rename="internal_error")]
	InternalError
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
pub enum GetCopyReferenceError
{
	#[serde(rename="path")]
	Path{ path: LookupError},
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(tag=".tag")]
pub enum SaveCopyReferenceError
{
	#[serde(rename="path")]
	Path(WriteError),
	#[serde(rename="invalid_copy_reference")]
	InvalidCopyReference,
	#[serde(rename="no_permission")]
	NoPermission,
	#[serde(rename="not_found")]
	NotFound,
	#[serde(rename="too_many_files")]
	TooManyFiles,
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(tag=".tag")]
pub enum DownloadError
{
	#[serde(rename="path")]
	Path(LookupError)
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(tag=".tag")]
pub enum GetMetadataError
{
	#[serde(rename="path")]
	Path(LookupError),
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(tag=".tag")]
pub enum PreviewError
{
	#[serde(rename="path")]
	Path(LookupError),
	#[serde(rename="in_prpgress")]
	InProgress,
	#[serde(rename="unsupported_extension")]
	UnsupportedExtension,
	#[serde(rename="unsupported_content")]
	UnsupportedContent,
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(tag=".tag")]
pub enum GetTemporaryLinkError
{
	#[serde(rename="path")]
	Path(LookupError),
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(tag=".tag")]
pub enum ThumbnailError
{
	Path(LookupError),
	#[serde(rename="unsupported_extension")]
	UnsupportedExtension,
	#[serde(rename="unsupported_image")]
	UnsupportedImage,
	#[serde(rename="conversion_error")]
	ConversionError,
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(tag=".tag")]
pub enum ListFolderContinueError
{
	#[serde(rename="path")]
	Path(LookupError),
	#[serde(rename="reset")]
	Reset,
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(tag=".tag")]
pub enum ListFolderLongpollError
{
	#[serde(rename="reset")]
	Reset,
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(tag=".tag")]
pub enum ListRevisionsError
{
	#[serde(rename="path")]
	Path(LookupError),
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(tag=".tag")]
pub enum CreateFolderError
{
	#[serde(rename="path")]
	Path(WriteError),
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(tag=".tag")]
pub enum DeleteError
{
	#[serde(rename="path_lookup")]
	PathLookup(LookupError),
	#[serde(rename="path_write")]
	PathWrite(WriteError),
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
pub enum LookUpPropertiesError
{
	#[serde(rename="property_group_not_found")]
	PropertyGroupNotFound,
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(tag=".tag")]
pub enum ListFolderError
{
	#[serde(rename="path")]
	Path{ path: LookupError},
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(tag=".tag")]
pub enum LookupError
{
	#[serde(rename="malformed_path")]
	MalformedPath(Option<String>),
	#[serde(rename="not_found")]
	NotFound,
	#[serde(rename="not_file")]
	NotFile,
	#[serde(rename="not_folder")]
	NotFolder,
	#[serde(rename="restricted_content")]
	RestrictedContent,
	#[serde(rename="invalid_path_root")]
	InvalidPathRoot(PathRootError)
}

#[derive(Deserialize, Debug, Clone, Default, PartialEq)]
pub struct PathRootError
{
	pub path_root: Option<String>,
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(tag=".tag")]
pub enum RestoreError
{
	#[serde(rename="path_lookup")]
	PathLookup(LookupError),
	#[serde(rename="path_write")]
	PathWrite(WriteError),
	#[serde(rename="invalid_revision")]
	InvalidRevision,
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(tag=".tag")]
pub enum SaveUrlError
{
	#[serde(rename="path")]
	Path(WriteError),
	#[serde(rename="download_failed")]
	DownloadFailed,
	#[serde(rename="invalid_url")]
	InvalidUrl,
	#[serde(rename="not_found")]
	NotFound,
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(tag=".tag")]
pub enum SearchError
{
	#[serde(rename="path")]
	Path(LookupError),
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(tag=".tag")]
pub enum UploadError
{
	#[serde(rename="path")]
	Path(UploadWriteFailed),
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
pub struct UploadWriteFailed
{
	pub reason: WriteError,
	pub upload_session_id: String,
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
pub enum UploadSessionLookupError
{
	#[serde(rename="not_found")]
	NotFound,
	#[serde(rename="incorrect_offset")]
	IncorrectOffset(UploadSessionOffsetError),
	#[serde(rename="closed")]
	Closed,
	#[serde(rename="not_closed")]
	NotClosed,
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
pub struct UploadSessionOffsetError
{
	pub correct_offset: u64,
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
pub enum UploadSessionFinishError
{
	#[serde(rename="lookup_failed")]
	LookupFailed(UploadSessionLookupError),
	#[serde(rename="path")]
	Path(WriteError),
	#[serde(rename="too_many_shared_folder_targets")]
	TooManySharedFolderTargets,
	#[serde(rename="too_many_write_operations")]
	TooManyWriteOperations,
}
<commit_msg>more documentation<commit_after>#[derive(Deserialize, Debug, Clone, PartialEq)]
pub struct Error<T>
{
	error_summary: String,
	error: T,
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
pub enum AlphaGetMetadataError
{
	#[serde(rename="path")]
	Path(LookupError),
	#[serde(rename="properties_error")]
	PropertiesError(LookUpPropertiesError),
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
pub enum RelocationError
{
	#[serde(rename="from_lookup")]
	FromLookup(LookupError),
	#[serde(rename="from_write")]
	FromWrite(WriteError),
	#[serde(rename="to")]
	To(WriteError),
	/// Shared folders can't be copied.
	#[serde(rename="cant_copy_shared_folder")]
	CantCopySharedFolder,
	/// Your move operation would result in nested shared folders. This is not allowed.
	#[serde(rename="cant_nest_shared_folder")]
	CantNestSharedFolder,
	/// You cannot move a folder into itself.
	#[serde(rename="cant_move_folder_into_itself")]
	CantMoveFolderInfoItself,
	/// The operation would involve more than 10,000 files and folders.
	#[serde(rename="too_many_files")]
	TooManyFiles,
	/// There are duplicated/nested paths among RelocationArg.from_path and RelocationArg.to_path.
	#[serde(rename="duplicated_or_nested_paths")]
	DuplicatedOrNestedPaths,
	/// Your move operation would result in an ownership transfer.
	/// You may reissue the request with the field RelocationArg.allow_ownership_transfer to true.
	#[serde(rename="cant_transfer_ownership")]
	CantTransferOwnership,
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
pub enum WriteError
{
	/// This field is optional.
	#[serde(rename="malformed_path")]
	MalformedPath(Option<String>),
	/// Couldn't write to the target path because there was something in the way.
	#[serde(rename="conflict")]
	Conflict(WriteConflictError),
	/// The user doesn't have permissions to write to the target location.
	#[serde(rename="no_write_permission")]
	NoWritePermission,
	/// The user doesn't have enough available space (bytes) to write more data.
	#[serde(rename="insufficient_space")]
	InsufficientSpace,
	/// Dropbox will not save the file or folder because of its name.
	#[serde(rename="disallowed_name")]
	DisallowedName,
	/// This endpoint cannot modify or delete team folders.
	#[serde(rename="team_folder")]
	TeamFolder,
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
pub enum WriteConflictError
{
	/// There's a file in the way.
	#[serde(rename="file")]
	File,
	/// There's a folder in the way.
	#[serde(rename="folder")]
	Folder,
	/// There's a file at an ancestor path, so we couldn't create the required parent folders.
	#[serde(rename="file_ancestor")]
	FileAncestor,
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
pub enum RelocationBatchError
{
	#[serde(rename="from_lookup")]
	FromLookup(LookupError),
	#[serde(rename="from_write")]
	FromWrite(WriteError),
	#[serde(rename="to")]
	To(WriteError),
	/// Shared folders can't be copied.
	#[serde(rename="cant_copy_shared_folder")]
	CantCopySharedFolder,
	/// Your move operation would result in nested shared folders. This is not allowed.
	#[serde(rename="cant_nest_shared_folder")]
	CantNestSharedFolder,
	/// You cannot move a folder into itself.
	#[serde(rename="too_many_files")]
	TooManyFiles,
	/// The operation would involve more than 10,000 files and folders.
	#[serde(rename="duplicated_or_nested_paths")]
	DuplicatedOrNestedPaths,
	/// Your move operation would result in an ownership transfer.
	/// You may reissue the request with the field RelocationArg.allow_ownership_transfer to true.
	#[serde(rename="cant_transfer_ownership")]
	CantTransferOwnership,
	/// There are too many write operations in user's Dropbox. Please retry this request.
	#[serde(rename="too_many_write_operations ")]
	TooManyWriteOperations,
}

/// Error returned by methods for polling the status of asynchronous job.
/// This datatype comes from an imported namespace originally defined in the async namespace
#[derive(Deserialize, Debug, Clone, PartialEq)]
pub enum PollError
{
	/// The job ID is invalid.
	#[serde(rename="invalid_async_job_id")]
	InvalidAsyncJobId,
	/// Something went wrong with the job on Dropbox's end.
	/// You'll need to verify that the action you were taking succeeded,
	/// and if not, try again. This should happen very rarely.
	#[serde(rename="internal_error")]
	InternalError
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
pub enum GetCopyReferenceError
{
	#[serde(rename="path")]
	Path(LookupError),
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(tag=".tag")]
pub enum SaveCopyReferenceError
{
	#[serde(rename="path")]
	Path(WriteError),
	/// The copy reference is invalid.
	#[serde(rename="invalid_copy_reference")]
	InvalidCopyReference,
	/// You don't have permission to save the given copy reference.
	/// Please make sure this app is same app which created the copy reference and
	/// the source user is still linked to the app.
	#[serde(rename="no_permission")]
	NoPermission,
	/// The file referenced by the copy reference cannot be found.
	#[serde(rename="not_found")]
	NotFound,
	/// The operation would involve more than 10,000 files and folders.
	#[serde(rename="too_many_files")]
	TooManyFiles,
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(tag=".tag")]
pub enum DownloadError
{
	#[serde(rename="path")]
	Path(LookupError)
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(tag=".tag")]
pub enum GetMetadataError
{
	#[serde(rename="path")]
	Path(LookupError),
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(tag=".tag")]
pub enum PreviewError
{
	/// An error occurs when downloading metadata for the file.
	#[serde(rename="path")]
	Path(LookupError),
	/// This preview generation is still in progress and the file is not ready for preview yet.
	#[serde(rename="in_prpgress")]
	InProgress,
	/// The file extension is not supported preview generation.
	#[serde(rename="unsupported_extension")]
	UnsupportedExtension,
	/// The file content is not supported for preview generation.
	#[serde(rename="unsupported_content")]
	UnsupportedContent,
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(tag=".tag")]
pub enum GetTemporaryLinkError
{
	#[serde(rename="path")]
	Path(LookupError),
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(tag=".tag")]
pub enum ThumbnailError
{
	/// An error occurs when downloading metadata for the image.
	Path(LookupError),
	/// The file extension doesn't allow conversion to a thumbnail.
	#[serde(rename="unsupported_extension")]
	UnsupportedExtension,
	/// The image cannot be converted to a thumbnail.
	#[serde(rename="unsupported_image")]
	UnsupportedImage,
	/// An error occurs during thumbnail conversion.
	#[serde(rename="conversion_error")]
	ConversionError,
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(tag=".tag")]
pub enum ListFolderContinueError
{
	#[serde(rename="path")]
	Path(LookupError),
	/// Indicates that the cursor has been invalidated. Call list_folder to obtain a new cursor.
	#[serde(rename="reset")]
	Reset,
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(tag=".tag")]
pub enum ListFolderLongpollError
{
	/// Indicates that the cursor has been invalidated. Call list_folder to obtain a new cursor.
	#[serde(rename="reset")]
	Reset,
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(tag=".tag")]
pub enum ListRevisionsError
{
	#[serde(rename="path")]
	Path(LookupError),
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(tag=".tag")]
pub enum CreateFolderError
{
	#[serde(rename="path")]
	Path(WriteError),
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(tag=".tag")]
pub enum DeleteError
{
	#[serde(rename="path_lookup")]
	PathLookup(LookupError),
	#[serde(rename="path_write")]
	PathWrite(WriteError),
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
pub enum LookUpPropertiesError
{
	/// his property group does not exist for this file.
	#[serde(rename="property_group_not_found")]
	PropertyGroupNotFound,
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(tag=".tag")]
pub enum ListFolderError
{
	#[serde(rename="path")]
	Path{ path: LookupError},
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(tag=".tag")]
pub enum LookupError
{
	/// This field is optional.
	#[serde(rename="malformed_path")]
	MalformedPath(Option<String>),
	/// There is nothing at the given path.
	#[serde(rename="not_found")]
	NotFound,
	/// We were expecting a file, but the given path refers to something that isn't a file.
	#[serde(rename="not_file")]
	NotFile,
	/// We were expecting a folder, but the given path refers to something that isn't a folder.
	#[serde(rename="not_folder")]
	NotFolder,
	/// The file cannot be transferred because the content is restricted.
	/// For example, sometimes there are legal restrictions due to copyright claims.
	#[serde(rename="restricted_content")]
	RestrictedContent,
	// I have no idea where the heck I found this, but it seems it dosn't belong anywhere
	// so I commented it out.
	// #[serde(rename="invalid_path_root")]
	// InvalidPathRoot(PathRootError)
}

// #[derive(Deserialize, Debug, Clone, Default, PartialEq)]
// pub struct PathRootError
// {
// 	pub path_root: Option<String>,
// }

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(tag=".tag")]
pub enum RestoreError
{
	/// An error occurs when downloading metadata for the file.
	#[serde(rename="path_lookup")]
	PathLookup(LookupError),
	/// An error occurs when trying to restore the file to that path.
	#[serde(rename="path_write")]
	PathWrite(WriteError),
	/// The revision is invalid. It may point to a different file.
	#[serde(rename="invalid_revision")]
	InvalidRevision,
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(tag=".tag")]
pub enum SaveUrlError
{
	#[serde(rename="path")]
	Path(WriteError),
	/// Failed downloading the given URL.
	#[serde(rename="download_failed")]
	DownloadFailed,
	/// The given URL is invalid.
	#[serde(rename="invalid_url")]
	InvalidUrl,
	/// The file where the URL is saved to no longer exists.
	#[serde(rename="not_found")]
	NotFound,
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(tag=".tag")]
pub enum SearchError
{
	#[serde(rename="path")]
	Path(LookupError),
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
#[serde(tag=".tag")]
pub enum UploadError
{
	///Unable to save the uploaded contents to a file.
	#[serde(rename="path")]
	Path(UploadWriteFailed),
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
pub struct UploadWriteFailed
{
	/// The reason why the file couldn't be saved.
	pub reason: WriteError,
	/// The upload session ID; this may be used to retry the commit.
	pub upload_session_id: String,
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
pub enum UploadSessionLookupError
{
	/// The upload session ID was not found or has expired. Upload sessions are valid for 48 hours.
	#[serde(rename="not_found")]
	NotFound,
	/// The specified offset was incorrect.
	/// See the value for the correct offset.
	/// This error may occur when a previous request was received and processed successfully but
	/// the client did not receive the response, e.g. due to a network error.
	#[serde(rename="incorrect_offset")]
	IncorrectOffset(UploadSessionOffsetError),
	/// You are attempting to append data to an upload session that has alread been closed (i.e. committed).
	#[serde(rename="closed")]
	Closed,
	/// The session must be closed before calling upload_session/finish_batch.
	#[serde(rename="not_closed")]
	NotClosed,
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
pub struct UploadSessionOffsetError
{
	/// The offset up to which data has been collected.
	pub correct_offset: u64,
}

#[derive(Deserialize, Debug, Clone, PartialEq)]
pub enum UploadSessionFinishError
{
	/// The session arguments are incorrect; the value explains the reason.
	#[serde(rename="lookup_failed")]
	LookupFailed(UploadSessionLookupError),
	/// Unable to save the uploaded contents to a file.
	#[serde(rename="path")]
	Path(WriteError),
	/// The batch request commits files into too many different shared folders.
	/// Please limit your batch request to files contained in a single shared folder.
	#[serde(rename="too_many_shared_folder_targets")]
	TooManySharedFolderTargets,
	/// There are too many write operations happening in the user's Dropbox. You should retry uploading this file.
	#[serde(rename="too_many_write_operations")]
	TooManyWriteOperations,
}
<|endoftext|>


<commit_before>use cgmath;
use cgmath::EuclideanSpace;
use glutin::Event;
use gfx;
use {level, model, render};
use config::Settings;

pub struct Camera {
    pub loc: cgmath::Vector3<f32>,
    pub rot: cgmath::Quaternion<f32>,
    proj: cgmath::PerspectiveFov<f32>,
}

pub struct Follow {
    offset: cgmath::Vector3<f32>,
    move_speed: f32,
    rot_speed: cgmath::Rad<f32>,
}

impl Camera {
    pub fn get_view_proj(&self) -> cgmath::Matrix4<f32> {
        use cgmath::{Decomposed, Matrix4, Transform};
        let view = Decomposed {
            scale: 1.0,
            rot: self.rot,
            disp: self.loc,
        };
        let view_mx: Matrix4<f32> = view.inverse_transform().unwrap().into();
        let proj_mx: Matrix4<f32> = self.proj.into();
        proj_mx * view_mx
    }

    fn follow(&mut self, target: &cgmath::Point3<f32>, follow: &Follow) {
        //TODO
        self.loc = (target + follow.offset).to_vec();
    }
}

pub trait App<R: gfx::Resources> {
    fn update<I: Iterator<Item=Event>, F: gfx::Factory<R>>(&mut self, I, f32, &mut F) -> bool;
    fn draw<C: gfx::CommandBuffer<R>>(&mut self, &mut gfx::Encoder<R, C>);
}

#[derive(Eq, PartialEq)]
enum Control {
    Player,
    //Artificial,
}

struct Dynamo {
    thrust: f32,
    steer: cgmath::Rad<f32>,
}

impl Dynamo {
    fn step(&mut self, target: &Dynamo, delta: f32) {
        // thrust
        let (accel_fw, accel_back, deaccel) = (80.0, 40.0, 120.0);
        let time_stop = self.thrust.max(0.0) / deaccel;
        if target.thrust > self.thrust {
            self.thrust = (self.thrust + accel_fw * delta).min(target.thrust);
        }else if target.thrust >= 0.0 || time_stop >= delta {
            self.thrust = (self.thrust - deaccel * delta).max(target.thrust);
        }else {
            self.thrust = (self.thrust - deaccel * time_stop - accel_back * (delta - time_stop)).max(target.thrust);
        }
        // steer
        let steer_accel = 0.2;
        let angle = if target.steer > self.steer {
            (self.steer.s + steer_accel * delta).min(target.steer.s)
        }else {
            (self.steer.s - steer_accel * delta).max(target.steer.s)
        };
        self.steer = cgmath::Rad::new(angle);
    }
}

pub struct Agent<R: gfx::Resources> {
    control: Control,
    pub transform: cgmath::Decomposed<cgmath::Vector3<f32>, cgmath::Quaternion<f32>>,
    pub model: model::Model<R>,
    dynamo: Dynamo,
}

impl<R: gfx::Resources> Agent<R> {
    fn step(&mut self, delta: f32) {
        use cgmath::{Rotation, Rotation3};
        // move forward
        let wheel_rot = cgmath::Quaternion::from_axis_angle(cgmath::Vector3::unit_z(), -self.dynamo.steer);
        let forward_local = wheel_rot.rotate_vector(cgmath::Vector3::unit_y());
        let forward_world = self.transform.rot.rotate_vector(forward_local);
        self.transform.disp += forward_world * self.dynamo.thrust * delta;
        // rotate
        let rot_speed = 0.1;
        let rot_angle = cgmath::Rad::new(rot_speed * self.dynamo.thrust * self.dynamo.steer.s * delta);
        self.transform.rot = self.transform.rot * cgmath::Quaternion::from_axis_angle(cgmath::Vector3::unit_z(), -rot_angle);
    }
}

pub struct Game<R: gfx::Resources> {
    render: render::Render<R>,
    agents: Vec<Agent<R>>,
    cam: Camera,
    dyn_target: Dynamo,
}

impl<R: gfx::Resources> Game<R> {
    pub fn new<F: gfx::Factory<R>>(settings: &Settings,
           out_color: gfx::handle::RenderTargetView<R, render::ColorFormat>,
           out_depth: gfx::handle::DepthStencilView<R, render::DepthFormat>,
           factory: &mut F) -> Game<R>
    {
        use std::io::BufReader;
        use std::fs::File;

        info!("Loading world parameters");
        let config = settings.get_level();
        let lev = level::load(&config);
        let pal_data = level::load_palette(&settings.get_object_palette_path());

        let mut model_file = BufReader::new(File::open(
            settings.get_vehicle_model_path(&settings.game.vehicle)
        ).unwrap());
        let agent = Agent {
            control: Control::Player,
            transform: cgmath::Decomposed {
                scale: 1.0,
                disp: cgmath::vec3(0.0, 0.0, 40.0),
                rot: cgmath::One::one(),
            },
            model: model::load_m3d(&mut model_file, factory),
            dynamo: Dynamo {
                thrust: 0.0,
                steer: cgmath::Zero::zero(),
            },
        };

        Game {
            render: render::init(factory, out_color, out_depth, &lev, &pal_data),
            agents: vec![agent],
            cam: Camera {
                loc: cgmath::vec3(0.0, 0.0, 200.0),
                rot: cgmath::Quaternion::new(1.0, 0.0, 0.0, 0.0),
                proj: cgmath::PerspectiveFov {
                    fovy: cgmath::deg(45.0).into(),
                    aspect: settings.get_screen_aspect(),
                    near: 1.0,
                    far: 100000.0,
                },
            },
            dyn_target: Dynamo {
                thrust: 0.0,
                steer: cgmath::Zero::zero(),
            },
        }
    }

    fn _move_cam(&mut self, step: f32) {
        use cgmath::{InnerSpace, Rotation};
        let mut back = self.cam.rot.rotate_vector(cgmath::Vector3::unit_z());
        back.z = 0.0;
        self.cam.loc -= back.normalize() * step;
    }
}

impl<R: gfx::Resources> App<R> for Game<R> {
    fn update<I: Iterator<Item=Event>, F: gfx::Factory<R>>(&mut self, events: I, delta: f32, factory: &mut F) -> bool {
        use cgmath::Rotation3;
        use glutin::VirtualKeyCode as Key;
        use glutin::ElementState::*;

        let angle = cgmath::rad(delta * 2.0);
        //let step = delta * 400.0;
        for event in events {
            match event {
                Event::KeyboardInput(_, _, Some(Key::Escape)) |
                Event::Closed => return false,
                Event::KeyboardInput(_, _, Some(Key::L)) => self.render.reload(factory),
                Event::KeyboardInput(_, _, Some(Key::R)) =>
                    self.cam.rot = self.cam.rot * cgmath::Quaternion::from_axis_angle(cgmath::Vector3::unit_x(), angle),
                Event::KeyboardInput(_, _, Some(Key::F)) =>
                    self.cam.rot = self.cam.rot * cgmath::Quaternion::from_axis_angle(cgmath::Vector3::unit_x(), -angle),
                Event::KeyboardInput(Pressed, _, Some(Key::W)) => self.dyn_target.thrust = 100.0,
                Event::KeyboardInput(Pressed, _, Some(Key::S)) => self.dyn_target.thrust = -40.0,
                Event::KeyboardInput(Released, _, Some(Key::W)) | Event::KeyboardInput(Released, _, Some(Key::S)) =>
                    self.dyn_target.thrust = 0.0,
                Event::KeyboardInput(Pressed, _, Some(Key::A)) => self.dyn_target.steer = cgmath::Rad::new(-0.2),
                Event::KeyboardInput(Pressed, _, Some(Key::D)) => self.dyn_target.steer = cgmath::Rad::new(0.2),
                Event::KeyboardInput(Released, _, Some(Key::A)) | Event::KeyboardInput(Released, _, Some(Key::D)) =>
                    self.dyn_target.steer = cgmath::Rad::new(0.0),
                /*
                Event::KeyboardInput(_, _, Some(Key::W)) => self.move_cam(step),
                Event::KeyboardInput(_, _, Some(Key::S)) => self.move_cam(-step),
                Event::KeyboardInput(_, _, Some(Key::A)) =>
                    self.cam.rot = cgmath::Quaternion::from_axis_angle(cgmath::Vector3::unit_z(), angle) * self.cam.rot,
                Event::KeyboardInput(_, _, Some(Key::D)) =>
                    self.cam.rot = cgmath::Quaternion::from_axis_angle(cgmath::Vector3::unit_z(), -angle) * self.cam.rot,
                */
                _ => {},
            }
        }

        if let Some(p) = self.agents.iter_mut().find(|a| a.control == Control::Player) {
            p.dynamo.step(&self.dyn_target, delta);
            let target = cgmath::Point3::from_vec(p.transform.disp);
            self.cam.follow(&target, &Follow {
                offset: cgmath::vec3(0.0, -100.0, 50.0),
                move_speed: 5.0,
                rot_speed: cgmath::Rad::new(0.1),
            });
        }

        for a in self.agents.iter_mut() {
            a.step(delta);
        }

        true
    }

    fn draw<C: gfx::CommandBuffer<R>>(&mut self, enc: &mut gfx::Encoder<R, C>) {
        self.render.draw(enc, &self.agents, &self.cam);
    }
}

pub struct ModelView<R: gfx::Resources> {
    model: model::Model<R>,
    transform: cgmath::Decomposed<cgmath::Vector3<f32>, cgmath::Quaternion<f32>>,
    pso: gfx::PipelineState<R, render::object::Meta>,
    data: render::object::Data<R>,
    cam: Camera,
}

impl<R: gfx::Resources> ModelView<R> {
    pub fn new<F: gfx::Factory<R>>(path: &str, settings: &Settings,
               out_color: gfx::handle::RenderTargetView<R, render::ColorFormat>,
               out_depth: gfx::handle::DepthStencilView<R, render::DepthFormat>,
               factory: &mut F) -> ModelView<R>
    {
        use std::io::BufReader;
        use gfx::traits::FactoryExt;

        let pal_data = level::load_palette(&settings.get_object_palette_path());

        info!("Loading model {}", path);
        let mut file = BufReader::new(settings.open(path));
        let model = model::load_m3d(&mut file, factory);
        let data = render::object::Data {
            vbuf: model.body.buffer.clone(),
            locals: factory.create_constant_buffer(1),
            ctable: render::Render::create_color_table(factory),
            palette: render::Render::create_palette(&pal_data, factory),
            out_color: out_color,
            out_depth: out_depth,
        };

        ModelView {
            model: model,
            transform: cgmath::Decomposed {
                scale: 1.0,
                disp: cgmath::Vector3::unit_z(),
                rot: cgmath::One::one(),
            },
            pso: render::Render::create_object_pso(factory),
            data: data,
            cam: Camera {
                loc: cgmath::vec3(0.0, -40.0, 20.0),
                rot: cgmath::Rotation3::from_axis_angle(cgmath::Vector3::unit_x(), cgmath::Angle::turn_div_6()),
                proj: cgmath::PerspectiveFov {
                    fovy: cgmath::deg(45.0).into(),
                    aspect: settings.get_screen_aspect(),
                    near: 1.0,
                    far: 100.0,
                },
            },
        }
    }

    fn rotate(&mut self, angle: cgmath::Rad<f32>) {
        use cgmath::Transform;
        let other = cgmath::Decomposed {
            scale: 1.0,
            rot: cgmath::Rotation3::from_axis_angle(cgmath::Vector3::unit_z(), angle),
            disp: cgmath::Zero::zero(),
        };
        self.transform = other.concat(&self.transform);
    }
}

impl<R: gfx::Resources> App<R> for ModelView<R> {
    fn update<I: Iterator<Item=Event>, F: gfx::Factory<R>>(&mut self, events: I, delta: f32, factory: &mut F) -> bool {
        use glutin::VirtualKeyCode as Key;
        let angle = cgmath::rad(delta * 2.0);
        for event in events {
            match event {
                Event::KeyboardInput(_, _, Some(Key::Escape)) |
                Event::Closed => return false,
                Event::KeyboardInput(_, _, Some(Key::A)) => self.rotate(-angle),
                Event::KeyboardInput(_, _, Some(Key::D)) => self.rotate(angle),
                Event::KeyboardInput(_, _, Some(Key::L)) =>
                    self.pso = render::Render::create_object_pso(factory),
                _ => {}, //TODO
            }
        }
        true
    }

    fn draw<C: gfx::CommandBuffer<R>>(&mut self, enc: &mut gfx::Encoder<R, C>) {
        let model_trans: cgmath::Matrix4<f32> = self.transform.into();
        let locals = render::ObjectLocals {
            m_mvp: (self.cam.get_view_proj() * model_trans).into(),
        };
        enc.update_constant_buffer(&self.data.locals, &locals);
        enc.clear(&self.data.out_color, [0.1, 0.2, 0.3, 1.0]);
        enc.clear_depth(&self.data.out_depth, 1.0);
        enc.draw(&self.model.body.slice, &self.pso, &self.data);
    }
}
<commit_msg>Real follow cam<commit_after>use cgmath;
use glutin::Event;
use gfx;
use {level, model, render};
use config::Settings;

pub type Transform = cgmath::Decomposed<cgmath::Vector3<f32>, cgmath::Quaternion<f32>>;

pub struct Camera {
    pub loc: cgmath::Vector3<f32>,
    pub rot: cgmath::Quaternion<f32>,
    proj: cgmath::PerspectiveFov<f32>,
}

pub struct Follow {
    transform: Transform,
    move_speed: f32,
    rot_speed: cgmath::Rad<f32>,
}

impl Camera {
    pub fn get_view_proj(&self) -> cgmath::Matrix4<f32> {
        use cgmath::{Decomposed, Matrix4, Transform};
        let view = Decomposed {
            scale: 1.0,
            rot: self.rot,
            disp: self.loc,
        };
        let view_mx: Matrix4<f32> = view.inverse_transform().unwrap().into();
        let proj_mx: Matrix4<f32> = self.proj.into();
        proj_mx * view_mx
    }

    fn follow(&mut self, target: &Transform, follow: &Follow) {
        use cgmath::Transform;
        let result = target.concat(&follow.transform);
        //TODO
        self.loc = result.disp;
        self.rot = result.rot;
    }
}

pub trait App<R: gfx::Resources> {
    fn update<I: Iterator<Item=Event>, F: gfx::Factory<R>>(&mut self, I, f32, &mut F) -> bool;
    fn draw<C: gfx::CommandBuffer<R>>(&mut self, &mut gfx::Encoder<R, C>);
}

#[derive(Eq, PartialEq)]
enum Control {
    Player,
    //Artificial,
}

struct Dynamo {
    thrust: f32,
    steer: cgmath::Rad<f32>,
}

impl Dynamo {
    fn step(&mut self, target: &Dynamo, delta: f32) {
        // thrust
        let (accel_fw, accel_back, deaccel) = (80.0, 40.0, 120.0);
        let time_stop = self.thrust.max(0.0) / deaccel;
        if target.thrust > self.thrust {
            self.thrust = (self.thrust + accel_fw * delta).min(target.thrust);
        }else if target.thrust >= 0.0 || time_stop >= delta {
            self.thrust = (self.thrust - deaccel * delta).max(target.thrust);
        }else {
            self.thrust = (self.thrust - deaccel * time_stop - accel_back * (delta - time_stop)).max(target.thrust);
        }
        // steer
        let steer_accel = 0.2;
        let angle = if target.steer > self.steer {
            (self.steer.s + steer_accel * delta).min(target.steer.s)
        }else {
            (self.steer.s - steer_accel * delta).max(target.steer.s)
        };
        self.steer = cgmath::Rad::new(angle);
    }
}

pub struct Agent<R: gfx::Resources> {
    control: Control,
    pub transform: Transform,
    pub model: model::Model<R>,
    dynamo: Dynamo,
}

impl<R: gfx::Resources> Agent<R> {
    fn step(&mut self, delta: f32) {
        use cgmath::{Rotation, Rotation3};
        // move forward
        let wheel_rot = cgmath::Quaternion::from_axis_angle(cgmath::Vector3::unit_z(), -self.dynamo.steer);
        let forward_local = wheel_rot.rotate_vector(cgmath::Vector3::unit_y());
        let forward_world = self.transform.rot.rotate_vector(forward_local);
        self.transform.disp += forward_world * self.dynamo.thrust * delta;
        // rotate
        let rot_speed = 0.1;
        let rot_angle = cgmath::Rad::new(rot_speed * self.dynamo.thrust * self.dynamo.steer.s * delta);
        self.transform.rot = self.transform.rot * cgmath::Quaternion::from_axis_angle(cgmath::Vector3::unit_z(), -rot_angle);
    }
}

pub struct Game<R: gfx::Resources> {
    render: render::Render<R>,
    agents: Vec<Agent<R>>,
    cam: Camera,
    dyn_target: Dynamo,
}

impl<R: gfx::Resources> Game<R> {
    pub fn new<F: gfx::Factory<R>>(settings: &Settings,
           out_color: gfx::handle::RenderTargetView<R, render::ColorFormat>,
           out_depth: gfx::handle::DepthStencilView<R, render::DepthFormat>,
           factory: &mut F) -> Game<R>
    {
        use std::io::BufReader;
        use std::fs::File;

        info!("Loading world parameters");
        let config = settings.get_level();
        let lev = level::load(&config);
        let pal_data = level::load_palette(&settings.get_object_palette_path());

        let mut model_file = BufReader::new(File::open(
            settings.get_vehicle_model_path(&settings.game.vehicle)
        ).unwrap());
        let agent = Agent {
            control: Control::Player,
            transform: cgmath::Decomposed {
                scale: 1.0,
                disp: cgmath::vec3(0.0, 0.0, 40.0),
                rot: cgmath::One::one(),
            },
            model: model::load_m3d(&mut model_file, factory),
            dynamo: Dynamo {
                thrust: 0.0,
                steer: cgmath::Zero::zero(),
            },
        };

        Game {
            render: render::init(factory, out_color, out_depth, &lev, &pal_data),
            agents: vec![agent],
            cam: Camera {
                loc: cgmath::vec3(0.0, 0.0, 200.0),
                rot: cgmath::Quaternion::new(1.0, 0.0, 0.0, 0.0),
                proj: cgmath::PerspectiveFov {
                    fovy: cgmath::deg(45.0).into(),
                    aspect: settings.get_screen_aspect(),
                    near: 10.0,
                    far: 10000.0,
                },
            },
            dyn_target: Dynamo {
                thrust: 0.0,
                steer: cgmath::Zero::zero(),
            },
        }
    }

    fn _move_cam(&mut self, step: f32) {
        use cgmath::{InnerSpace, Rotation};
        let mut back = self.cam.rot.rotate_vector(cgmath::Vector3::unit_z());
        back.z = 0.0;
        self.cam.loc -= back.normalize() * step;
    }
}

impl<R: gfx::Resources> App<R> for Game<R> {
    fn update<I: Iterator<Item=Event>, F: gfx::Factory<R>>(&mut self, events: I, delta: f32, factory: &mut F) -> bool {
        use cgmath::Rotation3;
        use glutin::VirtualKeyCode as Key;
        use glutin::ElementState::*;

        let angle = cgmath::rad(delta * 2.0);
        //let step = delta * 400.0;
        for event in events {
            match event {
                Event::KeyboardInput(Pressed, _, Some(Key::Escape)) |
                Event::Closed => return false,
                Event::KeyboardInput(Pressed, _, Some(Key::L)) => self.render.reload(factory),
                /*
                Event::KeyboardInput(_, _, Some(Key::R)) =>
                    self.cam.rot = self.cam.rot * cgmath::Quaternion::from_axis_angle(cgmath::Vector3::unit_x(), angle),
                Event::KeyboardInput(_, _, Some(Key::F)) =>
                    self.cam.rot = self.cam.rot * cgmath::Quaternion::from_axis_angle(cgmath::Vector3::unit_x(), -angle),
                */
                Event::KeyboardInput(Pressed, _, Some(Key::W)) => self.dyn_target.thrust = 100.0,
                Event::KeyboardInput(Pressed, _, Some(Key::S)) => self.dyn_target.thrust = -40.0,
                Event::KeyboardInput(Released, _, Some(Key::W)) | Event::KeyboardInput(Released, _, Some(Key::S)) =>
                    self.dyn_target.thrust = 0.0,
                Event::KeyboardInput(Pressed, _, Some(Key::A)) => self.dyn_target.steer = cgmath::Rad::new(-0.2),
                Event::KeyboardInput(Pressed, _, Some(Key::D)) => self.dyn_target.steer = cgmath::Rad::new(0.2),
                Event::KeyboardInput(Released, _, Some(Key::A)) | Event::KeyboardInput(Released, _, Some(Key::D)) =>
                    self.dyn_target.steer = cgmath::Rad::new(0.0),
                /*
                Event::KeyboardInput(_, _, Some(Key::W)) => self.move_cam(step),
                Event::KeyboardInput(_, _, Some(Key::S)) => self.move_cam(-step),
                Event::KeyboardInput(_, _, Some(Key::A)) =>
                    self.cam.rot = cgmath::Quaternion::from_axis_angle(cgmath::Vector3::unit_z(), angle) * self.cam.rot,
                Event::KeyboardInput(_, _, Some(Key::D)) =>
                    self.cam.rot = cgmath::Quaternion::from_axis_angle(cgmath::Vector3::unit_z(), -angle) * self.cam.rot,
                */
                _ => {},
            }
        }

        if let Some(p) = self.agents.iter_mut().find(|a| a.control == Control::Player) {
            p.dynamo.step(&self.dyn_target, delta);
            self.cam.follow(&p.transform, &Follow {
                transform: cgmath::Decomposed {
                    disp: cgmath::vec3(0.0, -100.0, 50.0),
                    rot: cgmath::Rotation3::from_axis_angle(cgmath::Vector3::unit_x(), cgmath::Angle::turn_div_6()),
                    scale: 1.0,
                },
                move_speed: 5.0,
                rot_speed: cgmath::Rad::new(0.1),
            });
        }

        for a in self.agents.iter_mut() {
            a.step(delta);
        }

        true
    }

    fn draw<C: gfx::CommandBuffer<R>>(&mut self, enc: &mut gfx::Encoder<R, C>) {
        self.render.draw(enc, &self.agents, &self.cam);
    }
}

pub struct ModelView<R: gfx::Resources> {
    model: model::Model<R>,
    transform: Transform,
    pso: gfx::PipelineState<R, render::object::Meta>,
    data: render::object::Data<R>,
    cam: Camera,
}

impl<R: gfx::Resources> ModelView<R> {
    pub fn new<F: gfx::Factory<R>>(path: &str, settings: &Settings,
               out_color: gfx::handle::RenderTargetView<R, render::ColorFormat>,
               out_depth: gfx::handle::DepthStencilView<R, render::DepthFormat>,
               factory: &mut F) -> ModelView<R>
    {
        use std::io::BufReader;
        use gfx::traits::FactoryExt;

        let pal_data = level::load_palette(&settings.get_object_palette_path());

        info!("Loading model {}", path);
        let mut file = BufReader::new(settings.open(path));
        let model = model::load_m3d(&mut file, factory);
        let data = render::object::Data {
            vbuf: model.body.buffer.clone(),
            locals: factory.create_constant_buffer(1),
            ctable: render::Render::create_color_table(factory),
            palette: render::Render::create_palette(&pal_data, factory),
            out_color: out_color,
            out_depth: out_depth,
        };

        ModelView {
            model: model,
            transform: cgmath::Decomposed {
                scale: 1.0,
                disp: cgmath::Vector3::unit_z(),
                rot: cgmath::One::one(),
            },
            pso: render::Render::create_object_pso(factory),
            data: data,
            cam: Camera {
                loc: cgmath::vec3(0.0, -40.0, 20.0),
                rot: cgmath::Rotation3::from_axis_angle(cgmath::Vector3::unit_x(), cgmath::Angle::turn_div_6()),
                proj: cgmath::PerspectiveFov {
                    fovy: cgmath::deg(45.0).into(),
                    aspect: settings.get_screen_aspect(),
                    near: 1.0,
                    far: 100.0,
                },
            },
        }
    }

    fn rotate(&mut self, angle: cgmath::Rad<f32>) {
        use cgmath::Transform;
        let other = cgmath::Decomposed {
            scale: 1.0,
            rot: cgmath::Rotation3::from_axis_angle(cgmath::Vector3::unit_z(), angle),
            disp: cgmath::Zero::zero(),
        };
        self.transform = other.concat(&self.transform);
    }
}

impl<R: gfx::Resources> App<R> for ModelView<R> {
    fn update<I: Iterator<Item=Event>, F: gfx::Factory<R>>(&mut self, events: I, delta: f32, factory: &mut F) -> bool {
        use glutin::VirtualKeyCode as Key;
        let angle = cgmath::rad(delta * 2.0);
        for event in events {
            match event {
                Event::KeyboardInput(_, _, Some(Key::Escape)) |
                Event::Closed => return false,
                Event::KeyboardInput(_, _, Some(Key::A)) => self.rotate(-angle),
                Event::KeyboardInput(_, _, Some(Key::D)) => self.rotate(angle),
                Event::KeyboardInput(_, _, Some(Key::L)) =>
                    self.pso = render::Render::create_object_pso(factory),
                _ => {}, //TODO
            }
        }
        true
    }

    fn draw<C: gfx::CommandBuffer<R>>(&mut self, enc: &mut gfx::Encoder<R, C>) {
        let model_trans: cgmath::Matrix4<f32> = self.transform.into();
        let locals = render::ObjectLocals {
            m_mvp: (self.cam.get_view_proj() * model_trans).into(),
        };
        enc.update_constant_buffer(&self.data.locals, &locals);
        enc.clear(&self.data.out_color, [0.1, 0.2, 0.3, 1.0]);
        enc.clear_depth(&self.data.out_depth, 1.0);
        enc.draw(&self.model.body.slice, &self.pso, &self.data);
    }
}
<|endoftext|>


<commit_before>use std::ascii::AsciiExt;
use std::borrow::Cow;
use std::collections::HashMap;
use std::path::*;
use std::string::String;

use case::*;

pub fn split_namespace_name(name: &str) -> (Option<&str>, &str) {
    let mut parts = name.split('.');
    let name = parts.next_back().unwrap();
    let ns = parts.next_back();
    assert!(ns.is_none() || parts.next().is_none());
    (ns, name)
}

pub fn strip_prefix<'a>(prefix: &str, name: &'a str) -> &'a str {
    let mut skip = 0;
    let mut prefix_upper = prefix.to_ascii_uppercase();
    prefix_upper.push('_');
    if name.starts_with(&prefix_upper) {
        skip = prefix_upper.len();
    }
    else if name.starts_with(prefix) {
        skip = prefix.len();
    }
    &name[skip..]
}

/* unused :(
pub fn strip_suffix<'a>(name: &'a str, suffix: &str) -> Option<&'a str> {
    if name.ends_with(suffix) {
        Some(&name[..name.len() - suffix.len()])
    }
    else {
        None
    }
}
*/

pub fn file_name(full_name: &str) -> String {
    let (_, class_name) = split_namespace_name(full_name);
    let mut name = PathBuf::from(module_name(class_name));
    let added = name.set_extension("rs");
    assert!(added);
    name.to_str().unwrap().into()
}

pub fn file_name_sys(name: &str) -> String {
    let mut path = PathBuf::from("src").join(name);
    let added = path.set_extension("rs");
    assert!(added);
    path.to_str().unwrap().into()
}

pub fn crate_name(name: &str) -> String {
    let name = name.to_snake();
    if name.starts_with("g_") {
        format!("g{}", &name[2..])
    }
    else {
        name
    }
}

pub fn module_name(name: &str) -> String {
    name.to_snake()
}

pub fn mangle_keywords<'a, S: Into<Cow<'a, str>>>(name: S) -> Cow<'a, str> {
    let name = name.into();
    if let Some(s) = KEYWORDS.get(&*name) {
        s[..].into()
    }
    else {
        name
    }
}

lazy_static! {
    static ref KEYWORDS: HashMap<&'static str, String> = {
        let mut map = HashMap::new();
        [
            "abstract", "alignof", "as", "become", "box", "break", "const",
            "continue", "crate", "do", "else", "enum", "extern", "false", "final",
            "fn", "for", "if", "impl", "in", "let", "loop", "macro", "match", "mod",
            "move", "mut", "offsetof", "override", "priv", "proc", "pub", "pure",
            "ref", "return", "Self", "self", "sizeof", "static", "struct", "super",
            "trait", "true", "type", "typeof", "unsafe", "unsized", "use", "virtual",
            "where", "while", "yield",
        ].iter().map(|k| map.insert(*k, format!("{}_", k))).count();
        map
    };
}

#[cfg(test)]
mod tests {
    use std::path::*;
    use super::*;

    #[test]
    fn split_no_namespace() {
        let (ns, name) = split_namespace_name("GObject");
        assert_eq!(ns, None);
        assert_eq!(name, "GObject");
    }

    #[test]
    fn split_full_name() {
        let (ns, name) = split_namespace_name("Gtk.StatusIcon");
        assert_eq!(ns, Some("Gtk"));
        assert_eq!(name, "StatusIcon");
    }

    #[test]
    fn strip_prefix_g() {
        assert_eq!(strip_prefix("G", "GBusType"), "BusType");
        assert_eq!(strip_prefix("G", "G_BUS_TYPE_NONE"), "BUS_TYPE_NONE");
    }

    #[test]
    fn strip_prefix_gtk() {
        assert_eq!(strip_prefix("Gtk", "GtkAlign"), "Align");
        assert_eq!(strip_prefix("Gtk", "GTK_ALIGN_FILL"), "ALIGN_FILL");
    }

    #[test]
    fn crate_name_works() {
        assert_eq!(crate_name("GdkPixbuf"), "gdk_pixbuf");
        assert_eq!(crate_name("GLib"), "glib");
        assert_eq!(crate_name("Gtk"), "gtk");
    }

    #[test]
    fn file_name_works() {
        assert_eq!(file_name("Gtk.StatusIcon"), "status_icon.rs");
    }

    #[test]
    fn file_name_sys_works() {
        let expected: String = PathBuf::from("src").join("funcs.rs")
            .to_str().unwrap().into();
        assert_eq!(file_name_sys("funcs"), expected);
    }
}
<commit_msg>nameutil: strip_prefix is unused now<commit_after>use std::borrow::Cow;
use std::collections::HashMap;
use std::path::*;
use std::string::String;

use case::*;

pub fn split_namespace_name(name: &str) -> (Option<&str>, &str) {
    let mut parts = name.split('.');
    let name = parts.next_back().unwrap();
    let ns = parts.next_back();
    assert!(ns.is_none() || parts.next().is_none());
    (ns, name)
}

/* unused :(
pub fn strip_prefix<'a>(prefix: &str, name: &'a str) -> &'a str {
    let mut skip = 0;
    let mut prefix_upper = prefix.to_ascii_uppercase();
    prefix_upper.push('_');
    if name.starts_with(&prefix_upper) {
        skip = prefix_upper.len();
    }
    else if name.starts_with(prefix) {
        skip = prefix.len();
    }
    &name[skip..]
}

pub fn strip_suffix<'a>(name: &'a str, suffix: &str) -> Option<&'a str> {
    if name.ends_with(suffix) {
        Some(&name[..name.len() - suffix.len()])
    }
    else {
        None
    }
}
*/

pub fn file_name(full_name: &str) -> String {
    let (_, class_name) = split_namespace_name(full_name);
    let mut name = PathBuf::from(module_name(class_name));
    let added = name.set_extension("rs");
    assert!(added);
    name.to_str().unwrap().into()
}

pub fn file_name_sys(name: &str) -> String {
    let mut path = PathBuf::from("src").join(name);
    let added = path.set_extension("rs");
    assert!(added);
    path.to_str().unwrap().into()
}

pub fn crate_name(name: &str) -> String {
    let name = name.to_snake();
    if name.starts_with("g_") {
        format!("g{}", &name[2..])
    }
    else {
        name
    }
}

pub fn module_name(name: &str) -> String {
    name.to_snake()
}

pub fn mangle_keywords<'a, S: Into<Cow<'a, str>>>(name: S) -> Cow<'a, str> {
    let name = name.into();
    if let Some(s) = KEYWORDS.get(&*name) {
        s[..].into()
    }
    else {
        name
    }
}

lazy_static! {
    static ref KEYWORDS: HashMap<&'static str, String> = {
        let mut map = HashMap::new();
        [
            "abstract", "alignof", "as", "become", "box", "break", "const",
            "continue", "crate", "do", "else", "enum", "extern", "false", "final",
            "fn", "for", "if", "impl", "in", "let", "loop", "macro", "match", "mod",
            "move", "mut", "offsetof", "override", "priv", "proc", "pub", "pure",
            "ref", "return", "Self", "self", "sizeof", "static", "struct", "super",
            "trait", "true", "type", "typeof", "unsafe", "unsized", "use", "virtual",
            "where", "while", "yield",
        ].iter().map(|k| map.insert(*k, format!("{}_", k))).count();
        map
    };
}

#[cfg(test)]
mod tests {
    use std::path::*;
    use super::*;

    #[test]
    fn split_no_namespace() {
        let (ns, name) = split_namespace_name("GObject");
        assert_eq!(ns, None);
        assert_eq!(name, "GObject");
    }

    #[test]
    fn split_full_name() {
        let (ns, name) = split_namespace_name("Gtk.StatusIcon");
        assert_eq!(ns, Some("Gtk"));
        assert_eq!(name, "StatusIcon");
    }

    /*
    #[test]
    fn strip_prefix_g() {
        assert_eq!(strip_prefix("G", "GBusType"), "BusType");
        assert_eq!(strip_prefix("G", "G_BUS_TYPE_NONE"), "BUS_TYPE_NONE");
    }

    #[test]
    fn strip_prefix_gtk() {
        assert_eq!(strip_prefix("Gtk", "GtkAlign"), "Align");
        assert_eq!(strip_prefix("Gtk", "GTK_ALIGN_FILL"), "ALIGN_FILL");
    }
    */

    #[test]
    fn crate_name_works() {
        assert_eq!(crate_name("GdkPixbuf"), "gdk_pixbuf");
        assert_eq!(crate_name("GLib"), "glib");
        assert_eq!(crate_name("Gtk"), "gtk");
    }

    #[test]
    fn file_name_works() {
        assert_eq!(file_name("Gtk.StatusIcon"), "status_icon.rs");
    }

    #[test]
    fn file_name_sys_works() {
        let expected: String = PathBuf::from("src").join("funcs.rs")
            .to_str().unwrap().into();
        assert_eq!(file_name_sys("funcs"), expected);
    }
}
<|endoftext|>


<commit_before>extern crate spaceapi_server;

use std::net::Ipv4Addr;
use std::net::TcpStream;
use std::io::ErrorKind;

use spaceapi_server::SpaceapiServer;
use spaceapi_server::api;
use spaceapi_server::api::optional::Optional;

/// Create a new status object containing test data.
fn get_status() -> api::Status {
    api::Status::new(
        "ourspace",
        "https://example.com/logo.png",
        "https://example.com/",
        api::Location {
            address: Optional::Value("Street 1, Zürich, Switzerland".into()),
            lat: 47.123,
            lon: 8.88,
        },
        api::Contact {
            irc: Optional::Absent,
            twitter: Optional::Absent,
            foursquare: Optional::Absent,
            email: Optional::Value("hi@example.com".into()),
        },
        vec![
            "email".into(),
            "twitter".into(),
        ],
    )
}

/// Create a new SpaceapiServer instance listening on the specified port.
fn get_server(ip: Ipv4Addr, port: u16, status: api::Status) -> SpaceapiServer {
    // Start and return a server instance
    SpaceapiServer::new(ip, port, status, "redis://127.0.0.1/", vec![]).unwrap()
}

#[test]
fn server_starts() {
    //! Test that the spaceapi server starts at all.

    // Ip / port for test server
    let ip = Ipv4Addr::new(127, 0, 0, 1);
    let port = 3344;

    // Test data
    let status = get_status();

    // Connection to port should fail right now
    let connect_result = TcpStream::connect((ip, port));
    assert!(connect_result.is_err());
    assert_eq!(connect_result.unwrap_err().kind(), ErrorKind::ConnectionRefused);

    // Instantiate and start server
    let server = get_server(ip, port, status);
    let mut listening = server.serve().unwrap();

    // Connecting to server should work now
    let connect_result = TcpStream::connect((ip, port));
    assert!(connect_result.is_ok());

    // Close server
    listening.close().unwrap();
}
<commit_msg>Fix failing unittest<commit_after>extern crate spaceapi_server;

use std::net::Ipv4Addr;
use std::net::TcpStream;
use std::io::ErrorKind;

use spaceapi_server::SpaceapiServer;
use spaceapi_server::api;
use spaceapi_server::api::optional::Optional;

/// Create a new status object containing test data.
fn get_status() -> api::Status {
    api::Status::new(
        "ourspace",
        "https://example.com/logo.png",
        "https://example.com/",
        api::Location {
            address: Optional::Value("Street 1, Zürich, Switzerland".into()),
            lat: 47.123,
            lon: 8.88,
        },
        api::Contact {
            irc: Optional::Absent,
            twitter: Optional::Absent,
            foursquare: Optional::Absent,
            email: Optional::Value("hi@example.com".into()),
        },
        vec![
            "email".into(),
            "twitter".into(),
        ],
    )
}

/// Create a new SpaceapiServer instance listening on the specified port.
fn get_server(ip: Ipv4Addr, port: u16, status: api::Status) -> SpaceapiServer {
    // Start and return a server instance
    SpaceapiServer::new((ip, port), status, "redis://127.0.0.1/", vec![]).unwrap()
}

#[test]
fn server_starts() {
    //! Test that the spaceapi server starts at all.

    // Ip / port for test server
    let ip = Ipv4Addr::new(127, 0, 0, 1);
    let port = 3344;

    // Test data
    let status = get_status();

    // Connection to port should fail right now
    let connect_result = TcpStream::connect((ip, port));
    assert!(connect_result.is_err());
    assert_eq!(connect_result.unwrap_err().kind(), ErrorKind::ConnectionRefused);

    // Instantiate and start server
    let server = get_server(ip, port, status);
    let mut listening = server.serve().unwrap();

    // Connecting to server should work now
    let connect_result = TcpStream::connect((ip, port));
    assert!(connect_result.is_ok());

    // Close server
    listening.close().unwrap();
}
<|endoftext|>


<commit_before>extern crate clap;
extern crate dent;
extern crate term_size;

use clap::{App, Arg};
use dent::plot;
use dent::summary::Summary;
use dent::t_test::{SigLevel, TTest, welch_t_test};

use std::fs::File;
use std::path::Path;
use std::io::{self, BufRead, BufReader};

fn print_summary(s: &Summary) {
    println!("N\tMin\tMax\tMedian\tMean\tStdDev\tStdErr");
    println!(
        "{}\t{:0.2}\t{:0.2}\t{:0.2}\t{:0.2}\t{:0.2}\t{:0.2}",
        s.size(),
        s.min(),
        s.max(),
        s.median(),
        s.mean(),
        s.standard_deviation(),
        s.standard_error(),
    );
}

fn print_t_test(t_test: &TTest) {
    println!("T\tDF\tAlpha\tCrit\tRejectNull");
    println!(
        "{:0.3}\t{}\t{:0.3}\t{:0.3}\t{}",
        t_test.t,
        t_test.df,
        t_test.alpha,
        t_test.crit,
        t_test.reject,
    );
}

fn summarize_file(path: &str, lax_parsing: bool) -> Summary {
    let p = Path::new(path);
    let f = File::open(p).unwrap();
    let reader = BufReader::new(f);

    let data = read_data(reader, lax_parsing);

    Summary::new(&data).unwrap()
}

fn read_data<R>(reader: R, lax_parsing: bool) -> Vec<f64> where R: BufRead {
    let mut data: Vec<f64> = vec![];

    for l in reader.lines() {
        let s = l.unwrap().trim().to_string();

        if s.is_empty() {
            continue;
        }

        match s.parse() {
            Ok(d) => data.push(d),
            err => if !lax_parsing { err.unwrap(); }
        }
    }

    data
}

fn parse_alpha(arg: &str) -> SigLevel {
    match arg {
        ".001" => SigLevel::Alpha001,
        ".005" => SigLevel::Alpha005,
        ".01"  => SigLevel::Alpha010,
        ".025" => SigLevel::Alpha025,
        ".05"  => SigLevel::Alpha050,
        ".1"   => SigLevel::Alpha100,
        _ => panic!(),
    }
}

fn summarize_stdin(lax_parsing: bool) -> Summary {
    let stdin = io::stdin();
    let data = read_data(stdin.lock(), lax_parsing);

    Summary::new(&data).unwrap()
}

fn display_summary(summary: &Summary, draw_plot: bool, width: usize, ascii: bool) {
    if draw_plot {
        println!("{}\n", plot::summary_plot(&summary, width, ascii));
    }

    print_summary(&summary);
}

fn t_test_files(
    file1: &str,
    file2: &str,
    alpha: SigLevel,
    draw_plot: bool,
    width: usize,
    ascii: bool,
    lax_parsing: bool,
) {
    let s1 = summarize_file(file1, lax_parsing);
    let s2 = summarize_file(file2, lax_parsing);

    let t_test = welch_t_test(&s1, &s2, alpha);

    if draw_plot {
        println!("{}\n", plot::comparison_plot(&[&s1, &s2], width, ascii, true));
    }

    print_summary(&s1);
    println!();
    print_summary(&s2);
    println!();
    print_t_test(&t_test);
}

fn main() {
    let matches = App::new("dent")
        .version("0.3.0")
        .author("Joe Ranweiler <joe@lemma.co>")
        .about("A tiny tool for t-tests &c.")
        .arg(Arg::with_name("stdin")
             .short("s")
             .long("stdin")
             .help("Read and summarize data from stdin"))
        .arg(Arg::with_name("files")
             .multiple(true)
             .value_name("FILES")
             .takes_value(true)
             .required_unless("stdin")
             .help("Path to one or more files of sample data"))
        .arg(Arg::with_name("alpha")
             .short("a")
             .long("alpha")
             .value_name("ALPHA")
             .help("Significance level α")
             .takes_value(true)
             .default_value(".05"))
        .arg(Arg::with_name("lax")
             .long("lax")
             .help("Ignore non-numeric input lines"))
        .arg(Arg::with_name("plot")
             .short("p")
             .long("plot")
             .help("Print standard boxplots"))
        .arg(Arg::with_name("ascii")
             .long("ascii")
             .help("Use only ASCII characters in boxplots"))
        .arg(Arg::with_name("width")
             .short("w")
             .long("width")
             .value_name("WIDTH")
             .takes_value(true)
             .help("Width of boxplot"))
        .get_matches();

    let ascii = matches.is_present("ascii");
    let lax_parsing = matches.is_present("lax");
    let draw_plot = matches.is_present("plot");
    let use_stdin = matches.is_present("stdin");

    let width = matches
        .value_of("width")
        .and_then(|w| w.parse::<usize>().ok())
        .or(term_size::dimensions().map(|(w, _)| w))
        .unwrap_or(80);

    if use_stdin {
        let s = summarize_stdin(lax_parsing);
        display_summary(&s, draw_plot, width, ascii);
    } else {
        let alpha = parse_alpha(matches.value_of("alpha").unwrap());
        let files: Vec<_> = matches.values_of("files").unwrap().collect();

        match files.len() {
            0 => unreachable!(),
            1 => {
                let s = summarize_file(files[0], lax_parsing);
                display_summary(&s, draw_plot, width, ascii);
            },
            2 => {
                t_test_files(
                    files[0],
                    files[1],
                    alpha,
                    draw_plot,
                    width,
                    ascii,
                    lax_parsing,
                );
            }
            _ => {
                let summaries: Vec<Summary> = files
                    .iter()
                    .map(|f| summarize_file(f, lax_parsing))
                    .collect();

                if draw_plot {
                    let summary_refs: Vec<&Summary> = summaries
                        .iter()
                        .collect();

                    let plot = plot::comparison_plot(&summary_refs, width, ascii, true);
                    println!("{}\n", plot);
                }

                for i in 0..summaries.len() {
                    if i > 0 {
                        println!();
                    }
                    print_summary(&summaries[i]);
                }
            },
        };
    }
}
<commit_msg>Summarize data, then plot<commit_after>extern crate clap;
extern crate dent;
extern crate term_size;

use clap::{App, Arg};
use dent::plot;
use dent::summary::Summary;
use dent::t_test::{SigLevel, TTest, welch_t_test};

use std::fs::File;
use std::path::Path;
use std::io::{self, BufRead, BufReader};

fn print_summary(s: &Summary) {
    println!("N\tMin\tMax\tMedian\tMean\tStdDev\tStdErr");
    println!(
        "{}\t{:0.2}\t{:0.2}\t{:0.2}\t{:0.2}\t{:0.2}\t{:0.2}",
        s.size(),
        s.min(),
        s.max(),
        s.median(),
        s.mean(),
        s.standard_deviation(),
        s.standard_error(),
    );
}

fn print_t_test(t_test: &TTest) {
    println!("T\tDF\tAlpha\tCrit\tRejectNull");
    println!(
        "{:0.3}\t{}\t{:0.3}\t{:0.3}\t{}",
        t_test.t,
        t_test.df,
        t_test.alpha,
        t_test.crit,
        t_test.reject,
    );
}

fn summarize_file(path: &str, lax_parsing: bool) -> Summary {
    let p = Path::new(path);
    let f = File::open(p).unwrap();
    let reader = BufReader::new(f);

    let data = read_data(reader, lax_parsing);

    Summary::new(&data).unwrap()
}

fn read_data<R>(reader: R, lax_parsing: bool) -> Vec<f64> where R: BufRead {
    let mut data: Vec<f64> = vec![];

    for l in reader.lines() {
        let s = l.unwrap().trim().to_string();

        if s.is_empty() {
            continue;
        }

        match s.parse() {
            Ok(d) => data.push(d),
            err => if !lax_parsing { err.unwrap(); }
        }
    }

    data
}

fn parse_alpha(arg: &str) -> SigLevel {
    match arg {
        ".001" => SigLevel::Alpha001,
        ".005" => SigLevel::Alpha005,
        ".01"  => SigLevel::Alpha010,
        ".025" => SigLevel::Alpha025,
        ".05"  => SigLevel::Alpha050,
        ".1"   => SigLevel::Alpha100,
        _ => panic!(),
    }
}

fn summarize_stdin(lax_parsing: bool) -> Summary {
    let stdin = io::stdin();
    let data = read_data(stdin.lock(), lax_parsing);

    Summary::new(&data).unwrap()
}

fn display_t_test(
    summary1: &Summary,
    summary2: &Summary,
    alpha: SigLevel,
    draw_plot: bool,
    width: usize,
    ascii: bool,
) {
    let t_test = welch_t_test(&summary1, &summary2, alpha);

    if draw_plot {
        let p = plot::comparison_plot(&[&summary1, &summary2], width, ascii, true);
        println!("{}\n", p);
    }

    print_summary(&summary1);
    println!();
    print_summary(&summary2);
    println!();
    print_t_test(&t_test);
}

fn main() {
    let matches = App::new("dent")
        .version("0.3.0")
        .author("Joe Ranweiler <joe@lemma.co>")
        .about("A tiny tool for t-tests &c.")
        .arg(Arg::with_name("stdin")
             .short("s")
             .long("stdin")
             .help("Read and summarize data from stdin"))
        .arg(Arg::with_name("files")
             .multiple(true)
             .value_name("FILES")
             .takes_value(true)
             .required_unless("stdin")
             .help("Path to one or more files of sample data"))
        .arg(Arg::with_name("alpha")
             .short("a")
             .long("alpha")
             .value_name("ALPHA")
             .help("Significance level α")
             .takes_value(true)
             .default_value(".05"))
        .arg(Arg::with_name("lax")
             .long("lax")
             .help("Ignore non-numeric input lines"))
        .arg(Arg::with_name("plot")
             .short("p")
             .long("plot")
             .help("Print standard boxplots"))
        .arg(Arg::with_name("ascii")
             .long("ascii")
             .help("Use only ASCII characters in boxplots"))
        .arg(Arg::with_name("width")
             .short("w")
             .long("width")
             .value_name("WIDTH")
             .takes_value(true)
             .help("Width of boxplot"))
        .get_matches();

    let ascii = matches.is_present("ascii");
    let lax_parsing = matches.is_present("lax");
    let draw_plot = matches.is_present("plot");
    let use_stdin = matches.is_present("stdin");

    let width = matches
        .value_of("width")
        .and_then(|w| w.parse::<usize>().ok())
        .or(term_size::dimensions().map(|(w, _)| w))
        .unwrap_or(80);

    let summaries = if use_stdin {
        vec![summarize_stdin(lax_parsing)]
    } else {
        matches.values_of("files").unwrap()
            .map(|f| summarize_file(f, lax_parsing))
            .collect()
    };

    match summaries.len() {
        0 => unreachable!(),
        2 => {
            let alpha = parse_alpha(matches.value_of("alpha").unwrap());

            display_t_test(
                &summaries[0],
                &summaries[1],
                alpha,
                draw_plot,
                width,
                ascii,
            );
        }
        _ => {
            if draw_plot {
                let summary_refs: Vec<&Summary> = summaries
                    .iter()
                    .collect();

                let plot = plot::comparison_plot(&summary_refs, width, ascii, true);
                println!("{}\n", plot);
            }

            for i in 0..summaries.len() {
                if i > 0 {
                    println!();
                }
                print_summary(&summaries[i]);
            }
        },
    };
}
<|endoftext|>


<commit_before>#[macro_use(implement_uniforms)]
extern crate erya;
#[macro_use(implement_vertex)]
extern crate glium;
extern crate cgmath;

use glium::glutin::Event;
use glium::{ Surface, Frame };
use cgmath::{ Matrix4, Rotation3, Rad, Quaternion, Angle };
use erya::shader;
use erya::{ Renderer, Renderable, Display, Mesh, Camera3D, Camera,
            Timer, Transform, Model };

#[derive(Copy, Clone)]
struct Vertex
{
    position: [f32; 2],
    color: [f32; 3],
}

implement_vertex! { Vertex, position, color }

struct Uniforms
{
    mat: [[f32; 4]; 4],
}

implement_uniforms! { Uniforms, mat }

struct Shader;

impl shader::ShaderType for Shader
{
    type Vertex = Vertex;
    type Uniforms = Uniforms;

    fn vertex() -> &'static str
    {
        "
        #version 140
        uniform mat4 mat;
        in vec2 position;
        in vec3 color;
        out vec3 vColor;

        void main()
        {
            gl_Position = mat * vec4(position, 0.0, 1.0);
            vColor = color;
        }
        "
    }

    fn fragment() -> &'static str
    {
        "
        #version 140
        in vec3 vColor;
        out vec4 f_color;
        void main()
        {
            f_color = vec4(vColor, 1.0);
        }
        "
    }
}

struct Triangle
{
    mesh: Mesh<Vertex>,
    transform: Transform,
}

impl Triangle
{
    fn new(display: &Display) -> Triangle
    {
        let mesh = Mesh::new(&display, &[
            Vertex { position: [-1.0, -1.0], color: [0.0, 1.0, 0.0] },
            Vertex { position: [ 0.0,  1.0], color: [0.0, 0.0, 1.0] },
            Vertex { position: [ 1.0, -1.0], color: [1.0, 0.0, 0.0] },
        ]);
        Triangle
        {
            mesh: mesh,
            transform: Transform::new(),
        }
    }
}

impl Renderable<Shader> for Triangle
{
    fn draw(&self, renderer: &Renderer<Shader>, target: &mut Frame, parent: &Matrix4<f32>)
    {
        let mat = parent * self.transform.matrix();
        let uniforms = Uniforms { mat: mat.into() };
        renderer.draw(target, &self.mesh, &uniforms);
    }
}

fn main()
{
    let display = erya::build_display("triangle", (800, 600));
    let renderer = Renderer::<Shader>::new(&display);
    let mut camera = Camera3D::new(&display);
    camera.eye = cgmath::Point3::new(3.0, 4.0, 4.0);
    let mut timer = Timer::new().limit(60);
    let mut angle: f32 = 0.0;
    let mut triangle = Triangle::new(&display);

    'main: loop
    {
        angle += 0.01;
        let mut target = display.draw();
        triangle.transform.rotation = Quaternion::from_angle_x(Rad::new(angle));
        target.clear_color(0.0, 0.0, 0.0, 0.0);
        triangle.draw(&renderer, &mut target, &camera.matrix());
        target.finish().unwrap();
        for event in display.poll_events()
        {
            match event
            {
                Event::Closed => break 'main,
                _ => (),
            }
        }
        timer.update();
    }
}
<commit_msg>Quick fix<commit_after>#[macro_use(implement_uniforms)]
extern crate erya;
#[macro_use(implement_vertex)]
extern crate glium;
extern crate cgmath;

use glium::glutin::Event;
use glium::{ Surface, Frame };
use cgmath::{ Matrix4, Rotation3, Rad, Quaternion, Angle };
use erya::shader;
use erya::{ Renderer, Renderable, Display, Mesh, Camera3D, Camera,
            Timer, Transform };

#[derive(Copy, Clone)]
struct Vertex
{
    position: [f32; 2],
    color: [f32; 3],
}

implement_vertex! { Vertex, position, color }

struct Uniforms
{
    mat: [[f32; 4]; 4],
}

implement_uniforms! { Uniforms, mat }

struct Shader;

impl shader::ShaderType for Shader
{
    type Vertex = Vertex;
    type Uniforms = Uniforms;

    fn vertex() -> &'static str
    {
        "
        #version 140
        uniform mat4 mat;
        in vec2 position;
        in vec3 color;
        out vec3 vColor;

        void main()
        {
            gl_Position = mat * vec4(position, 0.0, 1.0);
            vColor = color;
        }
        "
    }

    fn fragment() -> &'static str
    {
        "
        #version 140
        in vec3 vColor;
        out vec4 f_color;
        void main()
        {
            f_color = vec4(vColor, 1.0);
        }
        "
    }
}

struct Triangle
{
    mesh: Mesh<Vertex>,
    transform: Transform,
}

impl Triangle
{
    fn new(display: &Display) -> Triangle
    {
        let mesh = Mesh::new(&display, &[
            Vertex { position: [-1.0, -1.0], color: [0.0, 1.0, 0.0] },
            Vertex { position: [ 0.0,  1.0], color: [0.0, 0.0, 1.0] },
            Vertex { position: [ 1.0, -1.0], color: [1.0, 0.0, 0.0] },
        ]);
        Triangle
        {
            mesh: mesh,
            transform: Transform::new(),
        }
    }
}

impl Renderable<Shader> for Triangle
{
    fn draw(&self, renderer: &Renderer<Shader>, target: &mut Frame, parent: &Matrix4<f32>)
    {
        let mat = parent * self.transform.matrix();
        let uniforms = Uniforms { mat: mat.into() };
        renderer.draw(target, &self.mesh, &uniforms);
    }
}

fn main()
{
    let display = erya::build_display("triangle", (800, 600));
    let renderer = Renderer::<Shader>::new(&display);
    let mut camera = Camera3D::new(&display);
    camera.eye = cgmath::Point3::new(3.0, 4.0, 4.0);
    let mut timer = Timer::new().limit(60);
    let mut angle: f32 = 0.0;
    let mut triangle = Triangle::new(&display);

    'main: loop
    {
        angle += 0.01;
        let mut target = display.draw();
        triangle.transform.rotation = Quaternion::from_angle_x(Rad::new(angle));
        target.clear_color(0.0, 0.0, 0.0, 0.0);
        triangle.draw(&renderer, &mut target, &camera.matrix());
        target.finish().unwrap();
        for event in display.poll_events()
        {
            match event
            {
                Event::Closed => break 'main,
                _ => (),
            }
        }
        timer.update();
    }
}
<|endoftext|>


<commit_before>
extern crate ndarray;

use ndarray::{
    OwnedArray,
    ArrayBase,
    DataMut,
    Dimension,
    ArrayView,
};

use std::cmp;

#[derive(Copy, Clone, Debug)]
pub enum ZipError {
    NotSameLayout,
    NotSameShape,
}

/// Defines a function similar to zip_mut_with, that takes multiple read-only
/// arguments. All arrays must be of default layout and same shape.
macro_rules! define_zip {
    ($name:ident, $($arg:ident),+) => {
#[allow(non_snake_case)]
fn $name<A, $($arg,)+ Data, Dim, Func>(a: &mut ArrayBase<Data, Dim>,
    $($arg: ArrayView<$arg, Dim>,)+ mut f: Func)
    -> Result<(), ZipError>
    where Data: DataMut<Elem=A>,
          Dim: Dimension,
          Func: FnMut(&mut A, $(&$arg),+)
{
    if $(a.shape() != $arg.shape() ||)+ false {
        return Err(ZipError::NotSameShape);
    }
    if let Some(a_s) = a.as_slice_mut() {
        let len = a_s.len();
        $(
            // extract the slice
            let $arg = if let Some(s) = $arg.as_slice() {
                s
            } else {
                return Err(ZipError::NotSameLayout);
            };
            let len = cmp::min(len, $arg.len());
        )+
        let a_s = &mut a_s[..len];
        $(
            let $arg = &$arg[..len];
        )+
        for i in 0..len {
            f(&mut a_s[i], $(&$arg[i]),+)
        }
        return Ok(());
    }
    // otherwise
    Err(ZipError::NotSameLayout)
}
    }
}

define_zip!(zip_2, B);
define_zip!(zip_3, B, C);
define_zip!(zip_4, B, C, D);
define_zip!(zip_5, B, C, D, E);

fn main() {
    let n = 16;
    let mut a = OwnedArray::<f32, _>::zeros((n, n));
    let mut b = OwnedArray::<f32, _>::from_elem((n, n), 1.);
    for ((i, j), elt) in b.indexed_iter_mut() {
        *elt /= 1. + (i + j) as f32;
    }
    let c = OwnedArray::<f32, _>::from_elem((n, n), 1.7);

    for _ in 0..1000 {
        zip_3(&mut a, b.view(), c.view(), |x, &y, &z| *x += y * z).unwrap();
    }
    println!("{:4.2?}", a);
}
<commit_msg>Fix warnings in zip_many example<commit_after>
extern crate ndarray;

use ndarray::{
    OwnedArray,
    ArrayBase,
    DataMut,
    Dimension,
    ArrayView,
};

use std::cmp;

#[derive(Copy, Clone, Debug)]
pub enum ZipError {
    NotSameLayout,
    NotSameShape,
}

/// Defines a function similar to zip_mut_with, that takes multiple read-only
/// arguments. All arrays must be of default layout and same shape.
macro_rules! define_zip {
    ($name:ident, $($arg:ident),+) => {
#[allow(non_snake_case)]
fn $name<A, $($arg,)+ Data, Dim, Func>(a: &mut ArrayBase<Data, Dim>,
    $($arg: ArrayView<$arg, Dim>,)+ mut f: Func)
    -> Result<(), ZipError>
    where Data: DataMut<Elem=A>,
          Dim: Dimension,
          Func: FnMut(&mut A, $(&$arg),+)
{
    if $(a.shape() != $arg.shape() ||)+ false {
        return Err(ZipError::NotSameShape);
    }
    if let Some(a_s) = a.as_slice_mut() {
        let len = a_s.len();
        $(
            // extract the slice
            let $arg = if let Some(s) = $arg.as_slice() {
                s
            } else {
                return Err(ZipError::NotSameLayout);
            };
            let len = cmp::min(len, $arg.len());
        )+
        let a_s = &mut a_s[..len];
        $(
            let $arg = &$arg[..len];
        )+
        for i in 0..len {
            f(&mut a_s[i], $(&$arg[i]),+)
        }
        return Ok(());
    }
    // otherwise
    Err(ZipError::NotSameLayout)
}
    }
}

//define_zip!(zip_2, B);
define_zip!(zip_3, B, C);
//define_zip!(zip_4, B, C, D);
//define_zip!(zip_5, B, C, D, E);

fn main() {
    let n = 16;
    let mut a = OwnedArray::<f32, _>::zeros((n, n));
    let mut b = OwnedArray::<f32, _>::from_elem((n, n), 1.);
    for ((i, j), elt) in b.indexed_iter_mut() {
        *elt /= 1. + (i + j) as f32;
    }
    let c = OwnedArray::<f32, _>::from_elem((n, n), 1.7);

    for _ in 0..1000 {
        zip_3(&mut a, b.view(), c.view(), |x, &y, &z| *x += y * z).unwrap();
    }
    println!("{:4.2?}", a);
}
<|endoftext|>


<commit_before>#![deny(warnings)]

extern crate coreutils;
extern crate extra;

use std::env;
use std::fs;
use std::io::{stderr, stdout, Write};
use std::process::exit;
use coreutils::ArgParser;
use extra::option::OptionalExt;

const MAN_PAGE: &'static str = /* @MANSTART{shutdown} */ r#"
NAME
    shutdown - stop the system

SYNOPSIS
    shutdown [ -h | -help ]

DESCRIPTION
    Attempt to shutdown the system using ACPI. Failure will be logged to the terminal

OPTIONS
    -h
    --help
        display this help and exit
"#; /* @MANEND */

fn main() {
    let stdout = stdout();
    let mut stdout = stdout.lock();
    let mut stderr = stderr();
    let mut parser = ArgParser::new(1)
        .add_flag(&["h", "help"]);
    parser.parse(env::args());

    if parser.found("help") {
        stdout.write(MAN_PAGE.as_bytes()).try(&mut stderr);
        stdout.flush().try(&mut stderr);
        exit(0);
    }

    fs::File::create("acpi:off").try(&mut stderr);
}
<commit_msg>Update shutdown command for new API<commit_after>#![deny(warnings)]

extern crate coreutils;
extern crate extra;
extern crate syscall;

use std::env;
use std::io::{stderr, stdout, Error, Write};
use std::process::exit;
use coreutils::ArgParser;
use extra::option::OptionalExt;
use syscall::flag::SIGKILL;

const MAN_PAGE: &'static str = /* @MANSTART{shutdown} */ r#"
NAME
    shutdown - stop the system

SYNOPSIS
    shutdown [ -h | -help ]

DESCRIPTION
    Attempt to shutdown the system using ACPI. Failure will be logged to the terminal

OPTIONS
    -h
    --help
        display this help and exit
"#; /* @MANEND */

fn main() {
    let stdout = stdout();
    let mut stdout = stdout.lock();
    let mut stderr = stderr();
    let mut parser = ArgParser::new(1)
        .add_flag(&["h", "help"]);
    parser.parse(env::args());

    if parser.found("help") {
        stdout.write(MAN_PAGE.as_bytes()).try(&mut stderr);
        stdout.flush().try(&mut stderr);
        exit(0);
    }

    syscall::kill(1, SIGKILL).map_err(|err| Error::from_raw_os_error(err.errno)).try(&mut stderr);
}
<|endoftext|>


<commit_before>use std::default::Default;

use communication::Communicator;

use progress::frontier::{MutableAntichain, Antichain};
use progress::{Timestamp, Scope};
use progress::nested::Target;
use progress::nested::subgraph::Target::{GraphOutput, ScopeInput};

use progress::count_map::CountMap;

use progress::broadcast::ProgressVec;

pub struct ScopeWrapper<T: Timestamp> {
    pub scope:                  Box<Scope<T>>,          // the scope itself

    index:                  u64,

    pub inputs:                 u64,                       // cached information about inputs
    pub outputs:                u64,                       // cached information about outputs

    pub edges:                  Vec<Vec<Target>>,

    pub notify:                 bool,
    pub summary:                Vec<Vec<Antichain<T::Summary>>>,     // internal path summaries (input x output)

    pub guarantees:             Vec<MutableAntichain<T>>,   // per-input:   guarantee made by parent scope in inputs
    pub capabilities:           Vec<MutableAntichain<T>>,   // per-output:  capabilities retained by scope on outputs
    pub outstanding_messages:   Vec<MutableAntichain<T>>,   // per-input:   counts of messages on each input

    internal_progress:      Vec<CountMap<T>>,         // per-output:  temp buffer used to ask about internal progress
    consumed_messages:      Vec<CountMap<T>>,         // per-input:   temp buffer used to ask about consumed messages
    produced_messages:      Vec<CountMap<T>>,         // per-output:  temp buffer used to ask about produced messages

    pub guarantee_changes:      Vec<CountMap<T>>,         // per-input:   temp storage for changes in some guarantee...
}

impl<T: Timestamp> ScopeWrapper<T> {
    pub fn new(scope: Box<Scope<T>>, index: u64) -> ScopeWrapper<T> {
        let inputs = scope.inputs();
        let outputs = scope.outputs();
        let notify = scope.notify_me();

        let mut result = ScopeWrapper {
            scope:      scope,
            index:      index,
            inputs:     inputs,
            outputs:    outputs,
            edges:      vec![Default::default(); outputs as usize],

            notify:     notify,
            summary:    Vec::new(),

            guarantees:             vec![Default::default(); inputs as usize],
            capabilities:           vec![Default::default(); outputs as usize],
            outstanding_messages:   vec![Default::default(); inputs as usize],

            internal_progress: vec![CountMap::new(); outputs as usize],
            consumed_messages: vec![CountMap::new(); inputs as usize],
            produced_messages: vec![CountMap::new(); outputs as usize],

            guarantee_changes: vec![CountMap::new(); inputs as usize],
        };

        let (summary, work) = result.scope.get_internal_summary();

        result.summary = summary;

        // TODO : Gross. Fix.
        for (index, capability) in result.capabilities.iter_mut().enumerate() {
            capability.update_iter_and(work[index].elements().iter().map(|x|x.clone()), |_, _| {});
        }

        return result;
    }

    pub fn push_pointstamps(&mut self, external_progress: &Vec<CountMap<T>>) {
        if self.notify && external_progress.iter().any(|x| x.len() > 0) {
            for input_port in (0..self.inputs as usize) {
                self.guarantees[input_port]
                    .update_into_cm(&external_progress[input_port], &mut self.guarantee_changes[input_port]);
            }

            // push any changes to the frontier to the subgraph.
            if self.guarantee_changes.iter().any(|x| x.len() > 0) {
                self.scope.push_external_progress(&mut self.guarantee_changes);

                // TODO : Shouldn't be necessary
                // for change in self.guarantee_changes.iter_mut() { change.clear(); }
                debug_assert!(!self.guarantee_changes.iter().any(|x| x.len() > 0));
            }
        }
    }

    pub fn pull_pointstamps<A: FnMut(u64, T,i64)->()>(&mut self,
                                                  pointstamp_messages: &mut ProgressVec<T>,
                                                  pointstamp_internal: &mut ProgressVec<T>,
                                                  mut output_action:   A) -> bool {

        let active = self.scope.pull_internal_progress(&mut self.internal_progress,
                                                       &mut self.consumed_messages,
                                                       &mut self.produced_messages);

        // for each output: produced messages and internal progress
        for output in (0..self.outputs as usize) {
            while let Some((time, delta)) = self.produced_messages[output].pop() {
                for &target in self.edges[output].iter() {
                    match target {
                        ScopeInput(tgt, tgt_in)   => { pointstamp_messages.push((tgt, tgt_in, time, delta)); },
                        GraphOutput(graph_output) => { output_action(graph_output, time, delta); },
                    }
                }
            }

            while let Some((time, delta)) = self.internal_progress[output as usize].pop() {
                pointstamp_internal.push((self.index, output as u64, time, delta));
            }
        }

        // for each input: consumed messages
        for input in (0..self.inputs as usize) {
            while let Some((time, delta)) = self.consumed_messages[input as usize].pop() {
                pointstamp_messages.push((self.index, input as u64, time, -delta));
            }
        }

        return active;
    }

    pub fn add_edge(&mut self, output: u64, target: Target) { self.edges[output as usize].push(target); }
}
<commit_msg>added useful asserts<commit_after>use std::default::Default;

use communication::Communicator;

use progress::frontier::{MutableAntichain, Antichain};
use progress::{Timestamp, Scope};
use progress::nested::Target;
use progress::nested::subgraph::Target::{GraphOutput, ScopeInput};

use progress::count_map::CountMap;

use progress::broadcast::ProgressVec;

pub struct ScopeWrapper<T: Timestamp> {
    pub scope:                  Box<Scope<T>>,          // the scope itself

    index:                  u64,

    pub inputs:                 u64,                       // cached information about inputs
    pub outputs:                u64,                       // cached information about outputs

    pub edges:                  Vec<Vec<Target>>,

    pub notify:                 bool,
    pub summary:                Vec<Vec<Antichain<T::Summary>>>,     // internal path summaries (input x output)

    pub guarantees:             Vec<MutableAntichain<T>>,   // per-input:   guarantee made by parent scope in inputs
    pub capabilities:           Vec<MutableAntichain<T>>,   // per-output:  capabilities retained by scope on outputs
    pub outstanding_messages:   Vec<MutableAntichain<T>>,   // per-input:   counts of messages on each input

    internal_progress:      Vec<CountMap<T>>,         // per-output:  temp buffer used to ask about internal progress
    consumed_messages:      Vec<CountMap<T>>,         // per-input:   temp buffer used to ask about consumed messages
    produced_messages:      Vec<CountMap<T>>,         // per-output:  temp buffer used to ask about produced messages

    pub guarantee_changes:      Vec<CountMap<T>>,         // per-input:   temp storage for changes in some guarantee...
}

impl<T: Timestamp> ScopeWrapper<T> {
    pub fn new(scope: Box<Scope<T>>, index: u64) -> ScopeWrapper<T> {
        let inputs = scope.inputs();
        let outputs = scope.outputs();
        let notify = scope.notify_me();

        let mut result = ScopeWrapper {
            scope:      scope,
            index:      index,
            inputs:     inputs,
            outputs:    outputs,
            edges:      vec![Default::default(); outputs as usize],

            notify:     notify,
            summary:    Vec::new(),

            guarantees:             vec![Default::default(); inputs as usize],
            capabilities:           vec![Default::default(); outputs as usize],
            outstanding_messages:   vec![Default::default(); inputs as usize],

            internal_progress: vec![CountMap::new(); outputs as usize],
            consumed_messages: vec![CountMap::new(); inputs as usize],
            produced_messages: vec![CountMap::new(); outputs as usize],

            guarantee_changes: vec![CountMap::new(); inputs as usize],
        };

        let (summary, work) = result.scope.get_internal_summary();

        result.summary = summary;

        assert!(result.summary.len() as u64 == result.inputs);
        assert!(!result.summary.iter().any(|x| x.len() as u64 != result.outputs));

        // TODO : Gross. Fix.
        for (index, capability) in result.capabilities.iter_mut().enumerate() {
            capability.update_iter_and(work[index].elements().iter().map(|x|x.clone()), |_, _| {});
        }

        return result;
    }

    pub fn push_pointstamps(&mut self, external_progress: &Vec<CountMap<T>>) {
        if self.notify && external_progress.iter().any(|x| x.len() > 0) {
            for input_port in (0..self.inputs as usize) {
                self.guarantees[input_port]
                    .update_into_cm(&external_progress[input_port], &mut self.guarantee_changes[input_port]);
            }

            // push any changes to the frontier to the subgraph.
            if self.guarantee_changes.iter().any(|x| x.len() > 0) {
                self.scope.push_external_progress(&mut self.guarantee_changes);

                // TODO : Shouldn't be necessary
                // for change in self.guarantee_changes.iter_mut() { change.clear(); }
                debug_assert!(!self.guarantee_changes.iter().any(|x| x.len() > 0));
            }
        }
    }

    pub fn pull_pointstamps<A: FnMut(u64, T,i64)->()>(&mut self,
                                                  pointstamp_messages: &mut ProgressVec<T>,
                                                  pointstamp_internal: &mut ProgressVec<T>,
                                                  mut output_action:   A) -> bool {

        let active = self.scope.pull_internal_progress(&mut self.internal_progress,
                                                       &mut self.consumed_messages,
                                                       &mut self.produced_messages);

        // for each output: produced messages and internal progress
        for output in (0..self.outputs as usize) {
            while let Some((time, delta)) = self.produced_messages[output].pop() {
                for &target in self.edges[output].iter() {
                    match target {
                        ScopeInput(tgt, tgt_in)   => { pointstamp_messages.push((tgt, tgt_in, time, delta)); },
                        GraphOutput(graph_output) => { output_action(graph_output, time, delta); },
                    }
                }
            }

            while let Some((time, delta)) = self.internal_progress[output as usize].pop() {
                pointstamp_internal.push((self.index, output as u64, time, delta));
            }
        }

        // for each input: consumed messages
        for input in (0..self.inputs as usize) {
            while let Some((time, delta)) = self.consumed_messages[input as usize].pop() {
                pointstamp_messages.push((self.index, input as u64, time, -delta));
            }
        }

        return active;
    }

    pub fn add_edge(&mut self, output: u64, target: Target) { self.edges[output as usize].push(target); }
}
<|endoftext|>