When the code will be avaliable?

Hello, I am very interested in your paper. Could you please let me know when the code will be available? Thank you for your great work and your kind response.

Thank you for your concern. As I have been busy with my studies for half a year and have no time to organize the code, I will take the time to organize the code and open it completely in the near future.

Thank you~

Our code is available now and I will close this issue.


Firefox support for vite-dev

Hi @mathe42!
Congratulations on this awesome plugin, it works really really nice.
We are migrating a CRA project to Vite, our app uses workers extensively and it would be nice to test them during development in other browsers different from Chrome. Do you know any workaround to enable support on Firefox when using the Vite dev mode?
We are very interested, so if you think we can contribute to this plugin by coding, please point us in a good direction.

I will add an Option for that in the next day or so. Should be quite easy. Note that latest Version of Safari also works in Dev Mode.
Nur expect poor loading Times!

No update required just use the (currently not documented) customConfigs option:
{
  plugins: [
    comlink({
      customConfigs: {
        "comlink:": "comlink@main:worker-iife:comlink@worker:",
      }
    })
  ]
}

This will tranform the workers to an iife and don't use module syntax.
Note that it is currently only FireFox not supporting module Workers. See
https://caniuse.com/mdn-api_worker_worker_ecmascript_modules

Thank you @mathe42!
Almost all the dev team uses Chromium, but sometimes we test new features over Firefox. We will probably just document the workaround so Firefox users can modify the config when required.
Thank you very much!


GH-15025: [CI][C++][Homebrew] Ensure removing Python related commands

If they exist and Homebrew's Python formula is updated, the update is failed:
https://github.com/apache/arrow/actions/runs/3729475663/jobs/6325425516
==> Pouring<EMAIL_ADDRESS>Error: The `brew link` step did not complete successfully
The formula built, but is not symlinked into /usr/local
Could not symlink bin/2to3
Target /usr/local/bin/2to3
already exists. You may want to remove it:
  rm '/usr/local/bin/2to3'

To force the link and overwrite all conflicting files:
  brew link --overwrite<EMAIL_ADDRESS>
To list all files that would be deleted:
  brew link --overwrite --dry-run<EMAIL_ADDRESS>
Possible conflicting files are:
/usr/local/bin/2to3 -> /Library/Frameworks/Python.framework/Versions/3.11/bin/2to3
/usr/local/bin/idle3 -> /Library/Frameworks/Python.framework/Versions/3.11/bin/idle3
/usr/local/bin/pydoc3 -> /Library/Frameworks/Python.framework/Versions/3.11/bin/pydoc3
/usr/local/bin/python3 -> /Library/Frameworks/Python.framework/Versions/3.11/bin/python3
/usr/local/bin/python3-config -> /Library/Frameworks/Python.framework/Versions/3.11/bin/python3-config

Closes: #15025

+1


3.0.0 not published to cocoapods

Will new versions be published to cocoapods or best to use manual install?

3.0.0 isn't quite yet ready for release. There are a few more changes to get in and we are waiting for PromiseKit 5 to be published.

@apparentvisuals , we will be publishing to Cocoapods regularly once releases are complete. 3.0.1 has just been released and is ready for use!


chore: update dashboard yaml to new version

Description:
This PR updates the YAML definition of the assets to the new Superset version. It also adds a version card to the operator dashboard:

Fixes: #359

Thanks for the pull request, @Ian2012!  Please note that it may take us up to several weeks or months to complete a review and merge your PR.
Feel free to add as much of the following information to the ticket as you can:

supporting documentation
Open edX discussion forum threads
timeline information ("this must be merged by XX date", and why that is)
partner information ("this is a course on edx.org")
any other information that can help Product understand the context for the PR

All technical communication about the code itself will be done via the GitHub pull request interface. As a reminder, our process documentation is here.
This is currently a draft pull request. When it is ready for our review and all tests are green, click "Ready for Review", or remove "WIP" from the title, as appropriate.

@Ian2012 🎉 Your pull request was merged!  Please take a moment  to answer a two question survey so we can improve your experience in the future.


Fixed example Snippet and clarified it.

Found a possible error in one of the snippets
Summary
Fixes the 3rd snippet's return type and clarifies the local function's name to emphasize it's status as a local function
Details
Changed return type of snippet 3 from bool to int, as returned variable was declared as int.

Thank you so much, @sas41, for making the additional change. We'll merge your PR now. Your changes should appear live on docs.microsoft.com in the next day or two.


Technical Article About Object Model in Aptos

Money: 100 USDC
Bounty for technical article:
The framework source code analysis and contract practice about Object Mode
Object Model Documentation: https://aptos.dev/standards/aptos-object/
Object Model Example: https://github.com/aptos-labs/aptos-core/tree/main/aptos-move/move-examples/token_objects/hero

🙋

Aptos Object Model

Feedback requested. Please provide any proposed changes or suggestions within 24 hours, and I will consider and incorporate them into the article. Additionally, the 3 remaining TODOs will be  completed within the same timeframe.

Draft
Object model introduces a comprehensive capability framework that facilitates control over resources, ownership management, and event emission, which in return enhances the functionality and flexibility of on-chain interactions.
The primary motivation behind this model is to enable Move to represent a set of different complex types as a one collection of resources stored within a single address.
By organizing resources in this manner, objects can encompass various elements such as NFTs, tokens, and specialized data structures like player objects within a game.
The model offers several advantages, including improved type-safety, enhanced data access, and the ability to emit events directly from objects.
The existing Aptos data model relies on the store ability within Move, allowing structs to be stored in global storage. However, this approach has limitations:

Limited data accessibility: Data can be placed within user-defined resources, making it inaccessible or violating the expected behavior for that data. This can cause confusion for users and creators.
Mixing data types: Different data types can be stored in a single data structure using the "any" type, but this incurs additional costs due to deserialization. It also introduces confusion when developers expect a specific field to represent a particular type.
Lack of data composability: Move currently has restrictions on recursive data structures, which limits the composability of data. Moreover, true recursive data structures can lead to security vulnerabilities.
Complex data referencing: Referencing existing data within entry functions requires substantial code. Supporting unique keys for string validation becomes intricate, hindering development efficiency.
Limited event emission: Events can only be emitted from an account, not directly from associated data, leading to disjointed event tracking.
Costly transfer logic: Transferring logic is restricted to module-specific APIs, resulting in unnecessary cost overhead and resource loading for both senders and receivers.

Let's delve into the composition of the object model:
The core structure compromised of four components.
struct `ObjectCore` has key {
        guid_creation_num: u64,
        owner: address,
        allow_ungated_transfer: bool,
        transfer_events: event::EventHandle<TransferEvent>,
    }

guid_creation_num: A distinctive identifier.
owner: The owner's address (whether pertaining to an object or an account).
allow_ungated_transfer: A boolean variable enabling or disabling the object's transferability. Visualize this variable as a gate, allowing the execution of transfers when in the open (true) state, and restricting them when closed (false).
transfer_events: The transfer event that is emitted whenever a transfer takes place.

These variables represent the object's uniqueness, ownership details, transferability status, and discoverability, respectively. By already encompassing the core structure, the principles of scarcity within the Move framework is effectively validated.
[Scarcity refers to the limited availability of a particular object or asset within a given system.
Firstly, guid_creation_num assigned to each object ensures that no two entities share the same identity. This uniqueness fosters a sense of rarity and exclusivity, as each object can be distinctly identified and differentiated from others.
Secondly, owner address associated with the object or account further enhances scarcity. By explicitly designating an owner, it establishes a sense of ownership and control over the object, limiting its availability to a specific individual or entity. This owner-based restriction helps maintain scarcity by ensuring that the transfer of ownership is intentional and controlled.
allow_ungated_transfer, acting as a gate for enabling or disabling transfer, adds an additional layer of scarcity enforcement. By providing the ability to regulate and restrict transfers, the model empowers owners to determine when and to whom an object can be transferred. This mechanism prevents unauthorized or undesired transfers, reinforcing the scarcity of the object by granting ownership control.
Finally, transfer_events, emitted whenever a transfer occurs, contributes to the overall discoverability and transparency of the system. This event serves as an acknowledgment and record of the transfer, allowing participants to be aware of ownership changes and facilitating the tracking of object movement. By providing visibility into the transfer process, the model ensures that the scarcity of an object is evident and verifiable.]
These properties define the object model:

simplified storage interface.

data and ownership model are globally accessible.

extensible programming model.

simplified storage interface:
the object model supports a heterogeneous collection of resources to be stored together, providing a common core data layer for different data types. This means that different data types can be stored together.
The purpose of this feature is to enable data types to share common functionality and resources while still allowing for richer extensions specific to each data type. For example, the core data layer may contain shared properties or attributes that are common to all objects, while the extensions may contain additional properties or behaviors specific to each object type (e.g., a concert ticket object may have additional properties related to the concert event).
In order to simplifies the storage and retrieval process, resources within an object share the same storage.
#[resource_group(scope = global)]
This also enables the sharing of common data structures or core data layers among different resource types. For example, all resources within an object can share a common set of tokens or basic data fields.
#[resource_group_member(group = aptos_framework::object::ObjectGroup)]
The Object<phantom T> struct allows for the storage and retrieval of objects of different types in a unified manner, providing a simplified interface to interact with the objects stored in the Move storage.

data and ownership model are globally accessible.
Objects and their associated data can be accessed and managed from anywhere since they are not confined to specific scopes or modules but are accessible globally.

Structs:

ObjectCore: This struct defines the core properties of an object, including the owner, transferability, and events associated with the object. It represents the ownership and data model of an object.

Object<phantom T>: This struct represents a pointer to an object. It holds the address of the object and allows access to the underlying data. It represents the data model of an object.

ConstructorRef, DeleteRef, ExtendRef, TransferRef, LinearTransferRef, DeriveRef: These structs represent references or handles to perform various operations on objects, such as creation, deletion, extension, transfer, and derivation. They provide access to the ownership and data model of an object.

Functions:

create_named_object, create_object_from_account, generate_delete_ref, generate_extend_ref, etc.: These functions manipulate the object model by creating objects, generating references, and performing operations on objects. They interact with the data and ownership model of objects.

This structure promotes creating and managing objects with a globally accessible data and ownership model, enabling various operations on objects and supporting event handling.

extensible programming model:
This refers to the ability to extend and customize the behavior of objects without modifying their original implementation. It allows developers to add new functionality, modify existing behavior, or specialize objects for specific use cases without directly modifying the underlying code.

Structs:

ConstructorRef: Represents the ability given to the creator to configure the object as necessary.
DeleteRef: Used to remove an object from storage.
ExtendRef: Used to create events or move additional resources into object storage.
TransferRef: Used to create LinearTransferRef, hence ownership transfer.
LinearTransferRef: Used to perform transfers.
DeriveRef: Used to create derived objects from a given object.

Functions:

create_named_object: Creates a new named object and returns the ConstructorRef. Named objects can be queried globally by knowing the user-generated seed used to create them.
create_user_derived_object: Creates a new object whose address is derived based on the creator account address and another object.
create_object_from_account: Creates a new object from a GUID generated by an account.
create_object_from_object: Creates a new object from a GUID generated by an object.
create_object_from_guid: Creates a new object from a GUID generated by either an account or an object.
convert: converts the object type.

These structs and functions provide mechanisms to create, configure, extend, transfer, derive, convert, and delete objects, allowing for individualization of user applications and leveraging the core framework.

Object lifecycle:
TODO: add implementation code to each specification.

Object Declaration.
Object Instantiation.
Object Ownership. (to the creator address by default)
Object Access.
Object Deletion.
Event Emission.
Object Composition.

TODO: security considerations?

TODO:
3. Object model use cases:

Aptos Token v2: an object-based token model
Aptos Fungible Asset: an object-based fungible asset model

Aptos Object Model

Feedback requested. Please provide any proposed changes or suggestions within 24 hours, and I will consider and incorporate them into the article. Additionally, the 3 remaining TODOs will be  completed within the same timeframe.

Draft
Object model introduces a comprehensive capability framework that facilitates control over resources, ownership management, and event emission, which in return enhances the functionality and flexibility of on-chain interactions.
The primary motivation behind this model is to enable Move to represent a set of different complex types as a one collection of resources stored within a single address.
By organizing resources in this manner, objects can encompass various elements such as NFTs, tokens, and specialized data structures like player objects within a game. The model offers several advantages, including improved type-safety, enhanced data access, and the ability to emit events directly from objects.
The existing Aptos data model relies on the store ability within Move, allowing structs to be stored in global storage. However, this approach has limitations:

Limited data accessibility: Data can be placed within user-defined resources, making it inaccessible or violating the expected behavior for that data. This can cause confusion for users and creators.
Mixing data types: Different data types can be stored in a single data structure using the "any" type, but this incurs additional costs due to deserialization. It also introduces confusion when developers expect a specific field to represent a particular type.
Lack of data composability: Move currently has restrictions on recursive data structures, which limits the composability of data. Moreover, true recursive data structures can lead to security vulnerabilities.
Complex data referencing: Referencing existing data within entry functions requires substantial code. Supporting unique keys for string validation becomes intricate, hindering development efficiency.
Limited event emission: Events can only be emitted from an account, not directly from associated data, leading to disjointed event tracking.
Costly transfer logic: Transferring logic is restricted to module-specific APIs, resulting in unnecessary cost overhead and resource loading for both senders and receivers.

Let's delve into the composition of the object model: The core structure compromised of four components.
struct `ObjectCore` has key {
        guid_creation_num: u64,
        owner: address,
        allow_ungated_transfer: bool,
        transfer_events: event::EventHandle<TransferEvent>,
    }

guid_creation_num: A distinctive identifier.
owner: The owner's address (whether pertaining to an object or an account).
allow_ungated_transfer: A boolean variable enabling or disabling the object's transferability. Visualize this variable as a gate, allowing the execution of transfers when in the open (true) state, and restricting them when closed (false).
transfer_events: The transfer event that is emitted whenever a transfer takes place.

These variables represent the object's uniqueness, ownership details, transferability status, and discoverability, respectively. By already encompassing the core structure, the principles of scarcity within the Move framework is effectively validated.
[Scarcity refers to the limited availability of a particular object or asset within a given system.
Firstly, guid_creation_num assigned to each object ensures that no two entities share the same identity. This uniqueness fosters a sense of rarity and exclusivity, as each object can be distinctly identified and differentiated from others.
Secondly, owner address associated with the object or account further enhances scarcity. By explicitly designating an owner, it establishes a sense of ownership and control over the object, limiting its availability to a specific individual or entity. This owner-based restriction helps maintain scarcity by ensuring that the transfer of ownership is intentional and controlled.
allow_ungated_transfer, acting as a gate for enabling or disabling transfer, adds an additional layer of scarcity enforcement. By providing the ability to regulate and restrict transfers, the model empowers owners to determine when and to whom an object can be transferred. This mechanism prevents unauthorized or undesired transfers, reinforcing the scarcity of the object by granting ownership control.
Finally, transfer_events, emitted whenever a transfer occurs, contributes to the overall discoverability and transparency of the system. This event serves as an acknowledgment and record of the transfer, allowing participants to be aware of ownership changes and facilitating the tracking of object movement. By providing visibility into the transfer process, the model ensures that the scarcity of an object is evident and verifiable.]
These properties define the object model:

simplified storage interface.

data and ownership model are globally accessible.

extensible programming model.

simplified storage interface:
the object model supports a heterogeneous collection of resources to be stored together, providing a common core data layer for different data types. This means that different data types can be stored together.
The purpose of this feature is to enable data types to share common functionality and resources while still allowing for richer extensions specific to each data type. For example, the core data layer may contain shared properties or attributes that are common to all objects, while the extensions may contain additional properties or behaviors specific to each object type (e.g., a concert ticket object may have additional properties related to the concert event).
In order to simplifies the storage and retrieval process, resources within an object share the same storage.
#[resource_group(scope = global)]
This also enables the sharing of common data structures or core data layers among different resource types. For example, all resources within an object can share a common set of tokens or basic data fields.
#[resource_group_member(group = aptos_framework::object::ObjectGroup)]
The Object<phantom T> struct allows for the storage and retrieval of objects of different types in a unified manner, providing a simplified interface to interact with the objects stored in the Move storage.

data and ownership model are globally accessible.
Objects and their associated data can be accessed and managed from anywhere since they are not confined to specific scopes or modules but are accessible globally.

Structs:

ObjectCore: This struct defines the core properties of an object, including the owner, transferability, and events associated with the object. It represents the ownership and data model of an object.
Object<phantom T>: This struct represents a pointer to an object. It holds the address of the object and allows access to the underlying data. It represents the data model of an object.
ConstructorRef, DeleteRef, ExtendRef, TransferRef, LinearTransferRef, DeriveRef: These structs represent references or handles to perform various operations on objects, such as creation, deletion, extension, transfer, and derivation. They provide access to the ownership and data model of an object.

Functions:

create_named_object, create_object_from_account, generate_delete_ref, generate_extend_ref, etc.: These functions manipulate the object model by creating objects, generating references, and performing operations on objects. They interact with the data and ownership model of objects.

This structure promotes creating and managing objects with a globally accessible data and ownership model, enabling various operations on objects and supporting event handling.

extensible programming model:
This refers to the ability to extend and customize the behavior of objects without modifying their original implementation. It allows developers to add new functionality, modify existing behavior, or specialize objects for specific use cases without directly modifying the underlying code.

Structs:

ConstructorRef: Represents the ability given to the creator to configure the object as necessary.
DeleteRef: Used to remove an object from storage.
ExtendRef: Used to create events or move additional resources into object storage.
TransferRef: Used to create LinearTransferRef, hence ownership transfer.
LinearTransferRef: Used to perform transfers.
DeriveRef: Used to create derived objects from a given object.

Functions:

create_named_object: Creates a new named object and returns the ConstructorRef. Named objects can be queried globally by knowing the user-generated seed used to create them.
create_user_derived_object: Creates a new object whose address is derived based on the creator account address and another object.
create_object_from_account: Creates a new object from a GUID generated by an account.
create_object_from_object: Creates a new object from a GUID generated by an object.
create_object_from_guid: Creates a new object from a GUID generated by either an account or an object.
convert: converts the object type.

These structs and functions provide mechanisms to create, configure, extend, transfer, derive, convert, and delete objects, allowing for individualization of user applications and leveraging the core framework.

Object lifecycle:
TODO: add implementation code to each specification.

Object Declaration.
Object Instantiation.
Object Ownership. (to the creator address by default)
Object Access.
Object Deletion.
Event Emission.
Object Composition.

TODO: security considerations?

TODO: 3. Object model use cases:

Aptos Token v2: an object-based token model
Aptos Fungible Asset: an object-based fungible asset model

Great, go ahead finish todo, everything is fine.

Aptos Object Model
Introduction
Object model introduces a comprehensive capability framework that facilitates control over resources, ownership management, and event emission, which in return enhances the functionality and flexibility of on-chain interactions.
The primary motivation behind the object model is to enable Move to represent a set of different complex types as a one collection of resources stored within a single address.
By organizing resources in this manner, objects can encompass various elements such as NFTs, tokens, and specialized data structures like player objects within a game.
The model offers several advantages, including improved type-safety, enhanced data access, and the ability to emit events directly from objects.
The existing Aptos data model relies on the store ability within Move, allowing structs to be stored in global storage. However, this approach has limitations:

Limited data accessibility: Data can be placed within user-defined resources, making it inaccessible or violating the expected behavior for that data. This can cause confusion for users and creators.
Mixing data types: Different data types can be stored in a single data structure using the "any" type, but this incurs additional costs due to deserialization. It also introduces confusion when developers expect a specific field to represent a particular type.
Lack of data composability: Move currently has restrictions on recursive data structures, which limits the composability of data. Moreover, true recursive data structures can lead to security vulnerabilities.
Complex data referencing: Referencing existing data within entry functions requires substantial code. Supporting unique keys for string validation becomes intricate, hindering development efficiency.
Limited event emission: Events can only be emitted from an account, not directly from associated data, leading to disjointed event tracking.
Costly transfer logic: Transferring logic is restricted to module-specific APIs, resulting in unnecessary cost overhead and resource loading for both senders and receivers.

Analyzing object.move
Let's delve into the composition of the object model:
The core structure compromised of four components.
struct `ObjectCore` has key {
        guid_creation_num: u64,
        owner: address,
        allow_ungated_transfer: bool,
        transfer_events: event::EventHandle<TransferEvent>,
    }

guid_creation_num: A distinctive identifier.
owner: The owner's address (whether pertaining to an object or an account).
allow_ungated_transfer: A boolean variable enabling or disabling the object's transferability. Visualize this variable as a gate, allowing the execution of transfers when in the open (true) state, and restricting them when closed (false).
transfer_events: The transfer event that is emitted whenever a transfer takes place.

These variables represent the object's uniqueness, ownership details, transferability status, and discoverability, respectively. By already encompassing the core structure, the principles of scarcity within the Move framework is effectively validated.
[Scarcity refers to the limited availability of a particular object or asset within a given system.
Firstly, guid_creation_num assigned to each object ensures that no two entities share the same identity. This uniqueness fosters a sense of rarity and exclusivity, as each object can be distinctly identified and differentiated from others.
Secondly, owner address associated with the object or account further enhances scarcity. By explicitly designating an owner, it establishes a sense of ownership and control over the object, limiting its availability to a specific individual or entity. This owner-based restriction helps maintain scarcity by ensuring that the transfer of ownership is intentional and controlled.
allow_ungated_transfer, acting as a gate for enabling or disabling transfer, adds an additional layer of scarcity enforcement. By providing the ability to regulate and restrict transfers, the model empowers owners to determine when and to whom an object can be transferred. This mechanism prevents unauthorized or undesired transfers, reinforcing the scarcity of the object by granting ownership control.
Finally, transfer_events, emitted whenever a transfer occurs, contributes to the overall discoverability and transparency of the system. This event serves as an acknowledgment and record of the transfer, allowing participants to be aware of ownership changes and facilitating the tracking of object movement. By providing visibility into the transfer process, the model ensures that the scarcity of an object is evident and verifiable.]
These properties define the object model:

simplified storage interface.

data and ownership model are globally accessible.

extensible programming model.

simplified storage interface:
the object model supports a heterogeneous collection of resources to be stored together, providing a common core data layer for different data types. This means that different data types can be stored together.
The purpose of this feature is to enable data types to share common functionality and resources while still allowing for richer extensions specific to each data type. For example, the core data layer may contain shared properties or attributes that are common to all objects, while the extensions may contain additional properties or behaviors specific to each object type (e.g., a concert ticket object may have additional properties related to the concert event).
In order to simplifies the storage and retrieval process, resources within an object share the same storage.
#[resource_group(scope = global)]
This also enables the sharing of common data structures or core data layers among different resource types. For example, all resources within an object can share a common set of tokens or basic data fields.
#[resource_group_member(group = aptos_framework::object::ObjectGroup)]
The Object<phantom T> struct allows for the storage and retrieval of objects of different types in a unified manner, providing a simplified interface to interact with the objects stored in the Move storage.

data and ownership model are globally accessible.
Objects and their associated data can be accessed and managed from anywhere since they are not confined to specific scopes or modules but are accessible globally.

Structs:

ObjectCore: This struct defines the core properties of an object, including the owner, transferability, and events associated with the object. It represents the ownership and data model of an object.

Object<phantom T>: This struct represents a pointer to an object. It holds the address of the object and allows access to the underlying data. It represents the data model of an object.

ConstructorRef, DeleteRef, ExtendRef, TransferRef, LinearTransferRef, DeriveRef: These structs represent references or handles to perform various operations on objects, such as creation, deletion, extension, transfer, and derivation. They provide access to the ownership and data model of an object.

Functions:

create_named_object, create_object_from_account, generate_delete_ref, generate_extend_ref, etc.: These functions manipulate the object model by creating objects, generating references, and performing operations on objects. They interact with the data and ownership model of objects.

This structure promotes creating and managing objects with a globally accessible data and ownership model, enabling various operations on objects and supporting event handling.

extensible programming model:
This refers to the ability to extend and customize the behavior of objects without modifying their original implementation. It allows developers to add new functionality, modify existing behavior, or specialize objects for specific use cases without directly modifying the underlying code.

Structs:

ConstructorRef: Represents the ability given to the creator to configure the object as necessary.
DeleteRef: Used to remove an object from storage.
ExtendRef: Used to create events or move additional resources into object storage.
TransferRef: Used to create LinearTransferRef, hence ownership transfer.
LinearTransferRef: Used to perform transfers.
DeriveRef: Used to create derived objects from a given object.

Functions:

create_named_object: Creates a new named object and returns the ConstructorRef. Named objects can be queried globally by knowing the user-generated seed used to create them.
create_user_derived_object: Creates a new object whose address is derived based on the creator account address and another object.
create_object_from_account: Creates a new object from a GUID generated by an account.
create_object_from_object: Creates a new object from a GUID generated by an object.
create_object_from_guid: Creates a new object from a GUID generated by either an account or an object.
convert: converts the object type.

These structs and functions provide mechanisms to create, configure, extend, transfer, derive, convert, and delete objects, allowing for individualization of user applications and leveraging the core framework.

as a general rule, input validation, access control, appropriate event handling, and unit testing are effective to identify and potential security vulnerabilities.

Implementation example - Ticket as Object
https://github.com/Aladeenb/simple-ticket
Object model implementations within Aptos Framework:

Aptos Token v2: an object-based token model
Aptos Fungible Asset: an object-based fungible asset model

Aptos Object Model
Introduction
Object model introduces a comprehensive capability framework that facilitates control over resources, ownership management, and event emission, which in return enhances the functionality and flexibility of on-chain interactions.
The primary motivation behind the object model is to enable Move to represent a set of different complex types as a one collection of resources stored within a single address.
By organizing resources in this manner, objects can encompass various elements such as NFTs, tokens, and specialized data structures like player objects within a game. The model offers several advantages, including improved type-safety, enhanced data access, and the ability to emit events directly from objects.
The existing Aptos data model relies on the store ability within Move, allowing structs to be stored in global storage. However, this approach has limitations:

Limited data accessibility: Data can be placed within user-defined resources, making it inaccessible or violating the expected behavior for that data. This can cause confusion for users and creators.
Mixing data types: Different data types can be stored in a single data structure using the "any" type, but this incurs additional costs due to deserialization. It also introduces confusion when developers expect a specific field to represent a particular type.
Lack of data composability: Move currently has restrictions on recursive data structures, which limits the composability of data. Moreover, true recursive data structures can lead to security vulnerabilities.
Complex data referencing: Referencing existing data within entry functions requires substantial code. Supporting unique keys for string validation becomes intricate, hindering development efficiency.
Limited event emission: Events can only be emitted from an account, not directly from associated data, leading to disjointed event tracking.
Costly transfer logic: Transferring logic is restricted to module-specific APIs, resulting in unnecessary cost overhead and resource loading for both senders and receivers.

Analyzing object.move
Let's delve into the composition of the object model: The core structure compromised of four components.
struct `ObjectCore` has key {
        guid_creation_num: u64,
        owner: address,
        allow_ungated_transfer: bool,
        transfer_events: event::EventHandle<TransferEvent>,
    }

guid_creation_num: A distinctive identifier.
owner: The owner's address (whether pertaining to an object or an account).
allow_ungated_transfer: A boolean variable enabling or disabling the object's transferability. Visualize this variable as a gate, allowing the execution of transfers when in the open (true) state, and restricting them when closed (false).
transfer_events: The transfer event that is emitted whenever a transfer takes place.

These variables represent the object's uniqueness, ownership details, transferability status, and discoverability, respectively. By already encompassing the core structure, the principles of scarcity within the Move framework is effectively validated.
[Scarcity refers to the limited availability of a particular object or asset within a given system.
Firstly, guid_creation_num assigned to each object ensures that no two entities share the same identity. This uniqueness fosters a sense of rarity and exclusivity, as each object can be distinctly identified and differentiated from others.
Secondly, owner address associated with the object or account further enhances scarcity. By explicitly designating an owner, it establishes a sense of ownership and control over the object, limiting its availability to a specific individual or entity. This owner-based restriction helps maintain scarcity by ensuring that the transfer of ownership is intentional and controlled.
allow_ungated_transfer, acting as a gate for enabling or disabling transfer, adds an additional layer of scarcity enforcement. By providing the ability to regulate and restrict transfers, the model empowers owners to determine when and to whom an object can be transferred. This mechanism prevents unauthorized or undesired transfers, reinforcing the scarcity of the object by granting ownership control.
Finally, transfer_events, emitted whenever a transfer occurs, contributes to the overall discoverability and transparency of the system. This event serves as an acknowledgment and record of the transfer, allowing participants to be aware of ownership changes and facilitating the tracking of object movement. By providing visibility into the transfer process, the model ensures that the scarcity of an object is evident and verifiable.]
These properties define the object model:

simplified storage interface.

data and ownership model are globally accessible.

extensible programming model.

simplified storage interface:
the object model supports a heterogeneous collection of resources to be stored together, providing a common core data layer for different data types. This means that different data types can be stored together.
The purpose of this feature is to enable data types to share common functionality and resources while still allowing for richer extensions specific to each data type. For example, the core data layer may contain shared properties or attributes that are common to all objects, while the extensions may contain additional properties or behaviors specific to each object type (e.g., a concert ticket object may have additional properties related to the concert event).
In order to simplifies the storage and retrieval process, resources within an object share the same storage.
#[resource_group(scope = global)]
This also enables the sharing of common data structures or core data layers among different resource types. For example, all resources within an object can share a common set of tokens or basic data fields.
#[resource_group_member(group = aptos_framework::object::ObjectGroup)]
The Object<phantom T> struct allows for the storage and retrieval of objects of different types in a unified manner, providing a simplified interface to interact with the objects stored in the Move storage.

data and ownership model are globally accessible.
Objects and their associated data can be accessed and managed from anywhere since they are not confined to specific scopes or modules but are accessible globally.

Structs:

ObjectCore: This struct defines the core properties of an object, including the owner, transferability, and events associated with the object. It represents the ownership and data model of an object.
Object<phantom T>: This struct represents a pointer to an object. It holds the address of the object and allows access to the underlying data. It represents the data model of an object.
ConstructorRef, DeleteRef, ExtendRef, TransferRef, LinearTransferRef, DeriveRef: These structs represent references or handles to perform various operations on objects, such as creation, deletion, extension, transfer, and derivation. They provide access to the ownership and data model of an object.

Functions:

create_named_object, create_object_from_account, generate_delete_ref, generate_extend_ref, etc.: These functions manipulate the object model by creating objects, generating references, and performing operations on objects. They interact with the data and ownership model of objects.

This structure promotes creating and managing objects with a globally accessible data and ownership model, enabling various operations on objects and supporting event handling.

extensible programming model:
This refers to the ability to extend and customize the behavior of objects without modifying their original implementation. It allows developers to add new functionality, modify existing behavior, or specialize objects for specific use cases without directly modifying the underlying code.

Structs:

ConstructorRef: Represents the ability given to the creator to configure the object as necessary.
DeleteRef: Used to remove an object from storage.
ExtendRef: Used to create events or move additional resources into object storage.
TransferRef: Used to create LinearTransferRef, hence ownership transfer.
LinearTransferRef: Used to perform transfers.
DeriveRef: Used to create derived objects from a given object.

Functions:

create_named_object: Creates a new named object and returns the ConstructorRef. Named objects can be queried globally by knowing the user-generated seed used to create them.
create_user_derived_object: Creates a new object whose address is derived based on the creator account address and another object.
create_object_from_account: Creates a new object from a GUID generated by an account.
create_object_from_object: Creates a new object from a GUID generated by an object.
create_object_from_guid: Creates a new object from a GUID generated by either an account or an object.
convert: converts the object type.

These structs and functions provide mechanisms to create, configure, extend, transfer, derive, convert, and delete objects, allowing for individualization of user applications and leveraging the core framework.

as a general rule, input validation, access control, appropriate event handling, and unit testing are effective to identify and potential security vulnerabilities.

Implementation example - Ticket as Object
https://github.com/Aladeenb/simple-ticket
Object model implementations within Aptos Framework:

Aptos Token v2: an object-based token model
Aptos Fungible Asset: an object-based fungible asset model

Could there be more details on these two parts? For example, explain more source codes of the object implementation in tickets example and aptos framework.

Aptos Object Model
Introduction
Object model introduces a comprehensive capability framework that facilitates control over resources, ownership management, and event emission, which in return enhances the functionality and flexibility of on-chain interactions.
The primary motivation behind the object model is to enable Move to represent a set of different complex types as a one collection of resources stored within a single address.
By organizing resources in this manner, objects can encompass various elements such as NFTs, tokens, and specialized data structures like player objects within a game.
The model offers several advantages, including improved type-safety, enhanced data access, and the ability to emit events directly from objects.
The existing Aptos data model relies on the store ability within Move, allowing structs to be stored in global storage. However, this approach has limitations:

Limited data accessibility: Data can be placed within user-defined resources, making it inaccessible or violating the expected behavior for that data. This can cause confusion for users and creators.
Mixing data types: Different data types can be stored in a single data structure using the "any" type, but this incurs additional costs due to deserialization. It also introduces confusion when developers expect a specific field to represent a particular type.
Lack of data composability: Move currently has restrictions on recursive data structures, which limits the composability of data. Moreover, true recursive data structures can lead to security vulnerabilities.
Complex data referencing: Referencing existing data within entry functions requires substantial code. Supporting unique keys for string validation becomes intricate, hindering development efficiency.
Limited event emission: Events can only be emitted from an account, not directly from associated data, leading to disjointed event tracking.
Costly transfer logic: Transferring logic is restricted to module-specific APIs, resulting in unnecessary cost overhead and resource loading for both senders and receivers.

Analyzing object.move
Let's delve into the composition of the object model:
The core structure compromised of four components.
struct `ObjectCore` has key {
        guid_creation_num: u64,
        owner: address,
        allow_ungated_transfer: bool,
        transfer_events: event::EventHandle<TransferEvent>,
    }

guid_creation_num: A distinctive identifier.
owner: The owner's address (whether pertaining to an object or an account).
allow_ungated_transfer: A boolean variable enabling or disabling the object's transferability. Visualize this variable as a gate, allowing the execution of transfers when in the open (true) state, and restricting them when closed (false).
transfer_events: The transfer event that is emitted whenever a transfer takes place.

These variables represent the object's uniqueness, ownership details, transferability status, and discoverability, respectively. By already encompassing the core structure, the principles of scarcity within the Move framework is effectively validated.
[Scarcity refers to the limited availability of a particular object or asset within a given system.
Firstly, guid_creation_num assigned to each object ensures that no two entities share the same identity. This uniqueness fosters a sense of rarity and exclusivity, as each object can be distinctly identified and differentiated from others.
Secondly, owner address associated with the object or account further enhances scarcity. By explicitly designating an owner, it establishes a sense of ownership and control over the object, limiting its availability to a specific individual or entity. This owner-based restriction helps maintain scarcity by ensuring that the transfer of ownership is intentional and controlled.
allow_ungated_transfer, acting as a gate for enabling or disabling transfer, adds an additional layer of scarcity enforcement. By providing the ability to regulate and restrict transfers, the model empowers owners to determine when and to whom an object can be transferred. This mechanism prevents unauthorized or undesired transfers, reinforcing the scarcity of the object by granting ownership control.
Finally, transfer_events, emitted whenever a transfer occurs, contributes to the overall discoverability and transparency of the system. This event serves as an acknowledgment and record of the transfer, allowing participants to be aware of ownership changes and facilitating the tracking of object movement. By providing visibility into the transfer process, the model ensures that the scarcity of an object is evident and verifiable.]
These properties define the object model:

simplified storage interface.

data and ownership model are globally accessible.

extensible programming model.

simplified storage interface:
the object model supports a heterogeneous collection of resources to be stored together, providing a common core data layer for different data types. This means that different data types can be stored together.
The purpose of this feature is to enable data types to share common functionality and resources while still allowing for richer extensions specific to each data type. For example, the core data layer may contain shared properties or attributes that are common to all objects, while the extensions may contain additional properties or behaviors specific to each object type (e.g., a concert ticket object may have additional properties related to the concert event).
In order to simplifies the storage and retrieval process, resources within an object share the same storage.
#[resource_group(scope = global)]
This also enables the sharing of common data structures or core data layers among different resource types. For example, all resources within an object can share a common set of tokens or basic data fields.
#[resource_group_member(group = aptos_framework::object::ObjectGroup)]
The Object<phantom T> struct allows for the storage and retrieval of objects of different types in a unified manner, providing a simplified interface to interact with the objects stored in the Move storage.

data and ownership model are globally accessible.
Objects and their associated data can be accessed and managed from anywhere since they are not confined to specific scopes or modules but are accessible globally.

Structs:

ObjectCore: This struct defines the core properties of an object, including the owner, transferability, and events associated with the object. It represents the ownership and data model of an object.

Object<phantom T>: This struct represents a pointer to an object. It holds the address of the object and allows access to the underlying data. It represents the data model of an object.

ConstructorRef, DeleteRef, ExtendRef, TransferRef, LinearTransferRef, DeriveRef: These structs represent references or handles to perform various operations on objects, such as creation, deletion, extension, transfer, and derivation. They provide access to the ownership and data model of an object.

Functions:

create_named_object, create_object_from_account, generate_delete_ref, generate_extend_ref, etc.: These functions manipulate the object model by creating objects, generating references, and performing operations on objects. They interact with the data and ownership model of objects.

This structure promotes creating and managing objects with a globally accessible data and ownership model, enabling various operations on objects and supporting event handling.

extensible programming model:
This refers to the ability to extend and customize the behavior of objects without modifying their original implementation. It allows developers to add new functionality, modify existing behavior, or specialize objects for specific use cases without directly modifying the underlying code.

Structs:

ConstructorRef: Represents the ability given to the creator to configure the object as necessary.
DeleteRef: Used to remove an object from storage.
ExtendRef: Used to create events or move additional resources into object storage.
TransferRef: Used to create LinearTransferRef, hence ownership transfer.
LinearTransferRef: Used to perform transfers.
DeriveRef: Used to create derived objects from a given object.

Functions:

create_named_object: Creates a new named object and returns the ConstructorRef. Named objects can be queried globally by knowing the user-generated seed used to create them.
create_user_derived_object: Creates a new object whose address is derived based on the creator account address and another object.
create_object_from_account: Creates a new object from a GUID generated by an account.
create_object_from_object: Creates a new object from a GUID generated by an object.
create_object_from_guid: Creates a new object from a GUID generated by either an account or an object.
convert: converts the object type.

These structs and functions provide mechanisms to create, configure, extend, transfer, derive, convert, and delete objects, allowing for individualization of user applications and leveraging the core framework.

as a general rule, input validation, access control, appropriate event handling, and unit testing are effective to identify and potential security vulnerabilities.

Implementation example - Ticket as Object
https://github.com/Aladeenb/simple-ticket
This module represents a simple ticket implementation of the object model:

A ticket represents an object, it consists of 2 variables, price and seat.
A seat represents another object, it has 2 variables as well, category and price_modifier, and it can be upgraded.
click for more details

TODO: Tickets can be transfered; add a function for that.

Object model implementations within Aptos Framework:
The following implementations will be explained in future articles:

Aptos Token v2: an object-based token model
Aptos Fungible Asset: an object-based fungible asset model
Primary Fungible Store: a support module for managing and transferring fungible assets


added new feature to build pdf with option -nonstop

Here is my promised pull request to support --interaction=nonstopmode for pdf build to make automated builds for softcover books more robust even if latex errors are present.

This is a nice addition. I've fixed a typo (quite to quiet), polished up one conditional, and changed the indentation to match the style used elsewhere in the code, but otherwise this appears to work as written. Thanks!


Inner join handle common columns

- *Potentially BREAKING behavior*: ~innerJoin~ now has another
  parameter ~commonColumns~, which handles how columns that are common
  to both dataframes are handled.
  Previously, we wrongly assumed that the data in all common columns
  must match exactly. In that case it didn't matter which column to
  take.
  However, if they did *not* match, the data for the common columns
  (including the one we joined by) was corrupted and left at default
  initialization from the first mismatch in a common column.
  There are now 3 different ways:
  - ~ccLeft~: keep the data of the left input
  - ~ccRename~: Rename the common columns to ~*_left~ and ~*_right~
    (default)
  - ~ccDrop~: Drop common columns that are not the joined one.
  We choose to use ~ccRename~ as the default, because it keeps all
  information. It is a breaking change however, because the common
  columns now have a different name. But imo it's better here to make
  people aware that this change happened instead of giving them wrong
  data.
  Feel free to conflict me on this.

Merging despite CI failures. Those are unrelated (due to nimcuda) and will be fixed separately.


[WFLY-14922] Convert picketlink extensions to model-only legacy extensions

https://issues.redhat.com/browse/WFLY-14922

@fjuma FYI I moved this out of draft status.

Great, thanks @bstansberry.

Is there some newer PR? This PR has conflicts, so it can't be merged

@bstansberry one more for a rebase.

@darranl @fjuma I rebased this.


Costs from interleaving 1Q gates

consider that some regions are cheaper with a larger basis gate when 1Q gates are non-neglible

See haar.cost_statistics, perhaps the 1Q gates can be treated as a term in the cost function.


Fixing JS SDK Version in doc

Latest JS SDK is 1.6.0 (see release notes https://docs.microsoft.com/en-gb/azure/cognitive-services/speech-service/releasenotes).
The link is downloading a zip called "SpeechSDK-JavaScript-1.6.0.zip"

@nrobert : Thanks for your contribution! The author(s) have been notified to review your proposed change.

Looks like the changes were approved by @fmegen on July 29th. So, we can go ahead and merge.
#sign-off

@nitinme: I'm sorry - only the author of this article, @fmegen, can sign off on your changes. But we do have an exception process - if you are on the Microsoft content or product team for this product area, you can ask the PR review team to review and merge it by sending mail to the techdocprs alias.

Thanks for your contribution, @nrobert.

Thanks @nitinme , really small contrib here!

@nrobert Every bit counts and is equally appreciated!


Enable pretty_print otherwise ct renders empty Ignition

As for<EMAIL_ADDRESS>if pretty_print is set to false, non-empty snippets will empty the rendered Ignition.
This is likely a bug of ct provider.

Decided to downgrade to v0.6.1 since v0.7.0 introduces the bug


VulkanSwapChain::create sizing

Describe the bug
Running on Linux Wayland with two different Vulkan drivers I am seeing VulkanSwapChain::create fail.
NVIDIA RTX A2000 Laptop GPU
Error
VULKAN ERROR: (VUID-VkSwapchainCreateInfoKHR-imageExtent-01274) Validation Error: [ VUID-VkSwapchainCreateInfoKHR-imageExtent-01274 ] Object 0: handle = 0x7fa4b499bcc0, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0x7cd0911d | vkCreateSwapchainKHR() called with imageExtent =<PHONE_NUMBER>,4294967295), which is outside the bounds returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR(): currentExtent =<PHONE_NUMBER>,4294967295), minImageExtent = (1,1), maxImageExtent = (16384,16384). The Vulkan spec states: imageExtent must be between minImageExtent and maxImageExtent, inclusive, where minImageExtent and maxImageExtent are members of the VkSurfaceCapabilitiesKHR structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface (https://vulkan.lunarg.com/doc/view/<IP_ADDRESS>/linux/1.3-extensions/vkspec.html#VUID-VkSwapchainCreateInfoKHR-imageExtent-01274)

Intel(R) UHD Graphics (TGL GT1)
Error
VULKAN ERROR: (VUID-VkSwapchainCreateInfoKHR-imageExtent-01274) Validation Error: [ VUID-VkSwapchainCreateInfoKHR-imageExtent-01274 ] Object 0: handle = 0x7fd39c99bcc0, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0x7cd0911d | vkCreateSwapchainKHR() called with imageExtent =<PHONE_NUMBER>,4294967295), which is outside the bounds returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR(): currentExtent =<PHONE_NUMBER>,4294967295), minImageExtent = (1,1), maxImageExtent = (16384,16384). The Vulkan spec states: imageExtent must be between minImageExtent and maxImageExtent, inclusive, where minImageExtent and maxImageExtent are members of the VkSurfaceCapabilitiesKHR structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface (https://vulkan.lunarg.com/doc/view/<IP_ADDRESS>/linux/1.3-extensions/vkspec.html#VUID-VkSwapchainCreateInfoKHR-imageExtent-01274)

Expected behavior
Swap Chain is created
Desktop (please complete the following information):

OS: Linux
GPU: NVIDIA RTX A2000 Laptop GPU/PCIe/SSE2, Mesa Intel® UHD Graphic, AMD® Radeon rx 6800
Backend: Vulkan

Notes
If I implement this code in place of clientSize = caps.currentExtent;:
    if (caps.currentExtent.width != UINT32_MAX) {
        // If the surface reports a specific extent, we must use it.
        clientSize = caps.currentExtent;
    } else {
        VkExtent2D actual_extent = {
                .width = 1920, // Wayland surface size in pixels
                .height = 720,  // Wayland surface size in pixels
        };
        clientSize.width =
                std::max(caps.minImageExtent.width,
                         std::min(caps.maxImageExtent.width,
                                  actual_extent.width));
        clientSize.height =
                std::max(caps.minImageExtent.height,
                         std::min(caps.maxImageExtent.height,
                                  actual_extent.height));
    }

It will always succeed and ends up with the Wayland surface size:
vkCreateSwapchain: 1920x720, VK_FORMAT_B8G8R8A8_SRGB, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, 5, 1

test_bluevk runs on the same setup without issue.
This would require querying the native window for it's target size.

Just found DriverConfig.  This is great!

A common approach in extent setup is to call the underlying Windowing framework:
    int width, height;

GLFW
    glfwGetFramebufferSize(g_state.window, &width, &height);

SDL2
    SDL_Vulkan_GetDrawableSize(g_state.window, &width, &height);

Then
    VkExtent2D actual_extent = {
        .width = static_cast<uint32_t>(width),
        .height = static_cast<uint32_t>(height),
    };

I'm proposing adding an additional swapchain create() that adds additional parameter of a callback function pointer.  Which in turn would call the original create().  In original create() if the local variable function pointer is not == nullptr the callback gets called.  This would only happen where caps.currentExtent.width == UINT32_MAX.
How does this sound?

One potential solution.  Quick and dirty working example for Vulkan on top of https://github.com/google/filament/pull/6097 to help move the dialog forward.
From 18ff8fff3596a0bb7b0ba3d15e40e0e06e366e17 Mon Sep 17 00:00:00 2001
From: Joel Winarske<EMAIL_ADDRESS>Date: Sat, 24 Sep 2022 15:54:17 -0700
Subject: [PATCH] Size callback prototype

Signed-off-by: Joel Winarske<EMAIL_ADDRESS>---
 .../backend/include/private/backend/Driver.h  |  2 ++
 .../include/private/backend/DriverAPI.inc     |  5 +++
 filament/backend/src/vulkan/VulkanDriver.cpp  | 11 +++++++
 filament/backend/src/vulkan/VulkanDriver.h    |  1 +
 .../backend/src/vulkan/VulkanSwapChain.cpp    | 32 +++++++++++++++++++
 filament/backend/src/vulkan/VulkanSwapChain.h |  4 +++
 filament/include/filament/Engine.h            | 16 ++++++++++
 filament/include/filament/SwapChain.h         |  6 ++++
 filament/src/Engine.cpp                       |  5 +++
 filament/src/details/Engine.cpp               | 16 ++++++++++
 filament/src/details/Engine.h                 |  2 ++
 filament/src/details/SwapChain.cpp            |  5 +++
 filament/src/details/SwapChain.h              |  1 +
 .../include/filamentapp/NativeWindowHelper.h  |  4 +++
 libs/filamentapp/src/FilamentApp.cpp          |  5 ++-
 .../src/NativeWindowHelperLinux.cpp           | 12 +++++++
 16 files changed, 126 insertions(+), 1 deletion(-)

diff --git a/filament/backend/include/private/backend/Driver.h b/filament/backend/include/private/backend/Driver.h
index 5c28841b1..ea9ab574b 100644
--- a/filament/backend/include/private/backend/Driver.h
+++ b/filament/backend/include/private/backend/Driver.h
@@ -53,6 +53,8 @@ class ConcreteDispatcher;
 class Dispatcher;
 class CommandStream;

+typedef void (*PFN_SwapChainExtentCallback)(uint32_t *width, uint32_t *height);
+
 class Driver {
 public:
     virtual ~Driver() noexcept;
diff --git a/filament/backend/include/private/backend/DriverAPI.inc b/filament/backend/include/private/backend/DriverAPI.inc
index cbfb84e82..58e29fa7d 100644
--- a/filament/backend/include/private/backend/DriverAPI.inc
+++ b/filament/backend/include/private/backend/DriverAPI.inc
@@ -253,6 +253,11 @@ DECL_DRIVER_API_R_N(backend::SwapChainHandle, createSwapChainHeadless,
         uint32_t, height,
         uint64_t, flags)

+DECL_DRIVER_API_R_N(backend::SwapChainHandle, createSwapChainWithExtentCallback,
+        void*, nativeWindow,
+        PFN_SwapChainExtentCallback, extentCallback,
+        uint64_t, flags)
+
 DECL_DRIVER_API_R_0(backend::TimerQueryHandle, createTimerQuery)

diff --git a/filament/backend/src/vulkan/VulkanDriver.cpp b/filament/backend/src/vulkan/VulkanDriver.cpp
index 3e2fceceb..076f145cd 100644
--- a/filament/backend/src/vulkan/VulkanDriver.cpp
+++ b/filament/backend/src/vulkan/VulkanDriver.cpp
@@ -641,6 +641,13 @@ void VulkanDriver::createSwapChainHeadlessR(Handle<HwSwapChain> sch,
     construct<VulkanSwapChain>(sch, mContext, mStagePool, width, height);
 }

+void VulkanDriver::createSwapChainWithExtentCallbackR(Handle<HwSwapChain> sch, void *nativeWindow,
+        PFN_SwapChainExtentCallback extentCallback, uint64_t flags) {
+    const VkInstance instance = mContext.instance;
+    auto vksurface = (VkSurfaceKHR) mContextManager.createVkSurfaceKHR(nativeWindow, instance, flags);
+    construct<VulkanSwapChain>(sch, mContext, mStagePool, extentCallback, vksurface);
+}
+
 void VulkanDriver::createTimerQueryR(Handle<HwTimerQuery> tqh, int) {
     // nothing to do, timer query was constructed in createTimerQueryS
 }
@@ -707,6 +714,10 @@ Handle<HwSwapChain> VulkanDriver::createSwapChainHeadlessS() noexcept {
     return allocHandle<VulkanSwapChain>();
 }

+Handle<HwSwapChain> VulkanDriver::createSwapChainWithExtentCallbackS() noexcept {
+    return allocHandle<VulkanSwapChain>();
+}
+
 Handle<HwTimerQuery> VulkanDriver::createTimerQueryS() noexcept {
     // The handle must be constructed here, as a synchronous call to getTimerQueryValue might happen
     // before createTimerQueryR is executed.
diff --git a/filament/backend/src/vulkan/VulkanDriver.h b/filament/backend/src/vulkan/VulkanDriver.h
index 28e46dc1b..c4f148e52 100644
--- a/filament/backend/src/vulkan/VulkanDriver.h
+++ b/filament/backend/src/vulkan/VulkanDriver.h
@@ -153,6 +153,7 @@ private:
     VulkanSamplerGroup* mSamplerBindings[VulkanPipelineCache::SAMPLER_BINDING_COUNT] = {};
     VkDebugReportCallbackEXT mDebugCallback = VK_NULL_HANDLE;
     VkDebugUtilsMessengerEXT mDebugMessenger = VK_NULL_HANDLE;
+    PFN_SwapChainExtentCallback mExtentCallback = nullptr;
 };

 } // namespace filament::backend
diff --git a/filament/backend/src/vulkan/VulkanSwapChain.cpp b/filament/backend/src/vulkan/VulkanSwapChain.cpp
index aa8ff76f3..880422f0c 100644
--- a/filament/backend/src/vulkan/VulkanSwapChain.cpp
+++ b/filament/backend/src/vulkan/VulkanSwapChain.cpp
@@ -129,6 +129,27 @@ void VulkanSwapChain::create(VulkanStagePool& stagePool) {
     // Create the low-level swap chain.

     clientSize = caps.currentExtent;
+    if (clientSize.width == UINT32_MAX) {
+        uint32_t width = 0;
+        uint32_t height = 0;
+        if (mExtentCallback) {
+            mExtentCallback(&width, &height);
+        }
+        ASSERT_POSTCONDITION(width, "Buffer width not set.");
+        ASSERT_POSTCONDITION(height, "Buffer height not set.");
+        VkExtent2D actual_extent = {
+                .width = width,
+                .height = height,
+        };
+        clientSize.width =
+                std::max(caps.minImageExtent.width,
+                         std::min(caps.maxImageExtent.width,
+                                  actual_extent.width));
+        clientSize.height =
+                std::max(caps.minImageExtent.height,
+                         std::min(caps.maxImageExtent.height,
+                                  actual_extent.height));
+    }

     const VkCompositeAlphaFlagBitsKHR compositeAlpha = (caps.supportedCompositeAlpha & VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR) ?
             VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR : VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
@@ -306,6 +327,17 @@ VulkanSwapChain::VulkanSwapChain(VulkanContext& context, VulkanStagePool& stageP
     create(stagePool);
 }

+// Primary SwapChain constructor. (not headless)
+VulkanSwapChain::VulkanSwapChain(VulkanContext &context, VulkanStagePool &stagePool,
+                                 PFN_SwapChainExtentCallback extentCallback, VkSurfaceKHR vksurface) :
+        mContext(context), mExtentCallback(extentCallback) {
+    suboptimal = false;
+    surface = vksurface;
+    firstRenderPass = true;
+    getPresentationQueue(context, *this);
+    create(stagePool);
+}
+
 // Headless SwapChain constructor. (does not create a VkSwapChainKHR)
 VulkanSwapChain::VulkanSwapChain(VulkanContext& context, VulkanStagePool& stagePool, uint32_t width, uint32_t height) :
         mContext(context) {
diff --git a/filament/backend/src/vulkan/VulkanSwapChain.h b/filament/backend/src/vulkan/VulkanSwapChain.h
index c1b880adc..884020c09 100644
--- a/filament/backend/src/vulkan/VulkanSwapChain.h
+++ b/filament/backend/src/vulkan/VulkanSwapChain.h
@@ -33,6 +33,9 @@ struct VulkanSwapChain : public HwSwapChain {
     // Headless constructor.
     VulkanSwapChain(VulkanContext& context, VulkanStagePool& stagePool, uint32_t width, uint32_t height);

+    VulkanSwapChain(VulkanContext &context, VulkanStagePool &stagePool, PFN_SwapChainExtentCallback extentCallback,
+                    VkSurfaceKHR vksurface);
+
     bool acquire();
     void create(VulkanStagePool& stagePool);
     void destroy();
@@ -63,6 +66,7 @@ struct VulkanSwapChain : public HwSwapChain {
 private:
     VulkanContext& mContext;
     uint32_t mCurrentSwapIndex = 0u;
+    PFN_SwapChainExtentCallback mExtentCallback = nullptr;

     // Color attachments are swapped, but depth is not. Typically there are 2 or 3 color attachments
     // in a swap chain.
diff --git a/filament/include/filament/Engine.h b/filament/include/filament/Engine.h
index 7452c4d5c..cfeaf53a5 100644
--- a/filament/include/filament/Engine.h
+++ b/filament/include/filament/Engine.h
@@ -543,6 +543,22 @@ public:
      */
     SwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags = 0) noexcept;

+    typedef void (*SwapChainExtentVoidCallback)(uint32_t *, uint32_t *);
+
+    /**
+     * Creates a SwapChain from the given Operating System's native window handle.
+     *
+     * @param nativeWindow An opaque native window handle. e.g.: on Android this is an
+     *                     `ANativeWindow*`.
+     * @param callback Function pointer to callback that returns the frame buffer size.
+     * @param flags One or more configuration flags as defined in `SwapChain`.
+     *
+     * @return A pointer to the newly created SwapChain or nullptr if it couldn't be created.
+     *
+     * @see Renderer.beginFrame()
+     */
+    SwapChain* createSwapChain(void* nativeWindow, SwapChainExtentVoidCallback extentCallback, uint64_t flags = 0) noexcept;
+
     /**
      * Creates a renderer associated to this engine.
      *
diff --git a/filament/include/filament/SwapChain.h b/filament/include/filament/SwapChain.h
index 248476075..11607b396 100644
--- a/filament/include/filament/SwapChain.h
+++ b/filament/include/filament/SwapChain.h
@@ -148,6 +148,12 @@ public:
     using FrameScheduledCallback = backend::FrameScheduledCallback;
     using FrameCompletedCallback = backend::FrameCompletedCallback;

+    /**
+     * This defines a SwapChain Extent callback function pointer type.
+     *
+     */
+    typedef void (*PFN_SwapChainExtentCallback)(uint32_t *width, uint32_t *height);
+
     static const uint64_t CONFIG_TRANSPARENT = backend::SWAP_CHAIN_CONFIG_TRANSPARENT;
     /**
      * This flag indicates that the swap chain may be used as a source surface
diff --git a/filament/src/Engine.cpp b/filament/src/Engine.cpp
index b507b176f..30330bd6e 100644
--- a/filament/src/Engine.cpp
+++ b/filament/src/Engine.cpp
@@ -125,6 +125,11 @@ SwapChain* Engine::createSwapChain(uint32_t width, uint32_t height, uint64_t fla
     return upcast(this)->createSwapChain(width, height, flags);
 }

+SwapChain *
+Engine::createSwapChain(void *nativeWindow, SwapChainExtentVoidCallback extentCallback, uint64_t flags) noexcept {
+    return upcast(this)->createSwapChain(nativeWindow, extentCallback, flags);
+}
+
 bool Engine::destroy(const BufferObject* p) {
     return upcast(this)->destroy(upcast(p));
 }
diff --git a/filament/src/details/Engine.cpp b/filament/src/details/Engine.cpp
index 9e65b79de..6d5d31923 100644
--- a/filament/src/details/Engine.cpp
+++ b/filament/src/details/Engine.cpp
@@ -803,6 +803,22 @@ FSwapChain* FEngine::createSwapChain(uint32_t width, uint32_t height, uint64_t f
     return p;
 }

+FSwapChain *
+FEngine::createSwapChain(void *nativeWindow, SwapChainExtentVoidCallback extentCallback, uint64_t flags) noexcept {
+    if (UTILS_UNLIKELY(flags & backend::SWAP_CHAIN_CONFIG_APPLE_CVPIXELBUFFER)) {
+        // If this flag is set, then the nativeWindow is a CVPixelBufferRef.
+        // The call to setupExternalImage is synchronous, and allows the driver to take ownership of
+        // the buffer on this thread.
+        // For non-Metal backends, this is a no-op.
+        getDriverApi().setupExternalImage(nativeWindow);
+    }
+    FSwapChain *p = mHeapAllocator.make<FSwapChain>(*this, nativeWindow, extentCallback, flags);
+    if (p) {
+        mSwapChains.insert(p);
+    }
+    return p;
+}
+
 /*
  * Objects created with a component manager
  */
diff --git a/filament/src/details/Engine.h b/filament/src/details/Engine.h
index db663d892..b1854979f 100644
--- a/filament/src/details/Engine.h
+++ b/filament/src/details/Engine.h
@@ -267,6 +267,8 @@ public:
     FFence* createFence(FFence::Type type) noexcept;
     FSwapChain* createSwapChain(void* nativeWindow, uint64_t flags) noexcept;
     FSwapChain* createSwapChain(uint32_t width, uint32_t height, uint64_t flags) noexcept;
+    FSwapChain *
+    createSwapChain(void *nativeWindow, SwapChainExtentVoidCallback extentCallback, uint64_t flags) noexcept;

     FCamera* createCamera(utils::Entity entity) noexcept;
     FCamera* getCameraComponent(utils::Entity entity) noexcept;
diff --git a/filament/src/details/SwapChain.cpp b/filament/src/details/SwapChain.cpp
index 07d61a058..dece1fbb5 100644
--- a/filament/src/details/SwapChain.cpp
+++ b/filament/src/details/SwapChain.cpp
@@ -30,6 +30,11 @@ FSwapChain::FSwapChain(FEngine& engine, uint32_t width, uint32_t height, uint64_
     mSwapChain = engine.getDriverApi().createSwapChainHeadless(width, height, flags);
 }

+FSwapChain::FSwapChain(FEngine& engine, void* nativeWindow, PFN_SwapChainExtentCallback extentCallback, uint64_t flags)
+        : mEngine(engine), mNativeWindow(nativeWindow), mConfigFlags(flags) {
+    mSwapChain = engine.getDriverApi().createSwapChainWithExtentCallback(nativeWindow, extentCallback, flags);
+}
+
 void FSwapChain::terminate(FEngine& engine) noexcept {
     engine.getDriverApi().destroySwapChain(mSwapChain);
 }
diff --git a/filament/src/details/SwapChain.h b/filament/src/details/SwapChain.h
index 09bad013d..2332febc0 100644
--- a/filament/src/details/SwapChain.h
+++ b/filament/src/details/SwapChain.h
@@ -32,6 +32,7 @@ class FEngine;
 class FSwapChain : public SwapChain {
 public:
     FSwapChain(FEngine& engine, void* nativeWindow, uint64_t flags);
+    FSwapChain(FEngine& engine, void* nativeWindow, PFN_SwapChainExtentCallback extentCallback, uint64_t flags);
     FSwapChain(FEngine& engine, uint32_t width, uint32_t height, uint64_t flags);
     void terminate(FEngine& engine) noexcept;

diff --git a/libs/filamentapp/include/filamentapp/NativeWindowHelper.h b/libs/filamentapp/include/filamentapp/NativeWindowHelper.h
index 027c1a0be..24c4d50b4 100644
--- a/libs/filamentapp/include/filamentapp/NativeWindowHelper.h
+++ b/libs/filamentapp/include/filamentapp/NativeWindowHelper.h
@@ -17,10 +17,14 @@
 #ifndef TNT_FILAMENT_NATIVE_WINDOW_HELPER_H
 #define TNT_FILAMENT_NATIVE_WINDOW_HELPER_H

+#include <cstdint>
+
 struct SDL_Window;

 extern "C" void* getNativeWindow(SDL_Window* sdlWindow);

+extern "C" void getNativeDrawableSize(SDL_Window* sdlWindow, std::uint32_t *width, std::uint32_t *height);
+
 #if defined(__APPLE__)
 // Add a backing CAMetalLayer to the NSView and return the layer.
 extern "C" void* setUpMetalLayer(void* nativeWindow);
diff --git a/libs/filamentapp/src/FilamentApp.cpp b/libs/filamentapp/src/FilamentApp.cpp
index 259de73d4..6d240ce08 100644
--- a/libs/filamentapp/src/FilamentApp.cpp
+++ b/libs/filamentapp/src/FilamentApp.cpp
@@ -581,7 +581,10 @@ FilamentApp::Window::Window(FilamentApp* filamentApp,
                 mFilamentApp->mEngine->getSupportedFeatureLevel());
         mFilamentApp->mEngine->setActiveFeatureLevel(config.featureLevel);

-        mSwapChain = mFilamentApp->mEngine->createSwapChain(nativeSwapChain);
+        static SDL_Window *pWindow = mWindow;
+        mSwapChain = mFilamentApp->mEngine->createSwapChain(nativeSwapChain, [](uint32_t *width, uint32_t *height) {
+            ::getNativeDrawableSize(pWindow, width, height);
+        });
     }
     mRenderer = mFilamentApp->mEngine->createRenderer();

diff --git a/libs/filamentapp/src/NativeWindowHelperLinux.cpp b/libs/filamentapp/src/NativeWindowHelperLinux.cpp
index 78e737d0a..19c26adc7 100644
--- a/libs/filamentapp/src/NativeWindowHelperLinux.cpp
+++ b/libs/filamentapp/src/NativeWindowHelperLinux.cpp
@@ -19,6 +19,7 @@
 #include <utils/Panic.h>

 #include <SDL_syswm.h>
+#include <SDL_vulkan.h>

 void* getNativeWindow(SDL_Window* sdlWindow) {
     SDL_SysWMinfo wmi;
@@ -44,3 +45,14 @@ void* getNativeWindow(SDL_Window* sdlWindow) {
     }
     return nullptr;
 }
+
+void getNativeDrawableSize(SDL_Window* sdlWindow, uint32_t *width, uint32_t *height) {
+    int w, h;
+#if defined(FILAMENT_DRIVER_SUPPORTS_VULKAN)
+    SDL_Vulkan_GetDrawableSize(sdlWindow, &w, &h);
+#elif defined(FILAMENT_DRIVER_SUPPORTS_OPENGL)
+    SDL_GL_GetDrawableSize(sdlWindow, &w, &h);
+#endif
+    *width = w;
+    *height = w;
+}
--
2.34.3

@jwinarske your proposal might be interesting but it's hard to read, might be better just to show us a branch with those changes, since GitHub will show us a nice diff?  Also, I wonder if a much simpler fix exists, e.g. maybe the backend could simply clamp the size to the value returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR...
@pixelflinger I do not fully understand this issue, but it is Linux specific and I would be surprised if the fix actually requires a change to Filament's public-facing API.

@prideout I'll take a look at what vkGetPhysicalDeviceSurfaceCapabilitiesKHR returns.
This did work at one point when the Wayland code was originally merged.  I never looked at the path of swap chain sizing, so not clear on the allocation sizes involved.
Resizing is also on the radar.

@prideout
When the VK surface is created wl_display and wl_surface pointers are passed.  wl_display points to the client session.  wl_surface doesn't have a size association.
This is what I get in SwapChain::create querying vkGetPhysicalDeviceSurfaceCapabilitiesKHR.
surface_caps = {VkSurfaceCapabilitiesKHR}
 minImageCount = {uint32_t} 4
 maxImageCount = {uint32_t} 0
 currentExtent = {VkExtent2D}
  width = {uint32_t}<PHONE_NUMBER>
  height = {uint32_t}<PHONE_NUMBER>
 minImageExtent = {VkExtent2D}
  width = {uint32_t} 1
  height = {uint32_t} 1
 maxImageExtent = {VkExtent2D}
  width = {uint32_t} 16384
  height = {uint32_t} 16384
 maxImageArrayLayers = {uint32_t} 1
 supportedTransforms = {VkSurfaceTransformFlagsKHR} 1
 currentTransform = {VkSurfaceTransformFlagBitsKHR} VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR
 supportedCompositeAlpha = {VkCompositeAlphaFlagsKHR} 3
 supportedUsageFlags = {VkImageUsageFlags} 159

The values appear to be as designed:
On Wayland, currentExtent is undefined (0xFFFFFFFF, 0xFFFFFFFF). Whatever the application sets a swapchain’s imageExtent to will be the size of the window, after the first image is presented.

https://github.com/KhronosGroup/Vulkan-Docs/issues/590
Also:
RESOLVED: Yes. On some platforms (Wayland, for example), the surface size is defined by the images presented to it rather than the other way around.

https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_KHR_swapchain.html

@prideout
This SwapChain create supports:

Win32
Android
Wayland
XCB
X11
iOS
MacOS
Direct2Display

https://github.com/SaschaWillems/Vulkan-glTF-PBR/blob/master/base/VulkanSwapChain.hpp#L262
Wayland is handled by this:
// If width (and height) equals the special value 0xFFFFFFFF, the size of the surface will be set by the swapchain
if (surfCaps.currentExtent.width == (uint32_t)-1)
{
	// If the surface size is undefined, the size is set to
	// the size of the images requested.
	extent.width = *width;
	extent.height = *height;
}

So width, and height does need to get passed in.
Also the preferred present mode may not want to be FIFO.  In the case of Wayland one can use wl_surface:frame callbacks to drive the render loop, in which case nothing in the render path should block.

@pixelflinger @poweifeng ping

Hi @jwinarske Joel, I'm still ramping up on the issue here, and appreciate your patience.
So I think the issue here is that for your drivers+Wayland, the currentExtent returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR somehow is set to 0xFFFFFFFF, which is ok by spec.
And you're proposing that we add another backend API so that we can use the native windows extent for setting the extent of the swapchain.  Am I understanding correctly?

@poweifeng correct

I tried to repro but ran into issues. This might have to wait until next week.
My steps for building Filament for wayland is:

change FILAMENT_SUPPORTS_WAYLAND to default ON
Build with ./build.sh debug gltf_viewer

When crashed, I get the stack
0  0x00007ffff7f4e700 in wl_proxy_get_version () from /lib/x86_64-linux-gnu/libwayland-client.so.0
#1  0x00005555557e6561 in wl_shell_get_shell_surface (wl_shell=0x0, surface=0x5555592d2b60) at autogen/wayland/wayland-client-protocol.h:3033
#2  0x00005555557e61dd in Wayland_CreateWindow (_this=0x5555590b66e0, window=0x5555591087b0) at /home/powei/work2/f4/third_party/libsdl2/src/video/wayland/SDL_waylandwindow.c:424
#3  0x0000555555708634 in SDL_CreateWindow_REAL (title=0x7fffffffdba1 "Filament", x=805240832, y=805240832, w=1024, h=640, flags=8228) at /home/powei/work2/f4/third_party/libsdl2/src/video/SDL_video.c:1475
#4  0x00005555556c29fb in SDL_CreateWindow (a=0x7fffffffdba1 "Filament", b=805240832, c=805240832, d=1024, e=640, f=8228) at /home/powei/work2/f4/third_party/libsdl2/src/dynapi/SDL_dynapi_procs.h:542
#5  0x0000555555675104 in FilamentApp::Window::Window (this=0x5555590b6330, filamentApp=0x555558a8e810 <FilamentApp::get()::filamentApp>, config=..., title="Filament", w=1024, h=640) at /home/powei/work2/f4/libs/filamentapp/src/FilamentApp.cpp:531
#6  0x00005555556716e8 in FilamentApp::run(Config const&, std::__1::function<void (filament::Engine*, filament::View*, filament::Scene*)>, std::__1::function<void (filament::Engine*, filament::View*, filament::Scene*)>, std::__1::function<void (filament::Engine*, filament::View*)>, std::__1::function<void (filament::Engine*, filament::View*, filament::Scene*, filament::Renderer*)>, std::__1::function<void (filament::Engine*, filament::View*, filament::Scene*, filament::Renderer*)>, unsigned long, unsigned long) (this=0x555558a8e810 <FilamentApp::get()::filamentApp>, config=..., setupCallback=..., cleanupCallback=..., imguiCallback=..., preRender=..., postRender=..., width=1024, height=640)
    at /home/powei/work2/f4/libs/filamentapp/src/FilamentApp.cpp:84
#7  0x0000555555617708 in main (argc=1, argv=0x7fffffffe3e8) at /home/powei/work2/f4/samples/gltf_viewer.cpp:936

I think this is due to our outdated SDL2 using a deprecated call.
SDL2 uses the new API
wl_shell deprecation

I think I might try running core Filament using a bare wayland client. Not sure how complicated that will be.

@poweifeng This is my approach to workaround stale SDL2:
https://github.com/jwinarske/filament-samples/blob/main/third_party/libsdl2/tnt/CMakeLists.txt
I have a number of changes around building the samples that I figured were "too radical" for upstream.

@poweifeng these are examples of how I'm building for Linux.  The sample recipe is just building test cases at the moment.  But it can provide some insights on flag usage.
https://github.com/jwinarske/meta-vulkan/blob/kirkstone/recipes-graphics/filament/filament-vk_git.bb
https://github.com/jwinarske/meta-vulkan/blob/kirkstone/recipes-graphics/filament/filament-samples-vk_git.bb

@jwinarske can you give this patch/branch a try: https://github.com/google/filament/tree/pf/wayland-resizing ?
Instead adding an backend API for a special case, I try to keep the workaround contained in the vulkan backend.  If this works for you, I'll make a pull request.

I will take a look first thing in the morning.  Thanks!

@poweifeng
Hitting compile error on your branch:
/home/joel.winarske@toyotaconnected.com/development/comp_surf_filament/third_party/filament/filament/backend/src/vulkan/VulkanSwapChain.cpp:322:18: error: constructor for 'filament::backend::VulkanSwapChain' must explicitly initialize the const member 'mFallbackExtent'
VulkanSwapChain::VulkanSwapChain(VulkanContext& context, VulkanStagePool& stagePool, uint32_t width, uint32_t height) :

Added
// Headless SwapChain constructor. (does not create a VkSwapChainKHR)
VulkanSwapChain::VulkanSwapChain(VulkanContext& context, VulkanStagePool& stagePool, uint32_t width, uint32_t height) :
        mContext(context),
        mFallbackExtent({width, height}) {

Your branch works great with above change.

And I'm fine with adding the width and height values to native_window.

@poweifeng thank you


Disable sslv3 for glu agent

As reported in the forum: http://glu.977617.n3.nabble.com/Disable-sslv3-for-glu-Agent-host-port-12906-tp4026813.html

fixed in 5.5.4


logs are sent through closed hook

we have a hook to stackdriver hook: https://github.com/GoogleCloudPlatform/google-cloud-go/tree/master/logging
We create logger per request by design!.
since logrus asynchronously. if we write a log and then close the hook (i.e stackdriver client). logrus will try to send the message to the hook while it is closed which means we will not see the log on stackdriver and get an error for writing to a closed channel.
consider this code:
  hook:=CreateHook(...)
  log := logrus.New()
  log.Hooks.Add(hook)
  log.Info("hello world")
  hook.Close()

This is a severity A bug!
There is also no mechanism to flush the log

the issue is in the hook... nevermind

@David-hod did you solve your issue ? Can we close this one ?


⚠ Samsung has degraded performance

In a787611, Samsung (https://samsung.com) experienced degraded performance:

HTTP code: 200
Response time: 2935 ms

Resolved: Samsung performance has improved in d7a2e82.


any chance to build this dll's without MSVC dependency?

subj

The Microsoft C Runtime Library can be statically linked (and removed as a dependency) by changing the CFLAGS -MD compile option in makefile.msc to -MT.
I've added a patch in a new static_linking branch to make this change (as well as statically linking libbz2 into bzip2.exe).
This statically linked version of the build can be run by checking out the static_linking branch and running Build-Bzip2.ps1 (setting the GitPath and VisualStudioDir parameters appropriately).
I'm not going to publish statically linked binaries. As with any statically linked project, they would need to be re-released to keep up to date with security and bug fixes to the C runtime library.

Actually libbzip2 doesn't need C runtime. z_malloc -> VirtualAlloc etc, there are just 2-3 functions from runtime, all of them can be replaced by direct win32 api access...

You're welcome to submit a pull request if you think that eliminating the C runtime altogether would be useful for others.
I'd suggest using HeapAlloc rather than VirtualAlloc as a replacement for malloc though - see https://stackoverflow.com/q/872072/5981 and https://msdn.microsoft.com/en-us/library/windows/desktop/aa366533.aspx.

I'm not going to publish statically linked binaries. As with any statically linked project, they would need to be re-released to keep up to date with security and bug fixes to the C runtime library.

What about just statically linking libbz2? (EXEs still depending on MSVC Runtime)

@marcosfrm The unmodified makefile.msc file in the bzip2 source distribution will produce executables that statically link libbz2, but that still dynamically depend on the C runtime. The purpose of this project was to modify the build to produce the libbz2 DLL.
If you download the bzip2 sources (the current version is 1.0.8) and run nmake /f makefile.msc you should get the desired executables.


When being on the public view, the zoom level label shouldn't be visible

Comes from this DI issue.

There has been no activity on this issue for several months and that's why we are closing it (automatically). If you think this still needs to be addressed please reopen it. The good news is that we are now working on the next version of CARTO.js, stay tuned.


Feature Request: Windows support

Not sure if this is planned or not, but would be really nice to see this get Windows support! Looking at the source with my limited knowledge of cpp, I think the file open/save dialogs and such are the only parts that require macOS, but maybe there's more to it I'm not aware of.

@stysmmaker Thank you for the comment. Of course, I'm thinking of supporting Windows. Since I have been using Windows quite a little recently, the lack of a debugging environment is one of the reasons why I am focusing on macOS.
And to be honest, I'm not sure how much AE users really need a kind of this plugin -- I will try to support Windows if there are more reactions like yours.
FYI, PixelsWorld](https://aescripts.com/pixelsworld) would be a good alternative for Windows, which allows users to write effects in GLSL/Lua. Though it's proprietary and users need to understand its own specification, please try it if you're interested.

It would be very cool to see Windows support!
After Effects are great software, but with really customizable effects it would be much more powerful.
I'm not experienced in writing shader code but now I use Blender 3D shader nodes for some complicated effects, like CRT screen emulation, it's not very convenient to switch between software.
It could be also useful for some specific tasks for cartoon animation production.

@baku89 I think I can get it building on Windows.

I tried too, nothing seems to be preventing us from doing it, only a few #ifdef to handle MacOs dialog vs Windows dialogs.  I have put it on the shelf for now but definitely going back to it soon. I was planning on making a PR for a windows build once I am done. I can share it now if you want to look at it/contribute

Thanks so much for your consideration.
@gabgren Which lines does the compiler on Windows throw as errors?
I quickly sought the source files, but I couldn't find any sort of variables with the type byte.
If it is related to VVGL/VVISF, which is a wrapper for managing OpenGL contexts and parsing ISF, we might have to fix the forked version of them rather than this repo.

Awesome! That was my focus last night. I started getting a build environment for ISF4AE first - I knew I'd need the VVGL/VVISF dependencies but wanted to get the ISF4AE bits to the point where those dependencies were the only thing missing.
VVGL looks to use GLFW so I feel like this shouldn't be too difficult. I think you're right about the sections for Windows file dialogs vs Mac, I think that might be the extend of the differences.
@gabgren I have an mmdurrant/ISF4AE fork and have started  mmdurrant/win branch.

Sounds great!
Since my skill is basically like a front-end developer and I'm not used to writing such a low-level implementation in C++, the source code might be quite messy and hard to understand.
So if you have any questions about the architecture of the plugin or AESDK, pls feel free to ask me.

@baku89 Hey, I'm currently trying to transition part of the engine to a Windows version, but I've hit some snags with VVGL in Windows. The plugin crashes with the newer versions of the Nvidia Studio drivers. Interestingly, everything works perfectly with the older versions. I suspect the issue is related to context creation since I get a glGetError() = 1282 (Invalid operation) at the line "tmpCtx->makeCurrentIfNotCurrent();" in GLBufferPool.h, under the function CreateRGBAPBO.
Some backstory:
I tried to keep just the essentials in GlobalData to replicate the error:
struct GlobalData {
  AEGP_PluginID             aegpId;
  VVGL::GLContextRef        context;
  VVGL::GLCPUToTexCopierRef uploader;
  VVGL::GLTexToCPUCopierRef downloader;
  VVISF::ISF4AESceneRef     mainScene;
};

Another quirk with Windows is that the context in GlobalSetup is set up slightly differently than the Mac version:
// Initialize global OpenGL context
#ifdef AE_OS_WIN
  GLContext::bootstrapGLEnvironmentIfNecessary();
  globalData->context = VVGL::CreateNewGLContextRef(nullptr, nullptr); // VVGL on Windows Doesn't have pixel format functions
#else
  globalData->context = VVGL::CreateNewGLContextRef(NULL, CreateCompatibilityGLPixelFormat());
#endif

Then I just initialize the mainScene like this:
globalData->mainScene = VVISF::CreateISF4AESceneRefUsing(globalData->context->newContextSharingMe());
globalData->mainScene->useCode(MAIN_SHADER, "");

In PreRender, I just pass the mainScene to ParamInfo:
auto *paramInfo = static_cast<ParamInfo *>(suites.HandleSuite1()->host_lock_handle(paramInfoH));
paramInfo->scene = globalData->mainScene.get();

And then in SmartRender, I load the input to CPU:
ERR(uploadCPUBufferInSmartRender(globalData, in_data->effect_ref, extra, checkoutIndex, layerSize, image));

It's within uploadCPUToTex that I encounter the error at the aforementioned CreateRGBAPBO in GLBufferPool.h:
auto imageAE = globalData->uploader->uploadCPUToTex(imageAECPU);
assert("OpenGl Error" && glGetError() == GL_NO_ERROR);

If I ignore the assert, I get an Access Violation during the copying from cpuBackingPtr because cpuBackingPtr is null:
for (size_t y = 0; y < paramInfo->outSize.height; y++) {
  if (!outputImageCPU->cpuBackingPtr) {
    err = PF_Err_OUT_OF_MEMORY;
    assert("FATAL! CPU backing pointer is NULL! Cannot copy CPU buffer to EffectWorld!" && false);
  }
  glP = (char *)outputImageCPU->cpuBackingPtr + y * bytesPerRowGl;
  aeP = (char *)outputWorld->data + y * outputWorld->rowbytes;
  memcpy(aeP, glP, paramInfo->outSize.width * pixelBytes);
}

Any ideas on what I should be looking into or where I should dig next? Everything works great on Mac, and even on Windows, but updating the Nvidia drivers brings about these weird issues. Or could the 1282 error be a red herring, and the null cpuBackingPtr might be due to some other reason?

Can you share your branch? seeing any other edits you made to the locking code might provide hints.

See https://github.com/baku89/ISF4AE/pull/24

@gabgren Thank you so much for your pull request!
Although I have no Windows machine with AE installed and couldn't check if it works by myself, I've merged your patch to the main branch.
I would also like to thank everyone else who participated in this thread and discussed the Windows support!

And am also wondering how to compile, verify, and release the plug-in for both platforms more easily.  The notarization on macOS is quite strict and complicated so I've executed a bash script to prepare the binary by hand on a local machine. But this must be automated by something like GitHub Actions.
But regarding Windows, every time I update the version, I have to ask someone who uses AE on Windows to build it manually and send me back the binary. So if there's any smarter way to automate this process, it should be helpful for future updates.

I guess you could run a windows VM on your Mac ?
Notarization on OSX is quite tricky the first time but can be automated if
the certificate is installed on the computer.
Le jeu. 28 sept. 2023 à 10:16, Baku 麦 @.***> a écrit :

And am also wondering how to compile, verify, and release the plug-in for
both platforms more easily. The notarization on macOS is quite strict and
complicated so I've executed a bash script to prepare the binary by hand on
a local machine. But this must be automated by something like GitHub
Actions.
But regarding Windows, every time I update the version, I have to ask
someone who uses AE on Windows to build it manually and send me back the
binary. So if there's any smarter way to automate this process, it should
be helpful for future updates.
—
Reply to this email directly, view it on GitHub
https://github.com/baku89/ISF4AE/issues/19#issuecomment-1739324839, or
unsubscribe
https://github.com/notifications/unsubscribe-auth/AANFCMK3USXJPSGPTNS32B3X4WBC3ANCNFSM6AAAAAARSNRCWQ
.
You are receiving this because you were mentioned.Message ID:
@.***>

@gabgren Thank you so much for your pull request! Although I have no Windows machine with AE installed and couldn't check if it works by myself, I've merged your patch to the main branch.
I would also like to thank everyone else who participated in this thread and discussed the Windows support!

@baku89 thank you so much for such an amazing repository! Parts of your code still inspire my projects. It's very well-organized and has some beautifully done implementations.
I wanted to ask, is it alright if I open a separate Issue regarding the problem with the Windows version, which I still couldn't resolve in the fork we mentioned in the pull request to you?

I have no Windows machine with AE installed and couldn't check if it works by myself, I've merged your patch to the main branch.

For Windows, we can also attach a Release version. Here, for example, is an archive. It should work on its own, because it contains the static glew32s.lib, so there's no need to copy dll to system32 =)
ISF4AE.zip

@baku89 for notarization, I made a tool to make life easier: https://github.com/gabgren/notarizer

I'm trying to debug a dumb issue but can't compile this because I can't get
the VVISF-GL submodule patch to apply due to:
error: git diff header lacks filename information when removing 1 leading
pathname component (line 98)
Please advise.
Michael Durrant
@.***
On Thu, Sep 28, 2023 at 8:18 PM gabgren @.***> wrote:

@baku89 https://github.com/baku89 for notarization, I made a tool to
make life easier: https://github.com/gabgren/notarizer
—
Reply to this email directly, view it on GitHub
https://github.com/baku89/ISF4AE/issues/19#issuecomment-1740223846, or
unsubscribe
https://github.com/notifications/unsubscribe-auth/ABKYJ5R7BJLQA6SVHTQEFWDX4YVXHANCNFSM6AAAAAARSNRCWQ
.
You are receiving this because you commented.Message ID:
@.***>

I have no Windows machine with AE installed and couldn't check if it works by myself, I've merged your patch to the main branch.

For Windows, we can also attach a Release version. Here, for example, is an archive. It should work on its own, because it contains the static glew32s.lib, so there's no need to copy dll to system32 =)
ISF4AE.zip

hi, ive installed the plugin using the archive that u attached. however i noticed some issues with the plugin, sometimes the shader effect is not displaying at all regardless of what i do. even reloading the shader or readding the ISF4AE in new layers doesnt fix it. so after creating a complex procedural effect using the plugin and then purging the project i completely lost most of the progress in the procedural effect.  im not sure if this issue exist in the latest source code or its already fixed in the latest source code but when im trying to build the source code i encountered the same issue as the guy above me.
trying to apply
git apply VVISF-GL-Submodule.patch
returns an error
error: git diff header lacks filename information when removing 1 leading
i would really appreciate any help if possible, thanks :)